2 * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 package org.anbox.appmgr;
20 import android.os.ServiceManager;
21 import android.os.IBinder;
22 import android.os.Parcel;
23 import android.os.RemoteException;
24 import android.util.Log;
25 import android.content.Intent;
26 import android.content.Context;
27 import android.content.pm.PackageManager;
28 import android.content.pm.ApplicationInfo;
29 import android.net.Uri;
30 import android.graphics.drawable.Drawable;
31 import android.graphics.drawable.BitmapDrawable;
32 import android.graphics.Bitmap;
33 import android.graphics.Bitmap.Config;
34 import android.graphics.Canvas;
36 import java.util.List;
37 import java.io.ByteArrayOutputStream;
39 public final class PlatformService {
40 private static final String TAG = "AnboxAppMgr";
41 private static final String SERVICE_NAME = "org.anbox.PlatformService";
42 private static final String DESCRIPTOR = "org.anbox.IPlatformService";
44 private static final int TRANSACTION_updateApplicationList = (IBinder.FIRST_CALL_TRANSACTION + 2);
46 private IBinder mService = null;
47 private PackageManager mPm = null;
49 private void connectService() {
52 mService = ServiceManager.getService(SERVICE_NAME);
55 public PlatformService(Context context) {
56 if (context != null) {
57 mPm = context.getPackageManager();
59 Log.w(TAG, "No context available");
62 Log.i(TAG, "Connected to platform service");
65 public void notifyPackageRemoved(String packageName) {
71 Log.i(TAG, "Sending package removed notification to host service");
73 Parcel data = Parcel.obtain();
74 data.writeInterfaceToken(DESCRIPTOR);
75 // No added or updated applications to report
77 // .. but a single removed application
79 data.writeString(packageName);
81 Parcel reply = Parcel.obtain();
83 mService.transact(TRANSACTION_updateApplicationList, data, reply, 0);
85 catch (RemoteException ex) {
86 Log.w(TAG, "Failed to send updatePackageList request to remote binder service: " + ex.getMessage());
90 public void sendApplicationListUpdate() {
93 if (mPm == null || mService == null)
96 Parcel data = Parcel.obtain();
97 data.writeInterfaceToken(DESCRIPTOR);
99 List<ApplicationInfo> apps = mPm.getInstalledApplications(0);
100 data.writeInt(apps.size());
101 for (int n = 0; n < apps.size(); n++) {
102 ApplicationInfo appInfo = apps.get(n);
104 Intent launchIntent = mPm.getLaunchIntentForPackage(appInfo.packageName);
105 if (launchIntent == null)
108 Drawable icon = null;
110 icon = mPm.getApplicationIcon(appInfo.packageName);
112 catch (PackageManager.NameNotFoundException ex) {
119 String name = appInfo.name;
120 CharSequence label = appInfo.loadLabel(mPm);
122 name = label.toString();
124 data.writeString(name);
125 data.writeString(appInfo.packageName);
127 data.writeString(launchIntent.getAction());
128 if (launchIntent.getData() != null)
129 data.writeString(launchIntent.getData().toString());
131 data.writeString("");
132 data.writeString(launchIntent.getType());
133 data.writeString(launchIntent.getComponent().getPackageName());
134 data.writeString(launchIntent.getComponent().getClassName());
135 data.writeInt(launchIntent.getCategories().size());
136 for (String category : launchIntent.getCategories())
137 data.writeString(category);
139 Bitmap iconBitmap = drawableToBitmap(icon);
140 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
141 iconBitmap.compress(Bitmap.CompressFormat.PNG, 90, outStream);
142 data.writeByteArray(outStream.toByteArray());
145 // We don't have any removed applications to include in the update
148 Parcel reply = Parcel.obtain();
150 mService.transact(TRANSACTION_updateApplicationList, data, reply, 0);
152 catch (RemoteException ex) {
153 Log.w(TAG, "Failed to send updatePackageList request to remote binder service: " + ex.getMessage());
157 private Bitmap drawableToBitmap(Drawable drawable) {
158 if (drawable instanceof BitmapDrawable)
159 return ((BitmapDrawable)drawable).getBitmap();
161 Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
162 Canvas canvas = new Canvas(bitmap);
163 drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
164 drawable.draw(canvas);