TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / android / appmgr / src / org / anbox / appmgr / PlatformService.java
1 /*
2  * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
3  *
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.
7  *
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.
12  *
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/>.
15  *
16  */
17
18 package org.anbox.appmgr;
19
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;
35
36 import java.util.List;
37 import java.io.ByteArrayOutputStream;
38
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";
43
44     private static final int TRANSACTION_updateApplicationList = (IBinder.FIRST_CALL_TRANSACTION + 2);
45
46     private IBinder mService = null;
47     private PackageManager mPm = null;
48
49     private void connectService() {
50         if (mService != null)
51             return;
52         mService = ServiceManager.getService(SERVICE_NAME);
53     }
54
55     public PlatformService(Context context) {
56         if (context != null) {
57             mPm = context.getPackageManager();
58         } else {
59             Log.w(TAG, "No context available");
60         }
61
62         Log.i(TAG, "Connected to platform service");
63     }
64
65     public void notifyPackageRemoved(String packageName) {
66         connectService();
67
68         if (mService == null)
69             return;
70
71         Log.i(TAG, "Sending package removed notification to host service");
72
73         Parcel data = Parcel.obtain();
74         data.writeInterfaceToken(DESCRIPTOR);
75         // No added or updated applications to report
76         data.writeInt(0);
77         // .. but a single removed application
78         data.writeInt(1);
79         data.writeString(packageName);
80
81         Parcel reply = Parcel.obtain();
82         try {
83             mService.transact(TRANSACTION_updateApplicationList, data, reply, 0);
84         }
85         catch (RemoteException ex) {
86             Log.w(TAG, "Failed to send updatePackageList request to remote binder service: " + ex.getMessage());
87         }
88     }
89
90     public void sendApplicationListUpdate() {
91         connectService();
92
93         if (mPm == null || mService == null)
94             return;
95
96         Parcel data = Parcel.obtain();
97         data.writeInterfaceToken(DESCRIPTOR);
98
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);
103
104             Intent launchIntent = mPm.getLaunchIntentForPackage(appInfo.packageName);
105             if (launchIntent == null)
106                 continue;
107
108             Drawable icon = null;
109             try {
110                 icon = mPm.getApplicationIcon(appInfo.packageName);
111             }
112             catch (PackageManager.NameNotFoundException ex) {
113                 continue;
114             }
115
116             if (icon == null)
117                 continue;
118
119             String name = appInfo.name;
120             CharSequence label = appInfo.loadLabel(mPm);
121             if (label != null)
122                 name = label.toString();
123
124             data.writeString(name);
125             data.writeString(appInfo.packageName);
126
127             data.writeString(launchIntent.getAction());
128             if (launchIntent.getData() != null)
129                 data.writeString(launchIntent.getData().toString());
130             else
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);
138
139             Bitmap iconBitmap = drawableToBitmap(icon);
140             ByteArrayOutputStream outStream = new ByteArrayOutputStream();
141             iconBitmap.compress(Bitmap.CompressFormat.PNG, 90, outStream);
142             data.writeByteArray(outStream.toByteArray());
143         }
144
145         // We don't have any removed applications to include in the update
146         data.writeInt(0);
147
148         Parcel reply = Parcel.obtain();
149         try {
150             mService.transact(TRANSACTION_updateApplicationList, data, reply, 0);
151         }
152         catch (RemoteException ex) {
153             Log.w(TAG, "Failed to send updatePackageList request to remote binder service: " + ex.getMessage());
154         }
155     }
156
157     private Bitmap drawableToBitmap(Drawable drawable) {
158         if (drawable instanceof BitmapDrawable)
159             return ((BitmapDrawable)drawable).getBitmap();
160
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);
165
166         return bitmap;
167     }
168 }