blob: 90293a48949f8b5b0481c58ad8245319f493c0be [file] [log] [blame]
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
Tor Norbye7b9c9122013-05-30 16:48:33 -070019import android.annotation.DrawableRes;
Alan Viveretteecd585a2015-04-13 10:32:51 -070020import android.annotation.NonNull;
21import android.annotation.Nullable;
Tor Norbye7b9c9122013-05-30 16:48:33 -070022import android.annotation.StringRes;
23import android.annotation.XmlRes;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080024import android.content.ComponentName;
25import android.content.ContentResolver;
26import android.content.Intent;
27import android.content.IntentFilter;
28import android.content.IntentSender;
29import android.content.pm.ActivityInfo;
30import android.content.pm.ApplicationInfo;
31import android.content.pm.ComponentInfo;
Anonymous Cowardceb1b0b2012-04-24 10:35:16 -070032import android.content.pm.ContainerEncryptionParams;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080033import android.content.pm.FeatureInfo;
34import android.content.pm.IPackageDataObserver;
35import android.content.pm.IPackageDeleteObserver;
36import android.content.pm.IPackageInstallObserver;
37import android.content.pm.IPackageManager;
38import android.content.pm.IPackageMoveObserver;
39import android.content.pm.IPackageStatsObserver;
40import android.content.pm.InstrumentationInfo;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080041import android.content.pm.IntentFilterVerificationInfo;
dcashman9d2f4412014-06-09 09:27:54 -070042import android.content.pm.KeySet;
Jeff Sharkey513a0742014-07-08 17:10:32 -070043import android.content.pm.ManifestDigest;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080044import android.content.pm.PackageInfo;
Jeff Sharkey3a44f3f2014-04-28 17:36:31 -070045import android.content.pm.PackageInstaller;
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +010046import android.content.pm.PackageItemInfo;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080047import android.content.pm.PackageManager;
Kenny Roote6cd0c72011-05-19 12:48:14 -070048import android.content.pm.ParceledListSlice;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080049import android.content.pm.PermissionGroupInfo;
50import android.content.pm.PermissionInfo;
51import android.content.pm.ProviderInfo;
52import android.content.pm.ResolveInfo;
53import android.content.pm.ServiceInfo;
Svetoslavc7d62f02014-09-04 15:39:54 -070054import android.content.pm.UserInfo;
rich cannings706e8ba2012-08-20 13:20:14 -070055import android.content.pm.VerificationParams;
Kenny Root0aaa0d92011-09-12 16:42:55 -070056import android.content.pm.VerifierDeviceIdentity;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080057import android.content.res.Resources;
58import android.content.res.XmlResourceParser;
Svetoslavc7d62f02014-09-04 15:39:54 -070059import android.graphics.Bitmap;
60import android.graphics.Canvas;
61import android.graphics.Rect;
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +010062import android.graphics.drawable.BitmapDrawable;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080063import android.graphics.drawable.Drawable;
64import android.net.Uri;
Jeff Sharkey50a05452015-04-29 11:24:52 -070065import android.os.Bundle;
Jeff Sharkey620b32b2015-04-23 19:36:02 -070066import android.os.Handler;
67import android.os.Looper;
68import android.os.Message;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080069import android.os.Process;
70import android.os.RemoteException;
Jeff Sharkeyb2b9ab82015-04-05 21:10:42 -070071import android.os.SystemProperties;
Amith Yamasani67df64b2012-12-14 12:09:36 -080072import android.os.UserHandle;
Nicolas Prevot88cc3462014-05-14 14:51:48 +010073import android.os.UserManager;
Jeff Sharkeye2d45be2015-04-15 17:14:12 -070074import android.os.storage.StorageManager;
75import android.os.storage.VolumeInfo;
Dianne Hackbornadd005c2013-07-17 18:43:12 -070076import android.util.ArrayMap;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080077import android.util.Log;
Jeff Browna492c3a2012-08-23 19:48:44 -070078import android.view.Display;
Jeff Sharkeyb2b9ab82015-04-05 21:10:42 -070079
80import dalvik.system.VMRuntime;
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -070081
82import com.android.internal.annotations.GuardedBy;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070083import com.android.internal.os.SomeArgs;
dcashman9d2f4412014-06-09 09:27:54 -070084import com.android.internal.util.Preconditions;
Alexandra Gherghina64d4dca2014-08-28 18:26:56 +010085import com.android.internal.util.UserIcons;
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -070086
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080087import java.lang.ref.WeakReference;
88import java.util.ArrayList;
Jeff Sharkey620b32b2015-04-23 19:36:02 -070089import java.util.Iterator;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080090import java.util.List;
Jeff Sharkey620b32b2015-04-23 19:36:02 -070091import java.util.Objects;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080092
93/*package*/
94final class ApplicationPackageManager extends PackageManager {
95 private static final String TAG = "ApplicationPackageManager";
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080096 private final static boolean DEBUG_ICONS = false;
97
Adam Lesinskid00bb5e2014-10-07 12:14:45 -070098 // Default flags to use with PackageManager when no flags are given.
99 private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES;
100
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -0700101 private final Object mLock = new Object();
102
103 @GuardedBy("mLock")
104 private UserManager mUserManager;
105 @GuardedBy("mLock")
106 private PackageInstaller mInstaller;
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +0100107
Jeff Sharkey620b32b2015-04-23 19:36:02 -0700108 @GuardedBy("mDelegates")
109 private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();
110
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +0100111 UserManager getUserManager() {
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -0700112 synchronized (mLock) {
113 if (mUserManager == null) {
114 mUserManager = UserManager.get(mContext);
115 }
116 return mUserManager;
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +0100117 }
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +0100118 }
119
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800120 @Override
121 public PackageInfo getPackageInfo(String packageName, int flags)
122 throws NameNotFoundException {
123 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700124 PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800125 if (pi != null) {
126 return pi;
127 }
128 } catch (RemoteException e) {
129 throw new RuntimeException("Package manager has died", e);
130 }
131
132 throw new NameNotFoundException(packageName);
133 }
134
135 @Override
136 public String[] currentToCanonicalPackageNames(String[] names) {
137 try {
138 return mPM.currentToCanonicalPackageNames(names);
139 } catch (RemoteException e) {
140 throw new RuntimeException("Package manager has died", e);
141 }
142 }
143
144 @Override
145 public String[] canonicalToCurrentPackageNames(String[] names) {
146 try {
147 return mPM.canonicalToCurrentPackageNames(names);
148 } catch (RemoteException e) {
149 throw new RuntimeException("Package manager has died", e);
150 }
151 }
152
153 @Override
154 public Intent getLaunchIntentForPackage(String packageName) {
155 // First see if the package has an INFO activity; the existence of
156 // such an activity is implied to be the desired front-door for the
157 // overall package (such as if it has multiple launcher entries).
158 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
159 intentToResolve.addCategory(Intent.CATEGORY_INFO);
160 intentToResolve.setPackage(packageName);
Dianne Hackborn19415762010-12-15 00:20:27 -0800161 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800162
163 // Otherwise, try to find a main launcher activity.
Dianne Hackborn19415762010-12-15 00:20:27 -0800164 if (ris == null || ris.size() <= 0) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800165 // reuse the intent instance
166 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
167 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
168 intentToResolve.setPackage(packageName);
Dianne Hackborn19415762010-12-15 00:20:27 -0800169 ris = queryIntentActivities(intentToResolve, 0);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800170 }
Dianne Hackborn19415762010-12-15 00:20:27 -0800171 if (ris == null || ris.size() <= 0) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800172 return null;
173 }
174 Intent intent = new Intent(intentToResolve);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800175 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn19415762010-12-15 00:20:27 -0800176 intent.setClassName(ris.get(0).activityInfo.packageName,
177 ris.get(0).activityInfo.name);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800178 return intent;
179 }
180
181 @Override
Jose Lima970417c2014-04-10 10:42:19 -0700182 public Intent getLeanbackLaunchIntentForPackage(String packageName) {
183 // Try to find a main leanback_launcher activity.
184 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
185 intentToResolve.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER);
186 intentToResolve.setPackage(packageName);
187 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
188
189 if (ris == null || ris.size() <= 0) {
190 return null;
191 }
192 Intent intent = new Intent(intentToResolve);
193 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
194 intent.setClassName(ris.get(0).activityInfo.packageName,
195 ris.get(0).activityInfo.name);
196 return intent;
197 }
198
199 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800200 public int[] getPackageGids(String packageName)
201 throws NameNotFoundException {
202 try {
Svetoslavc6d1c342015-02-26 14:44:43 -0800203 int[] gids = mPM.getPackageGids(packageName, mContext.getUserId());
204 if (gids != null) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800205 return gids;
206 }
207 } catch (RemoteException e) {
208 throw new RuntimeException("Package manager has died", e);
209 }
210
211 throw new NameNotFoundException(packageName);
212 }
213
214 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800215 public int getPackageUid(String packageName, int userHandle)
216 throws NameNotFoundException {
217 try {
218 int uid = mPM.getPackageUid(packageName, userHandle);
219 if (uid >= 0) {
220 return uid;
221 }
222 } catch (RemoteException e) {
223 throw new RuntimeException("Package manager has died", e);
224 }
225
226 throw new NameNotFoundException(packageName);
227 }
228
229 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800230 public PermissionInfo getPermissionInfo(String name, int flags)
231 throws NameNotFoundException {
232 try {
233 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
234 if (pi != null) {
235 return pi;
236 }
237 } catch (RemoteException e) {
238 throw new RuntimeException("Package manager has died", e);
239 }
240
241 throw new NameNotFoundException(name);
242 }
243
244 @Override
245 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
246 throws NameNotFoundException {
247 try {
248 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
249 if (pi != null) {
250 return pi;
251 }
252 } catch (RemoteException e) {
253 throw new RuntimeException("Package manager has died", e);
254 }
255
256 throw new NameNotFoundException(group);
257 }
258
259 @Override
260 public PermissionGroupInfo getPermissionGroupInfo(String name,
261 int flags) throws NameNotFoundException {
262 try {
263 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
264 if (pgi != null) {
265 return pgi;
266 }
267 } catch (RemoteException e) {
268 throw new RuntimeException("Package manager has died", e);
269 }
270
271 throw new NameNotFoundException(name);
272 }
273
274 @Override
275 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
276 try {
277 return mPM.getAllPermissionGroups(flags);
278 } catch (RemoteException e) {
279 throw new RuntimeException("Package manager has died", e);
280 }
281 }
282
283 @Override
284 public ApplicationInfo getApplicationInfo(String packageName, int flags)
285 throws NameNotFoundException {
286 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700287 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800288 if (ai != null) {
Narayan Kamathcaa71192014-07-16 11:06:43 +0100289 // This is a temporary hack. Callers must use
290 // createPackageContext(packageName).getApplicationInfo() to
291 // get the right paths.
292 maybeAdjustApplicationInfo(ai);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800293 return ai;
294 }
295 } catch (RemoteException e) {
296 throw new RuntimeException("Package manager has died", e);
297 }
298
299 throw new NameNotFoundException(packageName);
300 }
301
Narayan Kamathcaa71192014-07-16 11:06:43 +0100302 private static void maybeAdjustApplicationInfo(ApplicationInfo info) {
303 // If we're dealing with a multi-arch application that has both
304 // 32 and 64 bit shared libraries, we might need to choose the secondary
305 // depending on what the current runtime's instruction set is.
306 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
307 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
jgu214741cd92014-12-17 17:23:29 -0500308
309 // Get the instruction set that the libraries of secondary Abi is supported.
310 // In presence of a native bridge this might be different than the one secondary Abi used.
311 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
312 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
313 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
Narayan Kamathcaa71192014-07-16 11:06:43 +0100314
315 // If the runtimeIsa is the same as the primary isa, then we do nothing.
316 // Everything will be set up correctly because info.nativeLibraryDir will
317 // correspond to the right ISA.
318 if (runtimeIsa.equals(secondaryIsa)) {
319 info.nativeLibraryDir = info.secondaryNativeLibraryDir;
320 }
321 }
322 }
323
324
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800325 @Override
326 public ActivityInfo getActivityInfo(ComponentName className, int flags)
327 throws NameNotFoundException {
328 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700329 ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800330 if (ai != null) {
331 return ai;
332 }
333 } catch (RemoteException e) {
334 throw new RuntimeException("Package manager has died", e);
335 }
336
337 throw new NameNotFoundException(className.toString());
338 }
339
340 @Override
341 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
342 throws NameNotFoundException {
343 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700344 ActivityInfo ai = mPM.getReceiverInfo(className, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800345 if (ai != null) {
346 return ai;
347 }
348 } catch (RemoteException e) {
349 throw new RuntimeException("Package manager has died", e);
350 }
351
352 throw new NameNotFoundException(className.toString());
353 }
354
355 @Override
356 public ServiceInfo getServiceInfo(ComponentName className, int flags)
357 throws NameNotFoundException {
358 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700359 ServiceInfo si = mPM.getServiceInfo(className, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800360 if (si != null) {
361 return si;
362 }
363 } catch (RemoteException e) {
364 throw new RuntimeException("Package manager has died", e);
365 }
366
367 throw new NameNotFoundException(className.toString());
368 }
369
370 @Override
371 public ProviderInfo getProviderInfo(ComponentName className, int flags)
372 throws NameNotFoundException {
373 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700374 ProviderInfo pi = mPM.getProviderInfo(className, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800375 if (pi != null) {
376 return pi;
377 }
378 } catch (RemoteException e) {
379 throw new RuntimeException("Package manager has died", e);
380 }
381
382 throw new NameNotFoundException(className.toString());
383 }
384
385 @Override
386 public String[] getSystemSharedLibraryNames() {
387 try {
388 return mPM.getSystemSharedLibraryNames();
389 } catch (RemoteException e) {
390 throw new RuntimeException("Package manager has died", e);
391 }
392 }
393
394 @Override
395 public FeatureInfo[] getSystemAvailableFeatures() {
396 try {
397 return mPM.getSystemAvailableFeatures();
398 } catch (RemoteException e) {
399 throw new RuntimeException("Package manager has died", e);
400 }
401 }
402
403 @Override
404 public boolean hasSystemFeature(String name) {
405 try {
406 return mPM.hasSystemFeature(name);
407 } catch (RemoteException e) {
408 throw new RuntimeException("Package manager has died", e);
409 }
410 }
411
412 @Override
413 public int checkPermission(String permName, String pkgName) {
414 try {
Svetoslavc6d1c342015-02-26 14:44:43 -0800415 return mPM.checkPermission(permName, pkgName, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800416 } catch (RemoteException e) {
417 throw new RuntimeException("Package manager has died", e);
418 }
419 }
420
421 @Override
422 public boolean addPermission(PermissionInfo info) {
423 try {
424 return mPM.addPermission(info);
425 } catch (RemoteException e) {
426 throw new RuntimeException("Package manager has died", e);
427 }
428 }
429
430 @Override
431 public boolean addPermissionAsync(PermissionInfo info) {
432 try {
433 return mPM.addPermissionAsync(info);
434 } catch (RemoteException e) {
435 throw new RuntimeException("Package manager has died", e);
436 }
437 }
438
439 @Override
440 public void removePermission(String name) {
441 try {
442 mPM.removePermission(name);
443 } catch (RemoteException e) {
444 throw new RuntimeException("Package manager has died", e);
445 }
446 }
447
448 @Override
Svetoslavc6d1c342015-02-26 14:44:43 -0800449 public void grantPermission(String packageName, String permissionName, UserHandle user) {
Dianne Hackborne639da72012-02-21 15:11:13 -0800450 try {
Svetoslavc6d1c342015-02-26 14:44:43 -0800451 mPM.grantPermission(packageName, permissionName, user.getIdentifier());
Dianne Hackborne639da72012-02-21 15:11:13 -0800452 } catch (RemoteException e) {
453 throw new RuntimeException("Package manager has died", e);
454 }
455 }
456
457 @Override
Svetoslavc6d1c342015-02-26 14:44:43 -0800458 public void revokePermission(String packageName, String permissionName, UserHandle user) {
Dianne Hackborne639da72012-02-21 15:11:13 -0800459 try {
Svetoslavc6d1c342015-02-26 14:44:43 -0800460 mPM.revokePermission(packageName, permissionName, user.getIdentifier());
Dianne Hackborne639da72012-02-21 15:11:13 -0800461 } catch (RemoteException e) {
462 throw new RuntimeException("Package manager has died", e);
463 }
464 }
465
466 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800467 public int checkSignatures(String pkg1, String pkg2) {
468 try {
469 return mPM.checkSignatures(pkg1, pkg2);
470 } catch (RemoteException e) {
471 throw new RuntimeException("Package manager has died", e);
472 }
473 }
474
475 @Override
476 public int checkSignatures(int uid1, int uid2) {
477 try {
478 return mPM.checkUidSignatures(uid1, uid2);
479 } catch (RemoteException e) {
480 throw new RuntimeException("Package manager has died", e);
481 }
482 }
483
484 @Override
485 public String[] getPackagesForUid(int uid) {
486 try {
487 return mPM.getPackagesForUid(uid);
488 } catch (RemoteException e) {
489 throw new RuntimeException("Package manager has died", e);
490 }
491 }
492
493 @Override
494 public String getNameForUid(int uid) {
495 try {
496 return mPM.getNameForUid(uid);
497 } catch (RemoteException e) {
498 throw new RuntimeException("Package manager has died", e);
499 }
500 }
501
502 @Override
503 public int getUidForSharedUser(String sharedUserName)
504 throws NameNotFoundException {
505 try {
506 int uid = mPM.getUidForSharedUser(sharedUserName);
507 if(uid != -1) {
508 return uid;
509 }
510 } catch (RemoteException e) {
511 throw new RuntimeException("Package manager has died", e);
512 }
513 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
514 }
515
Kenny Roote6cd0c72011-05-19 12:48:14 -0700516 @SuppressWarnings("unchecked")
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800517 @Override
518 public List<PackageInfo> getInstalledPackages(int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700519 return getInstalledPackages(flags, mContext.getUserId());
Amith Yamasani151ec4c2012-09-07 19:25:16 -0700520 }
521
522 /** @hide */
523 @Override
524 public List<PackageInfo> getInstalledPackages(int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800525 try {
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -0800526 ParceledListSlice<PackageInfo> slice = mPM.getInstalledPackages(flags, userId);
527 return slice.getList();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800528 } catch (RemoteException e) {
529 throw new RuntimeException("Package manager has died", e);
530 }
531 }
532
Kenny Roote6cd0c72011-05-19 12:48:14 -0700533 @SuppressWarnings("unchecked")
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800534 @Override
Dianne Hackborne7991752013-01-16 17:56:46 -0800535 public List<PackageInfo> getPackagesHoldingPermissions(
536 String[] permissions, int flags) {
537 final int userId = mContext.getUserId();
538 try {
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -0800539 ParceledListSlice<PackageInfo> slice = mPM.getPackagesHoldingPermissions(
540 permissions, flags, userId);
541 return slice.getList();
Dianne Hackborne7991752013-01-16 17:56:46 -0800542 } catch (RemoteException e) {
543 throw new RuntimeException("Package manager has died", e);
544 }
545 }
546
547 @SuppressWarnings("unchecked")
548 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800549 public List<ApplicationInfo> getInstalledApplications(int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700550 final int userId = mContext.getUserId();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800551 try {
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -0800552 ParceledListSlice<ApplicationInfo> slice = mPM.getInstalledApplications(flags, userId);
553 return slice.getList();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800554 } catch (RemoteException e) {
555 throw new RuntimeException("Package manager has died", e);
556 }
557 }
558
559 @Override
560 public ResolveInfo resolveActivity(Intent intent, int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700561 return resolveActivityAsUser(intent, flags, mContext.getUserId());
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700562 }
563
564 @Override
565 public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800566 try {
567 return mPM.resolveIntent(
568 intent,
569 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700570 flags,
571 userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800572 } catch (RemoteException e) {
573 throw new RuntimeException("Package manager has died", e);
574 }
575 }
576
577 @Override
578 public List<ResolveInfo> queryIntentActivities(Intent intent,
579 int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700580 return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId());
Amith Yamasani151ec4c2012-09-07 19:25:16 -0700581 }
582
583 /** @hide Same as above but for a specific user */
584 @Override
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700585 public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
Amith Yamasani151ec4c2012-09-07 19:25:16 -0700586 int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800587 try {
588 return mPM.queryIntentActivities(
589 intent,
590 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Amith Yamasani483f3b02012-03-13 16:08:00 -0700591 flags,
Amith Yamasani151ec4c2012-09-07 19:25:16 -0700592 userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800593 } catch (RemoteException e) {
594 throw new RuntimeException("Package manager has died", e);
595 }
596 }
597
598 @Override
599 public List<ResolveInfo> queryIntentActivityOptions(
600 ComponentName caller, Intent[] specifics, Intent intent,
601 int flags) {
602 final ContentResolver resolver = mContext.getContentResolver();
603
604 String[] specificTypes = null;
605 if (specifics != null) {
606 final int N = specifics.length;
607 for (int i=0; i<N; i++) {
608 Intent sp = specifics[i];
609 if (sp != null) {
610 String t = sp.resolveTypeIfNeeded(resolver);
611 if (t != null) {
612 if (specificTypes == null) {
613 specificTypes = new String[N];
614 }
615 specificTypes[i] = t;
616 }
617 }
618 }
619 }
620
621 try {
622 return mPM.queryIntentActivityOptions(caller, specifics,
623 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700624 flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800625 } catch (RemoteException e) {
626 throw new RuntimeException("Package manager has died", e);
627 }
628 }
629
Amith Yamasanif203aee2012-08-29 18:41:53 -0700630 /**
631 * @hide
632 */
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800633 @Override
Amith Yamasanif203aee2012-08-29 18:41:53 -0700634 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800635 try {
636 return mPM.queryIntentReceivers(
637 intent,
638 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Amith Yamasani483f3b02012-03-13 16:08:00 -0700639 flags,
Amith Yamasanif203aee2012-08-29 18:41:53 -0700640 userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800641 } catch (RemoteException e) {
642 throw new RuntimeException("Package manager has died", e);
643 }
644 }
645
646 @Override
Amith Yamasanif203aee2012-08-29 18:41:53 -0700647 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700648 return queryBroadcastReceivers(intent, flags, mContext.getUserId());
Amith Yamasanif203aee2012-08-29 18:41:53 -0700649 }
650
651 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800652 public ResolveInfo resolveService(Intent intent, int flags) {
653 try {
654 return mPM.resolveService(
655 intent,
656 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Amith Yamasani483f3b02012-03-13 16:08:00 -0700657 flags,
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700658 mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800659 } catch (RemoteException e) {
660 throw new RuntimeException("Package manager has died", e);
661 }
662 }
663
664 @Override
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700665 public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800666 try {
667 return mPM.queryIntentServices(
668 intent,
669 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Amith Yamasani483f3b02012-03-13 16:08:00 -0700670 flags,
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700671 userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800672 } catch (RemoteException e) {
673 throw new RuntimeException("Package manager has died", e);
674 }
675 }
676
677 @Override
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700678 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700679 return queryIntentServicesAsUser(intent, flags, mContext.getUserId());
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700680 }
681
682 @Override
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700683 public List<ResolveInfo> queryIntentContentProvidersAsUser(
684 Intent intent, int flags, int userId) {
685 try {
686 return mPM.queryIntentContentProviders(intent,
687 intent.resolveTypeIfNeeded(mContext.getContentResolver()), flags, userId);
688 } catch (RemoteException e) {
689 throw new RuntimeException("Package manager has died", e);
690 }
691 }
692
693 @Override
694 public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
695 return queryIntentContentProvidersAsUser(intent, flags, mContext.getUserId());
696 }
697
698 @Override
Alexandra Gherghina0363c3e2014-06-23 13:34:59 +0100699 public ProviderInfo resolveContentProvider(String name, int flags) {
700 return resolveContentProviderAsUser(name, flags, mContext.getUserId());
701 }
702
703 /** @hide **/
704 @Override
705 public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800706 try {
Alexandra Gherghina0363c3e2014-06-23 13:34:59 +0100707 return mPM.resolveContentProvider(name, flags, userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800708 } catch (RemoteException e) {
709 throw new RuntimeException("Package manager has died", e);
710 }
711 }
712
713 @Override
714 public List<ProviderInfo> queryContentProviders(String processName,
715 int uid, int flags) {
716 try {
717 return mPM.queryContentProviders(processName, uid, flags);
718 } catch (RemoteException e) {
719 throw new RuntimeException("Package manager has died", e);
720 }
721 }
722
723 @Override
724 public InstrumentationInfo getInstrumentationInfo(
725 ComponentName className, int flags)
726 throws NameNotFoundException {
727 try {
728 InstrumentationInfo ii = mPM.getInstrumentationInfo(
729 className, flags);
730 if (ii != null) {
731 return ii;
732 }
733 } catch (RemoteException e) {
734 throw new RuntimeException("Package manager has died", e);
735 }
736
737 throw new NameNotFoundException(className.toString());
738 }
739
740 @Override
741 public List<InstrumentationInfo> queryInstrumentation(
742 String targetPackage, int flags) {
743 try {
744 return mPM.queryInstrumentation(targetPackage, flags);
745 } catch (RemoteException e) {
746 throw new RuntimeException("Package manager has died", e);
747 }
748 }
749
Alan Viveretteecd585a2015-04-13 10:32:51 -0700750 @Nullable
751 @Override
752 public Drawable getDrawable(String packageName, @DrawableRes int resId,
753 @Nullable ApplicationInfo appInfo) {
754 final ResourceName name = new ResourceName(packageName, resId);
755 final Drawable cachedIcon = getCachedIcon(name);
756 if (cachedIcon != null) {
757 return cachedIcon;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800758 }
Alan Viveretteecd585a2015-04-13 10:32:51 -0700759
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800760 if (appInfo == null) {
761 try {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700762 appInfo = getApplicationInfo(packageName, sDefaultFlags);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800763 } catch (NameNotFoundException e) {
764 return null;
765 }
766 }
Alan Viveretteecd585a2015-04-13 10:32:51 -0700767
768 if (resId != 0) {
769 try {
770 final Resources r = getResourcesForApplication(appInfo);
771 final Drawable dr = r.getDrawable(resId, null);
772 if (dr != null) {
773 putCachedIcon(name, dr);
774 }
775
776 if (false) {
777 RuntimeException e = new RuntimeException("here");
778 e.fillInStackTrace();
779 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resId)
780 + " from package " + packageName
781 + ": app scale=" + r.getCompatibilityInfo().applicationScale
782 + ", caller scale=" + mContext.getResources()
783 .getCompatibilityInfo().applicationScale,
784 e);
785 }
Ricky Wai3ce46252015-04-15 16:12:22 +0100786 if (DEBUG_ICONS) {
Alan Viveretteecd585a2015-04-13 10:32:51 -0700787 Log.v(TAG, "Getting drawable 0x"
788 + Integer.toHexString(resId) + " from " + r
789 + ": " + dr);
Ricky Wai3ce46252015-04-15 16:12:22 +0100790 }
791 return dr;
Alan Viveretteecd585a2015-04-13 10:32:51 -0700792 } catch (NameNotFoundException e) {
793 Log.w("PackageManager", "Failure retrieving resources for "
794 + appInfo.packageName);
795 } catch (Resources.NotFoundException e) {
796 Log.w("PackageManager", "Failure retrieving resources for "
797 + appInfo.packageName + ": " + e.getMessage());
798 } catch (Exception e) {
799 // If an exception was thrown, fall through to return
800 // default icon.
801 Log.w("PackageManager", "Failure retrieving icon 0x"
802 + Integer.toHexString(resId) + " in package "
803 + packageName, e);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800804 }
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800805 }
Alan Viveretteecd585a2015-04-13 10:32:51 -0700806
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800807 return null;
808 }
809
810 @Override public Drawable getActivityIcon(ComponentName activityName)
811 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700812 return getActivityInfo(activityName, sDefaultFlags).loadIcon(this);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800813 }
814
815 @Override public Drawable getActivityIcon(Intent intent)
816 throws NameNotFoundException {
817 if (intent.getComponent() != null) {
818 return getActivityIcon(intent.getComponent());
819 }
820
821 ResolveInfo info = resolveActivity(
822 intent, PackageManager.MATCH_DEFAULT_ONLY);
823 if (info != null) {
824 return info.activityInfo.loadIcon(this);
825 }
826
Romain Guy39fe17c2011-11-30 10:34:07 -0800827 throw new NameNotFoundException(intent.toUri(0));
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800828 }
829
830 @Override public Drawable getDefaultActivityIcon() {
831 return Resources.getSystem().getDrawable(
832 com.android.internal.R.drawable.sym_def_app_icon);
833 }
834
835 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
836 return info.loadIcon(this);
837 }
838
839 @Override public Drawable getApplicationIcon(String packageName)
840 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700841 return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags));
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800842 }
843
844 @Override
Jose Limaf78e3122014-03-06 12:13:15 -0800845 public Drawable getActivityBanner(ComponentName activityName)
846 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700847 return getActivityInfo(activityName, sDefaultFlags).loadBanner(this);
Jose Limaf78e3122014-03-06 12:13:15 -0800848 }
849
850 @Override
851 public Drawable getActivityBanner(Intent intent)
852 throws NameNotFoundException {
853 if (intent.getComponent() != null) {
854 return getActivityBanner(intent.getComponent());
855 }
856
857 ResolveInfo info = resolveActivity(
858 intent, PackageManager.MATCH_DEFAULT_ONLY);
859 if (info != null) {
860 return info.activityInfo.loadBanner(this);
861 }
862
863 throw new NameNotFoundException(intent.toUri(0));
864 }
865
866 @Override
867 public Drawable getApplicationBanner(ApplicationInfo info) {
868 return info.loadBanner(this);
869 }
870
871 @Override
872 public Drawable getApplicationBanner(String packageName)
873 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700874 return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags));
Jose Limaf78e3122014-03-06 12:13:15 -0800875 }
876
877 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800878 public Drawable getActivityLogo(ComponentName activityName)
879 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700880 return getActivityInfo(activityName, sDefaultFlags).loadLogo(this);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800881 }
882
883 @Override
884 public Drawable getActivityLogo(Intent intent)
885 throws NameNotFoundException {
886 if (intent.getComponent() != null) {
887 return getActivityLogo(intent.getComponent());
888 }
889
890 ResolveInfo info = resolveActivity(
891 intent, PackageManager.MATCH_DEFAULT_ONLY);
892 if (info != null) {
893 return info.activityInfo.loadLogo(this);
894 }
895
896 throw new NameNotFoundException(intent.toUri(0));
897 }
898
899 @Override
900 public Drawable getApplicationLogo(ApplicationInfo info) {
901 return info.loadLogo(this);
902 }
903
904 @Override
905 public Drawable getApplicationLogo(String packageName)
906 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700907 return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags));
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800908 }
909
Svetoslavc7d62f02014-09-04 15:39:54 -0700910 @Override
911 public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
912 final int badgeResId = getBadgeResIdForUser(user.getIdentifier());
913 if (badgeResId == 0) {
914 return icon;
915 }
916 Drawable badgeIcon = getDrawable("system", badgeResId, null);
917 return getBadgedDrawable(icon, badgeIcon, null, true);
918 }
919
920 @Override
921 public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
922 Rect badgeLocation, int badgeDensity) {
923 Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity);
924 if (badgeDrawable == null) {
925 return drawable;
926 }
927 return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
928 }
929
930 @Override
931 public Drawable getUserBadgeForDensity(UserHandle user, int density) {
932 UserInfo userInfo = getUserIfProfile(user.getIdentifier());
933 if (userInfo != null && userInfo.isManagedProfile()) {
934 if (density <= 0) {
935 density = mContext.getResources().getDisplayMetrics().densityDpi;
936 }
937 return Resources.getSystem().getDrawableForDensity(
938 com.android.internal.R.drawable.ic_corp_badge, density);
939 }
940 return null;
941 }
942
943 @Override
944 public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
945 UserInfo userInfo = getUserIfProfile(user.getIdentifier());
946 if (userInfo != null && userInfo.isManagedProfile()) {
947 return Resources.getSystem().getString(
948 com.android.internal.R.string.managed_profile_label_badge, label);
949 }
950 return label;
951 }
952
Alan Viveretteecd585a2015-04-13 10:32:51 -0700953 @Override
954 public Resources getResourcesForActivity(ComponentName activityName)
955 throws NameNotFoundException {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800956 return getResourcesForApplication(
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700957 getActivityInfo(activityName, sDefaultFlags).applicationInfo);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800958 }
959
Alan Viveretteecd585a2015-04-13 10:32:51 -0700960 @Override
961 public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
962 throws NameNotFoundException {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800963 if (app.packageName.equals("system")) {
964 return mContext.mMainThread.getSystemContext().getResources();
965 }
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700966 final boolean sameUid = (app.uid == Process.myUid());
Alan Viveretteecd585a2015-04-13 10:32:51 -0700967 final Resources r = mContext.mMainThread.getTopLevelResources(
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700968 sameUid ? app.sourceDir : app.publicSourceDir,
969 sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700970 app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
971 null, mContext.mPackageInfo);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800972 if (r != null) {
973 return r;
974 }
975 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
976 }
977
Alan Viveretteecd585a2015-04-13 10:32:51 -0700978 @Override
979 public Resources getResourcesForApplication(String appPackageName)
980 throws NameNotFoundException {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800981 return getResourcesForApplication(
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700982 getApplicationInfo(appPackageName, sDefaultFlags));
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800983 }
984
Amith Yamasani98edc952012-09-25 14:09:27 -0700985 /** @hide */
986 @Override
987 public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
988 throws NameNotFoundException {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700989 if (userId < 0) {
990 throw new IllegalArgumentException(
991 "Call does not support special user #" + userId);
992 }
993 if ("system".equals(appPackageName)) {
994 return mContext.mMainThread.getSystemContext().getResources();
995 }
Amith Yamasani98edc952012-09-25 14:09:27 -0700996 try {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700997 ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
Amith Yamasani98edc952012-09-25 14:09:27 -0700998 if (ai != null) {
999 return getResourcesForApplication(ai);
1000 }
1001 } catch (RemoteException e) {
1002 throw new RuntimeException("Package manager has died", e);
1003 }
1004 throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
1005 }
1006
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001007 int mCachedSafeMode = -1;
1008 @Override public boolean isSafeMode() {
1009 try {
1010 if (mCachedSafeMode < 0) {
1011 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
1012 }
1013 return mCachedSafeMode != 0;
1014 } catch (RemoteException e) {
1015 throw new RuntimeException("Package manager has died", e);
1016 }
1017 }
1018
1019 static void configurationChanged() {
1020 synchronized (sSync) {
1021 sIconCache.clear();
1022 sStringCache.clear();
1023 }
1024 }
1025
1026 ApplicationPackageManager(ContextImpl context,
1027 IPackageManager pm) {
1028 mContext = context;
1029 mPM = pm;
1030 }
1031
Alan Viveretteecd585a2015-04-13 10:32:51 -07001032 @Nullable
1033 private Drawable getCachedIcon(@NonNull ResourceName name) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001034 synchronized (sSync) {
Alan Viveretteecd585a2015-04-13 10:32:51 -07001035 final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001036 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
1037 + name + ": " + wr);
1038 if (wr != null) { // we have the activity
Alan Viveretteecd585a2015-04-13 10:32:51 -07001039 final Drawable.ConstantState state = wr.get();
Romain Guy39fe17c2011-11-30 10:34:07 -08001040 if (state != null) {
1041 if (DEBUG_ICONS) {
1042 Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
1043 }
1044 // Note: It's okay here to not use the newDrawable(Resources) variant
1045 // of the API. The ConstantState comes from a drawable that was
1046 // originally created by passing the proper app Resources instance
1047 // which means the state should already contain the proper
1048 // resources specific information (like density.) See
1049 // BitmapDrawable.BitmapState for instance.
1050 return state.newDrawable();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001051 }
1052 // our entry has been purged
1053 sIconCache.remove(name);
1054 }
1055 }
1056 return null;
1057 }
1058
Alan Viveretteecd585a2015-04-13 10:32:51 -07001059 private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001060 synchronized (sSync) {
Alan Viveretteecd585a2015-04-13 10:32:51 -07001061 sIconCache.put(name, new WeakReference<>(dr.getConstantState()));
Romain Guy39fe17c2011-11-30 10:34:07 -08001062 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001063 }
1064 }
1065
Romain Guy39fe17c2011-11-30 10:34:07 -08001066 static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001067 boolean immediateGc = false;
1068 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
1069 immediateGc = true;
1070 }
1071 if (pkgList != null && (pkgList.length > 0)) {
1072 boolean needCleanup = false;
1073 for (String ssp : pkgList) {
1074 synchronized (sSync) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001075 for (int i=sIconCache.size()-1; i>=0; i--) {
1076 ResourceName nm = sIconCache.keyAt(i);
1077 if (nm.packageName.equals(ssp)) {
1078 //Log.i(TAG, "Removing cached drawable for " + nm);
1079 sIconCache.removeAt(i);
1080 needCleanup = true;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001081 }
1082 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001083 for (int i=sStringCache.size()-1; i>=0; i--) {
1084 ResourceName nm = sStringCache.keyAt(i);
1085 if (nm.packageName.equals(ssp)) {
1086 //Log.i(TAG, "Removing cached string for " + nm);
1087 sStringCache.removeAt(i);
1088 needCleanup = true;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001089 }
1090 }
1091 }
1092 }
1093 if (needCleanup || hasPkgInfo) {
1094 if (immediateGc) {
1095 // Schedule an immediate gc.
1096 Runtime.getRuntime().gc();
1097 } else {
1098 ActivityThread.currentActivityThread().scheduleGcIdler();
1099 }
1100 }
1101 }
1102 }
1103
1104 private static final class ResourceName {
1105 final String packageName;
1106 final int iconId;
1107
1108 ResourceName(String _packageName, int _iconId) {
1109 packageName = _packageName;
1110 iconId = _iconId;
1111 }
1112
1113 ResourceName(ApplicationInfo aInfo, int _iconId) {
1114 this(aInfo.packageName, _iconId);
1115 }
1116
1117 ResourceName(ComponentInfo cInfo, int _iconId) {
1118 this(cInfo.applicationInfo.packageName, _iconId);
1119 }
1120
1121 ResourceName(ResolveInfo rInfo, int _iconId) {
1122 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
1123 }
1124
1125 @Override
1126 public boolean equals(Object o) {
1127 if (this == o) return true;
1128 if (o == null || getClass() != o.getClass()) return false;
1129
1130 ResourceName that = (ResourceName) o;
1131
1132 if (iconId != that.iconId) return false;
1133 return !(packageName != null ?
1134 !packageName.equals(that.packageName) : that.packageName != null);
1135
1136 }
1137
1138 @Override
1139 public int hashCode() {
1140 int result;
1141 result = packageName.hashCode();
1142 result = 31 * result + iconId;
1143 return result;
1144 }
1145
1146 @Override
1147 public String toString() {
1148 return "{ResourceName " + packageName + " / " + iconId + "}";
1149 }
1150 }
1151
1152 private CharSequence getCachedString(ResourceName name) {
1153 synchronized (sSync) {
1154 WeakReference<CharSequence> wr = sStringCache.get(name);
1155 if (wr != null) { // we have the activity
1156 CharSequence cs = wr.get();
1157 if (cs != null) {
1158 return cs;
1159 }
1160 // our entry has been purged
1161 sStringCache.remove(name);
1162 }
1163 }
1164 return null;
1165 }
1166
1167 private void putCachedString(ResourceName name, CharSequence cs) {
1168 synchronized (sSync) {
1169 sStringCache.put(name, new WeakReference<CharSequence>(cs));
1170 }
1171 }
1172
1173 @Override
Tor Norbye7b9c9122013-05-30 16:48:33 -07001174 public CharSequence getText(String packageName, @StringRes int resid,
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001175 ApplicationInfo appInfo) {
1176 ResourceName name = new ResourceName(packageName, resid);
1177 CharSequence text = getCachedString(name);
1178 if (text != null) {
1179 return text;
1180 }
1181 if (appInfo == null) {
1182 try {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -07001183 appInfo = getApplicationInfo(packageName, sDefaultFlags);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001184 } catch (NameNotFoundException e) {
1185 return null;
1186 }
1187 }
1188 try {
1189 Resources r = getResourcesForApplication(appInfo);
1190 text = r.getText(resid);
1191 putCachedString(name, text);
1192 return text;
1193 } catch (NameNotFoundException e) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001194 Log.w("PackageManager", "Failure retrieving resources for "
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001195 + appInfo.packageName);
1196 } catch (RuntimeException e) {
1197 // If an exception was thrown, fall through to return
1198 // default icon.
1199 Log.w("PackageManager", "Failure retrieving text 0x"
1200 + Integer.toHexString(resid) + " in package "
1201 + packageName, e);
1202 }
1203 return null;
1204 }
1205
1206 @Override
Tor Norbye7b9c9122013-05-30 16:48:33 -07001207 public XmlResourceParser getXml(String packageName, @XmlRes int resid,
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001208 ApplicationInfo appInfo) {
1209 if (appInfo == null) {
1210 try {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -07001211 appInfo = getApplicationInfo(packageName, sDefaultFlags);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001212 } catch (NameNotFoundException e) {
1213 return null;
1214 }
1215 }
1216 try {
1217 Resources r = getResourcesForApplication(appInfo);
1218 return r.getXml(resid);
1219 } catch (RuntimeException e) {
1220 // If an exception was thrown, fall through to return
1221 // default icon.
1222 Log.w("PackageManager", "Failure retrieving xml 0x"
1223 + Integer.toHexString(resid) + " in package "
1224 + packageName, e);
1225 } catch (NameNotFoundException e) {
Alon Albert3fa51e32010-11-11 09:24:04 -08001226 Log.w("PackageManager", "Failure retrieving resources for "
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001227 + appInfo.packageName);
1228 }
1229 return null;
1230 }
1231
1232 @Override
1233 public CharSequence getApplicationLabel(ApplicationInfo info) {
1234 return info.loadLabel(this);
1235 }
1236
1237 @Override
1238 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1239 String installerPackageName) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001240 final VerificationParams verificationParams = new VerificationParams(null, null,
1241 null, VerificationParams.NO_UID, null);
1242 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1243 installerPackageName, verificationParams, null);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001244 }
1245
1246 @Override
Kenny Root5ab21572011-07-27 11:11:19 -07001247 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
1248 int flags, String installerPackageName, Uri verificationURI,
Rich Canningse1d7c712012-08-08 12:46:06 -07001249 ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001250 final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
1251 null, VerificationParams.NO_UID, manifestDigest);
1252 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1253 installerPackageName, verificationParams, encryptionParams);
Kenny Root5ab21572011-07-27 11:11:19 -07001254 }
1255
1256 @Override
John Spurlock8a985d22014-02-25 09:40:05 -05001257 public void installPackageWithVerificationAndEncryption(Uri packageURI,
rich cannings706e8ba2012-08-20 13:20:14 -07001258 IPackageInstallObserver observer, int flags, String installerPackageName,
1259 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001260 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1261 installerPackageName, verificationParams, encryptionParams);
Christopher Tatef1977b42014-03-24 16:25:51 -07001262 }
1263
Christopher Tatef1977b42014-03-24 16:25:51 -07001264 @Override
1265 public void installPackage(Uri packageURI, PackageInstallObserver observer,
1266 int flags, String installerPackageName) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001267 final VerificationParams verificationParams = new VerificationParams(null, null,
1268 null, VerificationParams.NO_UID, null);
1269 installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null);
Christopher Tatef1977b42014-03-24 16:25:51 -07001270 }
1271
1272 @Override
1273 public void installPackageWithVerification(Uri packageURI,
1274 PackageInstallObserver observer, int flags, String installerPackageName,
1275 Uri verificationURI, ManifestDigest manifestDigest,
1276 ContainerEncryptionParams encryptionParams) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001277 final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
1278 null, VerificationParams.NO_UID, manifestDigest);
1279 installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
1280 encryptionParams);
Christopher Tatef1977b42014-03-24 16:25:51 -07001281 }
1282
1283 @Override
1284 public void installPackageWithVerificationAndEncryption(Uri packageURI,
1285 PackageInstallObserver observer, int flags, String installerPackageName,
1286 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001287 installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
1288 encryptionParams);
1289 }
1290
1291 private void installCommon(Uri packageURI,
1292 PackageInstallObserver observer, int flags, String installerPackageName,
1293 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1294 if (!"file".equals(packageURI.getScheme())) {
1295 throw new UnsupportedOperationException("Only file:// URIs are supported");
1296 }
1297 if (encryptionParams != null) {
1298 throw new UnsupportedOperationException("ContainerEncryptionParams not supported");
1299 }
1300
1301 final String originPath = packageURI.getPath();
Christopher Tatef1977b42014-03-24 16:25:51 -07001302 try {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001303 mPM.installPackage(originPath, observer.getBinder(), flags, installerPackageName,
1304 verificationParams, null);
1305 } catch (RemoteException ignored) {
rich cannings706e8ba2012-08-20 13:20:14 -07001306 }
1307 }
1308
1309 @Override
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001310 public int installExistingPackage(String packageName)
1311 throws NameNotFoundException {
1312 try {
Amith Yamasani67df64b2012-12-14 12:09:36 -08001313 int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001314 if (res == INSTALL_FAILED_INVALID_URI) {
1315 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1316 }
1317 return res;
1318 } catch (RemoteException e) {
1319 // Should never happen!
1320 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1321 }
1322 }
1323
1324 @Override
Kenny Root3a9b5fb2011-09-20 14:15:38 -07001325 public void verifyPendingInstall(int id, int response) {
Kenny Root5ab21572011-07-27 11:11:19 -07001326 try {
Kenny Root3a9b5fb2011-09-20 14:15:38 -07001327 mPM.verifyPendingInstall(id, response);
Kenny Root5ab21572011-07-27 11:11:19 -07001328 } catch (RemoteException e) {
1329 // Should never happen!
1330 }
1331 }
1332
1333 @Override
rich canningsd9ef3e52012-08-22 14:28:05 -07001334 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1335 long millisecondsToDelay) {
1336 try {
1337 mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1338 } catch (RemoteException e) {
1339 // Should never happen!
1340 }
1341 }
1342
1343 @Override
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -08001344 public void verifyIntentFilter(int id, int verificationCode, List<String> outFailedDomains) {
1345 try {
1346 mPM.verifyIntentFilter(id, verificationCode, outFailedDomains);
1347 } catch (RemoteException e) {
1348 // Should never happen!
1349 }
1350 }
1351
1352 @Override
1353 public int getIntentVerificationStatus(String packageName, int userId) {
1354 try {
1355 return mPM.getIntentVerificationStatus(packageName, userId);
1356 } catch (RemoteException e) {
1357 // Should never happen!
1358 return PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1359 }
1360 }
1361
1362 @Override
1363 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
1364 try {
1365 return mPM.updateIntentVerificationStatus(packageName, status, userId);
1366 } catch (RemoteException e) {
1367 // Should never happen!
1368 return false;
1369 }
1370 }
1371
1372 @Override
1373 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
1374 try {
1375 return mPM.getIntentFilterVerifications(packageName);
1376 } catch (RemoteException e) {
1377 // Should never happen!
1378 return null;
1379 }
1380 }
1381
1382 @Override
Fabrice Di Meglio07885952015-04-06 19:41:28 -07001383 public List<IntentFilter> getAllIntentFilters(String packageName) {
1384 try {
1385 return mPM.getAllIntentFilters(packageName);
1386 } catch (RemoteException e) {
1387 // Should never happen!
1388 return null;
1389 }
1390 }
1391
1392 @Override
Fabrice Di Meglio62271722015-04-10 17:24:02 -07001393 public String getDefaultBrowserPackageName(int userId) {
1394 try {
1395 return mPM.getDefaultBrowserPackageName(userId);
1396 } catch (RemoteException e) {
1397 // Should never happen!
1398 return null;
1399 }
1400 }
1401
1402 @Override
1403 public boolean setDefaultBrowserPackageName(String packageName, int userId) {
1404 try {
1405 return mPM.setDefaultBrowserPackageName(packageName, userId);
1406 } catch (RemoteException e) {
1407 // Should never happen!
1408 return false;
1409 }
1410 }
1411
1412 @Override
Dianne Hackborn880119b2010-11-18 22:26:40 -08001413 public void setInstallerPackageName(String targetPackage,
1414 String installerPackageName) {
1415 try {
1416 mPM.setInstallerPackageName(targetPackage, installerPackageName);
1417 } catch (RemoteException e) {
1418 // Should never happen!
1419 }
1420 }
1421
1422 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001423 public String getInstallerPackageName(String packageName) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001424 try {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001425 return mPM.getInstallerPackageName(packageName);
1426 } catch (RemoteException e) {
1427 // Should never happen!
1428 }
1429 return null;
1430 }
1431
1432 @Override
1433 public int getMoveStatus(int moveId) {
1434 try {
1435 return mPM.getMoveStatus(moveId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001436 } catch (RemoteException e) {
Jeff Sharkeyb2b9ab82015-04-05 21:10:42 -07001437 throw e.rethrowAsRuntimeException();
1438 }
1439 }
1440
1441 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001442 public void registerMoveCallback(MoveCallback callback, Handler handler) {
1443 synchronized (mDelegates) {
1444 final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback,
1445 handler.getLooper());
1446 try {
1447 mPM.registerMoveCallback(delegate);
1448 } catch (RemoteException e) {
1449 throw e.rethrowAsRuntimeException();
1450 }
1451 mDelegates.add(delegate);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001452 }
1453 }
1454
1455 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001456 public void unregisterMoveCallback(MoveCallback callback) {
1457 synchronized (mDelegates) {
1458 for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
1459 final MoveCallbackDelegate delegate = i.next();
1460 if (delegate.mCallback == callback) {
1461 try {
1462 mPM.unregisterMoveCallback(delegate);
1463 } catch (RemoteException e) {
1464 throw e.rethrowAsRuntimeException();
1465 }
1466 i.remove();
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001467 }
1468 }
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001469 }
1470 }
1471
1472 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001473 public int movePackage(String packageName, VolumeInfo vol) {
1474 try {
1475 final String volumeUuid;
1476 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1477 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1478 } else if (vol.isPrimaryPhysical()) {
1479 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1480 } else {
1481 volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1482 }
1483
1484 return mPM.movePackage(packageName, volumeUuid);
1485 } catch (RemoteException e) {
1486 throw e.rethrowAsRuntimeException();
1487 }
1488 }
1489
1490 @Override
1491 public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001492 final StorageManager storage = mContext.getSystemService(StorageManager.class);
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001493 if (app.isInternal()) {
1494 return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
1495 } else if (app.isExternalAsec()) {
1496 return storage.getPrimaryPhysicalVolume();
1497 } else {
1498 return storage.findVolumeByUuid(app.volumeUuid);
1499 }
1500 }
1501
1502 @Override
1503 public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
1504 final StorageManager storage = mContext.getSystemService(StorageManager.class);
1505 final VolumeInfo currentVol = getPackageCurrentVolume(app);
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001506 final List<VolumeInfo> vols = storage.getVolumes();
1507 final List<VolumeInfo> candidates = new ArrayList<>();
1508 for (VolumeInfo vol : vols) {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001509 if (Objects.equals(vol, currentVol) || isPackageCandidateVolume(app, vol)) {
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001510 candidates.add(vol);
1511 }
1512 }
1513 return candidates;
1514 }
1515
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001516 private static boolean isPackageCandidateVolume(ApplicationInfo app, VolumeInfo vol) {
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001517 // Private internal is always an option
1518 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1519 return true;
1520 }
1521
1522 // System apps and apps demanding internal storage can't be moved
1523 // anywhere else
1524 if (app.isSystemApp()
1525 || app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
1526 return false;
1527 }
1528
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001529 // Gotta be able to write there
1530 if (!vol.isMountedWritable()) {
1531 return false;
1532 }
1533
1534 // Moving into an ASEC on public primary is only option internal
1535 if (vol.isPrimaryPhysical()) {
1536 return app.isInternal();
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001537 }
1538
1539 // Otherwise we can move to any private volume
1540 return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
1541 }
1542
1543 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001544 public int movePrimaryStorage(VolumeInfo vol) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001545 try {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001546 final String volumeUuid;
1547 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1548 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1549 } else if (vol.isPrimaryPhysical()) {
1550 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1551 } else {
1552 volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1553 }
1554
1555 return mPM.movePrimaryStorage(volumeUuid);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001556 } catch (RemoteException e) {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001557 throw e.rethrowAsRuntimeException();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001558 }
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001559 }
1560
Jeff Sharkey275e3e42015-04-24 16:10:32 -07001561 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001562 public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
1563 final StorageManager storage = mContext.getSystemService(StorageManager.class);
1564 final String volumeUuid = storage.getPrimaryStorageUuid();
Jeff Sharkey50a05452015-04-29 11:24:52 -07001565 return storage.findVolumeByQualifiedUuid(volumeUuid);
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001566 }
1567
Jeff Sharkey275e3e42015-04-24 16:10:32 -07001568 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001569 public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
1570 final StorageManager storage = mContext.getSystemService(StorageManager.class);
1571 final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
1572 final List<VolumeInfo> vols = storage.getVolumes();
1573 final List<VolumeInfo> candidates = new ArrayList<>();
1574 for (VolumeInfo vol : vols) {
1575 if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
1576 candidates.add(vol);
1577 }
1578 }
1579 return candidates;
1580 }
1581
1582 private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) {
1583 // Private internal is always an option
1584 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1585 return true;
1586 }
1587
1588 // Gotta be able to write there
1589 if (!vol.isMountedWritable()) {
1590 return false;
1591 }
1592
1593 // We can move to public volumes on legacy devices
1594 if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.getDisk().isDefaultPrimary()) {
1595 return true;
1596 }
1597
1598 // Otherwise we can move to any private volume
1599 return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001600 }
1601
1602 @Override
1603 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1604 try {
Amith Yamasani67df64b2012-12-14 12:09:36 -08001605 mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001606 } catch (RemoteException e) {
1607 // Should never happen!
1608 }
1609 }
Jeff Sharkeyfbd0e9f2014-08-06 16:34:34 -07001610
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001611 @Override
1612 public void clearApplicationUserData(String packageName,
1613 IPackageDataObserver observer) {
1614 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001615 mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001616 } catch (RemoteException e) {
1617 // Should never happen!
1618 }
1619 }
1620 @Override
1621 public void deleteApplicationCacheFiles(String packageName,
1622 IPackageDataObserver observer) {
1623 try {
1624 mPM.deleteApplicationCacheFiles(packageName, observer);
1625 } catch (RemoteException e) {
1626 // Should never happen!
1627 }
1628 }
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001629
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001630 @Override
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001631 public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
1632 IPackageDataObserver observer) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001633 try {
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001634 mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001635 } catch (RemoteException e) {
1636 // Should never happen!
1637 }
1638 }
1639
1640 @Override
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001641 public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001642 try {
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001643 mPM.freeStorage(volumeUuid, freeStorageSize, pi);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001644 } catch (RemoteException e) {
1645 // Should never happen!
1646 }
1647 }
1648
1649 @Override
Dianne Hackborn0c380492012-08-20 17:23:30 -07001650 public void getPackageSizeInfo(String packageName, int userHandle,
1651 IPackageStatsObserver observer) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001652 try {
Dianne Hackborn0c380492012-08-20 17:23:30 -07001653 mPM.getPackageSizeInfo(packageName, userHandle, observer);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001654 } catch (RemoteException e) {
1655 // Should never happen!
1656 }
1657 }
1658 @Override
1659 public void addPackageToPreferred(String packageName) {
1660 try {
1661 mPM.addPackageToPreferred(packageName);
1662 } catch (RemoteException e) {
1663 // Should never happen!
1664 }
1665 }
1666
1667 @Override
1668 public void removePackageFromPreferred(String packageName) {
1669 try {
1670 mPM.removePackageFromPreferred(packageName);
1671 } catch (RemoteException e) {
1672 // Should never happen!
1673 }
1674 }
1675
1676 @Override
1677 public List<PackageInfo> getPreferredPackages(int flags) {
1678 try {
1679 return mPM.getPreferredPackages(flags);
1680 } catch (RemoteException e) {
1681 // Should never happen!
1682 }
1683 return new ArrayList<PackageInfo>();
1684 }
1685
1686 @Override
1687 public void addPreferredActivity(IntentFilter filter,
1688 int match, ComponentName[] set, ComponentName activity) {
1689 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001690 mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
Amith Yamasania3f133a2012-08-09 17:11:28 -07001691 } catch (RemoteException e) {
1692 // Should never happen!
1693 }
1694 }
1695
1696 @Override
1697 public void addPreferredActivity(IntentFilter filter, int match,
1698 ComponentName[] set, ComponentName activity, int userId) {
1699 try {
1700 mPM.addPreferredActivity(filter, match, set, activity, userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001701 } catch (RemoteException e) {
1702 // Should never happen!
1703 }
1704 }
1705
1706 @Override
1707 public void replacePreferredActivity(IntentFilter filter,
1708 int match, ComponentName[] set, ComponentName activity) {
1709 try {
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001710 mPM.replacePreferredActivity(filter, match, set, activity, UserHandle.myUserId());
1711 } catch (RemoteException e) {
1712 // Should never happen!
1713 }
1714 }
1715
1716 @Override
1717 public void replacePreferredActivityAsUser(IntentFilter filter,
1718 int match, ComponentName[] set, ComponentName activity,
1719 int userId) {
1720 try {
1721 mPM.replacePreferredActivity(filter, match, set, activity, userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001722 } catch (RemoteException e) {
1723 // Should never happen!
1724 }
1725 }
1726
1727 @Override
1728 public void clearPackagePreferredActivities(String packageName) {
1729 try {
1730 mPM.clearPackagePreferredActivities(packageName);
1731 } catch (RemoteException e) {
1732 // Should never happen!
1733 }
1734 }
1735
1736 @Override
1737 public int getPreferredActivities(List<IntentFilter> outFilters,
1738 List<ComponentName> outActivities, String packageName) {
1739 try {
1740 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1741 } catch (RemoteException e) {
1742 // Should never happen!
1743 }
1744 return 0;
1745 }
1746
1747 @Override
Christopher Tatea2a0850d2013-09-05 16:38:58 -07001748 public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
1749 try {
1750 return mPM.getHomeActivities(outActivities);
1751 } catch (RemoteException e) {
1752 // Should never happen!
1753 }
1754 return null;
1755 }
1756
1757 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001758 public void setComponentEnabledSetting(ComponentName componentName,
1759 int newState, int flags) {
1760 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001761 mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001762 } catch (RemoteException e) {
1763 // Should never happen!
1764 }
1765 }
1766
1767 @Override
1768 public int getComponentEnabledSetting(ComponentName componentName) {
1769 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001770 return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001771 } catch (RemoteException e) {
1772 // Should never happen!
1773 }
1774 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1775 }
1776
1777 @Override
1778 public void setApplicationEnabledSetting(String packageName,
1779 int newState, int flags) {
1780 try {
Dianne Hackborn3fa3c28a2013-03-26 16:15:41 -07001781 mPM.setApplicationEnabledSetting(packageName, newState, flags,
Dianne Hackborn95d78532013-09-11 09:51:14 -07001782 mContext.getUserId(), mContext.getOpPackageName());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001783 } catch (RemoteException e) {
1784 // Should never happen!
1785 }
1786 }
1787
1788 @Override
1789 public int getApplicationEnabledSetting(String packageName) {
1790 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001791 return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001792 } catch (RemoteException e) {
1793 // Should never happen!
1794 }
1795 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1796 }
1797
Amith Yamasani655d0e22013-06-12 14:19:10 -07001798 @Override
Amith Yamasanie5bcff62014-07-19 15:44:09 -07001799 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
Amith Yamasani655d0e22013-06-12 14:19:10 -07001800 UserHandle user) {
1801 try {
Amith Yamasanie5bcff62014-07-19 15:44:09 -07001802 return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
Amith Yamasani655d0e22013-06-12 14:19:10 -07001803 user.getIdentifier());
1804 } catch (RemoteException re) {
1805 // Should never happen!
1806 }
1807 return false;
1808 }
1809
1810 @Override
Amith Yamasanie5bcff62014-07-19 15:44:09 -07001811 public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
Amith Yamasani655d0e22013-06-12 14:19:10 -07001812 try {
Amith Yamasanie5bcff62014-07-19 15:44:09 -07001813 return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
Amith Yamasani655d0e22013-06-12 14:19:10 -07001814 } catch (RemoteException re) {
1815 // Should never happen!
1816 }
1817 return false;
1818 }
1819
dcashmanc6f22492014-08-14 09:54:51 -07001820 /** @hide */
dcashman9d2f4412014-06-09 09:27:54 -07001821 @Override
1822 public KeySet getKeySetByAlias(String packageName, String alias) {
1823 Preconditions.checkNotNull(packageName);
1824 Preconditions.checkNotNull(alias);
dcashmanc6f22492014-08-14 09:54:51 -07001825 KeySet ks;
dcashman9d2f4412014-06-09 09:27:54 -07001826 try {
dcashmanc6f22492014-08-14 09:54:51 -07001827 ks = mPM.getKeySetByAlias(packageName, alias);
dcashman9d2f4412014-06-09 09:27:54 -07001828 } catch (RemoteException e) {
1829 return null;
1830 }
dcashmanc6f22492014-08-14 09:54:51 -07001831 return ks;
dcashman9d2f4412014-06-09 09:27:54 -07001832 }
1833
dcashmanc6f22492014-08-14 09:54:51 -07001834 /** @hide */
dcashman9d2f4412014-06-09 09:27:54 -07001835 @Override
1836 public KeySet getSigningKeySet(String packageName) {
1837 Preconditions.checkNotNull(packageName);
dcashmanc6f22492014-08-14 09:54:51 -07001838 KeySet ks;
dcashman9d2f4412014-06-09 09:27:54 -07001839 try {
dcashmanc6f22492014-08-14 09:54:51 -07001840 ks = mPM.getSigningKeySet(packageName);
dcashman9d2f4412014-06-09 09:27:54 -07001841 } catch (RemoteException e) {
1842 return null;
1843 }
dcashmanc6f22492014-08-14 09:54:51 -07001844 return ks;
dcashman9d2f4412014-06-09 09:27:54 -07001845 }
1846
dcashmanc6f22492014-08-14 09:54:51 -07001847 /** @hide */
dcashman9d2f4412014-06-09 09:27:54 -07001848 @Override
1849 public boolean isSignedBy(String packageName, KeySet ks) {
1850 Preconditions.checkNotNull(packageName);
1851 Preconditions.checkNotNull(ks);
dcashman9d2f4412014-06-09 09:27:54 -07001852 try {
dcashmanc6f22492014-08-14 09:54:51 -07001853 return mPM.isPackageSignedByKeySet(packageName, ks);
dcashman9d2f4412014-06-09 09:27:54 -07001854 } catch (RemoteException e) {
1855 return false;
1856 }
1857 }
1858
dcashmanc6f22492014-08-14 09:54:51 -07001859 /** @hide */
dcashman9d2f4412014-06-09 09:27:54 -07001860 @Override
1861 public boolean isSignedByExactly(String packageName, KeySet ks) {
1862 Preconditions.checkNotNull(packageName);
1863 Preconditions.checkNotNull(ks);
dcashman9d2f4412014-06-09 09:27:54 -07001864 try {
dcashmanc6f22492014-08-14 09:54:51 -07001865 return mPM.isPackageSignedByKeySetExactly(packageName, ks);
dcashman9d2f4412014-06-09 09:27:54 -07001866 } catch (RemoteException e) {
1867 return false;
1868 }
1869 }
1870
Kenny Root0aaa0d92011-09-12 16:42:55 -07001871 /**
1872 * @hide
1873 */
1874 @Override
1875 public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1876 try {
1877 return mPM.getVerifierDeviceIdentity();
1878 } catch (RemoteException e) {
1879 // Should never happen!
1880 }
1881 return null;
1882 }
1883
Jeff Hao9f60c082014-10-28 18:51:07 -07001884 /**
1885 * @hide
1886 */
1887 @Override
1888 public boolean isUpgrade() {
1889 try {
1890 return mPM.isUpgrade();
1891 } catch (RemoteException e) {
1892 return false;
1893 }
1894 }
1895
Jeff Sharkey3a44f3f2014-04-28 17:36:31 -07001896 @Override
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -07001897 public PackageInstaller getPackageInstaller() {
1898 synchronized (mLock) {
1899 if (mInstaller == null) {
1900 try {
Jeff Sharkeya0907432014-08-15 10:23:11 -07001901 mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(),
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -07001902 mContext.getPackageName(), mContext.getUserId());
1903 } catch (RemoteException e) {
1904 throw e.rethrowAsRuntimeException();
1905 }
1906 }
1907 return mInstaller;
Jeff Sharkey3a44f3f2014-04-28 17:36:31 -07001908 }
1909 }
1910
Jeff Sharkey6c833e02014-07-14 22:44:30 -07001911 @Override
1912 public boolean isPackageAvailable(String packageName) {
1913 try {
1914 return mPM.isPackageAvailable(packageName, mContext.getUserId());
1915 } catch (RemoteException e) {
1916 throw e.rethrowAsRuntimeException();
1917 }
1918 }
1919
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001920 /**
1921 * @hide
1922 */
1923 @Override
Nicolas Prevot63798c52014-05-27 13:22:38 +01001924 public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
1925 int flags) {
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001926 try {
Nicolas Prevot3f7777f2014-07-24 15:58:39 +01001927 mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
Nicolas Prevot4b8d5822015-03-05 15:20:49 +00001928 sourceUserId, targetUserId, flags);
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001929 } catch (RemoteException e) {
1930 // Should never happen!
1931 }
1932 }
1933
1934 /**
1935 * @hide
1936 */
1937 @Override
Nicolas Prevot81948992014-05-16 18:25:26 +01001938 public void clearCrossProfileIntentFilters(int sourceUserId) {
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001939 try {
Nicolas Prevot4b8d5822015-03-05 15:20:49 +00001940 mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001941 } catch (RemoteException e) {
1942 // Should never happen!
1943 }
1944 }
1945
Nicolas Prevot88cc3462014-05-14 14:51:48 +01001946 /**
1947 * @hide
1948 */
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +01001949 public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
Benjamin Franzec2d48b2014-10-01 15:38:43 +01001950 Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
1951 if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
1952 return dr;
1953 }
1954 return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
1955 }
1956
1957 /**
1958 * @hide
1959 */
1960 public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +01001961 if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
Alexandra Gherghina64d4dca2014-08-28 18:26:56 +01001962 Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
1963 if (bitmap == null) {
1964 return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false);
1965 }
1966 return new BitmapDrawable(bitmap);
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +01001967 }
Alexandra Gherghinadb811db2014-08-29 13:43:59 +01001968 Drawable dr = null;
1969 if (itemInfo.packageName != null) {
1970 dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
1971 }
Alexandra Gherghinaa71e3902014-07-25 20:03:47 +01001972 if (dr == null) {
Alexandra Gherghinaa7093142014-07-30 13:43:39 +01001973 dr = itemInfo.loadDefaultIcon(this);
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +01001974 }
Benjamin Franzec2d48b2014-10-01 15:38:43 +01001975 return dr;
Svetoslavc7d62f02014-09-04 15:39:54 -07001976 }
1977
1978 private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
1979 Rect badgeLocation, boolean tryBadgeInPlace) {
1980 final int badgedWidth = drawable.getIntrinsicWidth();
1981 final int badgedHeight = drawable.getIntrinsicHeight();
1982 final boolean canBadgeInPlace = tryBadgeInPlace
1983 && (drawable instanceof BitmapDrawable)
1984 && ((BitmapDrawable) drawable).getBitmap().isMutable();
1985
1986 final Bitmap bitmap;
1987 if (canBadgeInPlace) {
1988 bitmap = ((BitmapDrawable) drawable).getBitmap();
1989 } else {
1990 bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
1991 }
1992 Canvas canvas = new Canvas(bitmap);
1993
1994 if (!canBadgeInPlace) {
1995 drawable.setBounds(0, 0, badgedWidth, badgedHeight);
1996 drawable.draw(canvas);
1997 }
1998
1999 if (badgeLocation != null) {
2000 if (badgeLocation.left < 0 || badgeLocation.top < 0
2001 || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
2002 throw new IllegalArgumentException("Badge location " + badgeLocation
2003 + " not in badged drawable bounds "
2004 + new Rect(0, 0, badgedWidth, badgedHeight));
2005 }
2006 badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
2007
2008 canvas.save();
2009 canvas.translate(badgeLocation.left, badgeLocation.top);
2010 badgeDrawable.draw(canvas);
2011 canvas.restore();
2012 } else {
2013 badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
2014 badgeDrawable.draw(canvas);
2015 }
2016
2017 if (!canBadgeInPlace) {
2018 BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
2019
2020 if (drawable instanceof BitmapDrawable) {
2021 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
2022 mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
2023 }
2024
2025 return mergedDrawable;
2026 }
2027
2028 return drawable;
2029 }
2030
2031 private int getBadgeResIdForUser(int userHandle) {
2032 // Return the framework-provided badge.
2033 UserInfo userInfo = getUserIfProfile(userHandle);
2034 if (userInfo != null && userInfo.isManagedProfile()) {
2035 return com.android.internal.R.drawable.ic_corp_icon_badge;
2036 }
2037 return 0;
2038 }
2039
2040 private UserInfo getUserIfProfile(int userHandle) {
Svetoslav7de2abb2014-09-05 11:28:00 -07002041 List<UserInfo> userProfiles = getUserManager().getProfiles(UserHandle.myUserId());
Svetoslavc7d62f02014-09-04 15:39:54 -07002042 for (UserInfo user : userProfiles) {
2043 if (user.id == userHandle) {
2044 return user;
2045 }
2046 }
2047 return null;
Nicolas Prevot88cc3462014-05-14 14:51:48 +01002048 }
2049
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002050 /** {@hide} */
2051 private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
2052 Handler.Callback {
Jeff Sharkey50a05452015-04-29 11:24:52 -07002053 private static final int MSG_CREATED = 1;
2054 private static final int MSG_STATUS_CHANGED = 2;
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002055
2056 final MoveCallback mCallback;
2057 final Handler mHandler;
2058
2059 public MoveCallbackDelegate(MoveCallback callback, Looper looper) {
2060 mCallback = callback;
2061 mHandler = new Handler(looper, this);
2062 }
2063
2064 @Override
2065 public boolean handleMessage(Message msg) {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002066 switch (msg.what) {
Jeff Sharkey50a05452015-04-29 11:24:52 -07002067 case MSG_CREATED: {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -07002068 final SomeArgs args = (SomeArgs) msg.obj;
Jeff Sharkey50a05452015-04-29 11:24:52 -07002069 mCallback.onCreated(args.argi1, (Bundle) args.arg2);
Jeff Sharkeyb36586a2015-04-27 08:42:28 -07002070 args.recycle();
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002071 return true;
Jeff Sharkey50a05452015-04-29 11:24:52 -07002072 }
2073 case MSG_STATUS_CHANGED: {
2074 final SomeArgs args = (SomeArgs) msg.obj;
2075 mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
2076 args.recycle();
2077 return true;
2078 }
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002079 }
2080 return false;
2081 }
2082
2083 @Override
Jeff Sharkey50a05452015-04-29 11:24:52 -07002084 public void onCreated(int moveId, Bundle extras) {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -07002085 final SomeArgs args = SomeArgs.obtain();
2086 args.argi1 = moveId;
Jeff Sharkey50a05452015-04-29 11:24:52 -07002087 args.arg2 = extras;
2088 mHandler.obtainMessage(MSG_CREATED, args).sendToTarget();
2089 }
2090
2091 @Override
2092 public void onStatusChanged(int moveId, int status, long estMillis) {
2093 final SomeArgs args = SomeArgs.obtain();
2094 args.argi1 = moveId;
2095 args.argi2 = status;
2096 args.arg3 = estMillis;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -07002097 mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002098 }
2099 }
2100
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08002101 private final ContextImpl mContext;
2102 private final IPackageManager mPM;
2103
2104 private static final Object sSync = new Object();
Dianne Hackbornadd005c2013-07-17 18:43:12 -07002105 private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
2106 = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
2107 private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
2108 = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08002109}