blob: 6e511f38f7e707a1f45f2df9c5f4db8c409db8b9 [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 Sharkey620b32b2015-04-23 19:36:02 -070065import android.os.Handler;
66import android.os.Looper;
67import android.os.Message;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080068import android.os.Process;
69import android.os.RemoteException;
Jeff Sharkeyb2b9ab82015-04-05 21:10:42 -070070import android.os.SystemProperties;
Amith Yamasani67df64b2012-12-14 12:09:36 -080071import android.os.UserHandle;
Nicolas Prevot88cc3462014-05-14 14:51:48 +010072import android.os.UserManager;
Jeff Sharkeye2d45be2015-04-15 17:14:12 -070073import android.os.storage.StorageManager;
74import android.os.storage.VolumeInfo;
Dianne Hackbornadd005c2013-07-17 18:43:12 -070075import android.util.ArrayMap;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080076import android.util.Log;
Jeff Browna492c3a2012-08-23 19:48:44 -070077import android.view.Display;
Jeff Sharkeyb2b9ab82015-04-05 21:10:42 -070078
79import dalvik.system.VMRuntime;
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -070080
81import com.android.internal.annotations.GuardedBy;
Jeff Sharkeyb36586a2015-04-27 08:42:28 -070082import com.android.internal.os.SomeArgs;
dcashman9d2f4412014-06-09 09:27:54 -070083import com.android.internal.util.Preconditions;
Alexandra Gherghina64d4dca2014-08-28 18:26:56 +010084import com.android.internal.util.UserIcons;
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -070085
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080086import java.lang.ref.WeakReference;
87import java.util.ArrayList;
Jeff Sharkey620b32b2015-04-23 19:36:02 -070088import java.util.Iterator;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080089import java.util.List;
Jeff Sharkey620b32b2015-04-23 19:36:02 -070090import java.util.Objects;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080091
92/*package*/
93final class ApplicationPackageManager extends PackageManager {
94 private static final String TAG = "ApplicationPackageManager";
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080095 private final static boolean DEBUG_ICONS = false;
96
Adam Lesinskid00bb5e2014-10-07 12:14:45 -070097 // Default flags to use with PackageManager when no flags are given.
98 private final static int sDefaultFlags = PackageManager.GET_SHARED_LIBRARY_FILES;
99
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -0700100 private final Object mLock = new Object();
101
102 @GuardedBy("mLock")
103 private UserManager mUserManager;
104 @GuardedBy("mLock")
105 private PackageInstaller mInstaller;
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +0100106
Jeff Sharkey620b32b2015-04-23 19:36:02 -0700107 @GuardedBy("mDelegates")
108 private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();
109
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +0100110 UserManager getUserManager() {
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -0700111 synchronized (mLock) {
112 if (mUserManager == null) {
113 mUserManager = UserManager.get(mContext);
114 }
115 return mUserManager;
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +0100116 }
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +0100117 }
118
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800119 @Override
120 public PackageInfo getPackageInfo(String packageName, int flags)
121 throws NameNotFoundException {
122 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700123 PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800124 if (pi != null) {
125 return pi;
126 }
127 } catch (RemoteException e) {
128 throw new RuntimeException("Package manager has died", e);
129 }
130
131 throw new NameNotFoundException(packageName);
132 }
133
134 @Override
135 public String[] currentToCanonicalPackageNames(String[] names) {
136 try {
137 return mPM.currentToCanonicalPackageNames(names);
138 } catch (RemoteException e) {
139 throw new RuntimeException("Package manager has died", e);
140 }
141 }
142
143 @Override
144 public String[] canonicalToCurrentPackageNames(String[] names) {
145 try {
146 return mPM.canonicalToCurrentPackageNames(names);
147 } catch (RemoteException e) {
148 throw new RuntimeException("Package manager has died", e);
149 }
150 }
151
152 @Override
153 public Intent getLaunchIntentForPackage(String packageName) {
154 // First see if the package has an INFO activity; the existence of
155 // such an activity is implied to be the desired front-door for the
156 // overall package (such as if it has multiple launcher entries).
157 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
158 intentToResolve.addCategory(Intent.CATEGORY_INFO);
159 intentToResolve.setPackage(packageName);
Dianne Hackborn19415762010-12-15 00:20:27 -0800160 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800161
162 // Otherwise, try to find a main launcher activity.
Dianne Hackborn19415762010-12-15 00:20:27 -0800163 if (ris == null || ris.size() <= 0) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800164 // reuse the intent instance
165 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
166 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
167 intentToResolve.setPackage(packageName);
Dianne Hackborn19415762010-12-15 00:20:27 -0800168 ris = queryIntentActivities(intentToResolve, 0);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800169 }
Dianne Hackborn19415762010-12-15 00:20:27 -0800170 if (ris == null || ris.size() <= 0) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800171 return null;
172 }
173 Intent intent = new Intent(intentToResolve);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800174 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn19415762010-12-15 00:20:27 -0800175 intent.setClassName(ris.get(0).activityInfo.packageName,
176 ris.get(0).activityInfo.name);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800177 return intent;
178 }
179
180 @Override
Jose Lima970417c2014-04-10 10:42:19 -0700181 public Intent getLeanbackLaunchIntentForPackage(String packageName) {
182 // Try to find a main leanback_launcher activity.
183 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
184 intentToResolve.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER);
185 intentToResolve.setPackage(packageName);
186 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
187
188 if (ris == null || ris.size() <= 0) {
189 return null;
190 }
191 Intent intent = new Intent(intentToResolve);
192 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
193 intent.setClassName(ris.get(0).activityInfo.packageName,
194 ris.get(0).activityInfo.name);
195 return intent;
196 }
197
198 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800199 public int[] getPackageGids(String packageName)
200 throws NameNotFoundException {
201 try {
Svetoslavc6d1c342015-02-26 14:44:43 -0800202 int[] gids = mPM.getPackageGids(packageName, mContext.getUserId());
203 if (gids != null) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800204 return gids;
205 }
206 } catch (RemoteException e) {
207 throw new RuntimeException("Package manager has died", e);
208 }
209
210 throw new NameNotFoundException(packageName);
211 }
212
213 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800214 public int getPackageUid(String packageName, int userHandle)
215 throws NameNotFoundException {
216 try {
217 int uid = mPM.getPackageUid(packageName, userHandle);
218 if (uid >= 0) {
219 return uid;
220 }
221 } catch (RemoteException e) {
222 throw new RuntimeException("Package manager has died", e);
223 }
224
225 throw new NameNotFoundException(packageName);
226 }
227
228 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800229 public PermissionInfo getPermissionInfo(String name, int flags)
230 throws NameNotFoundException {
231 try {
232 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
233 if (pi != null) {
234 return pi;
235 }
236 } catch (RemoteException e) {
237 throw new RuntimeException("Package manager has died", e);
238 }
239
240 throw new NameNotFoundException(name);
241 }
242
243 @Override
244 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
245 throws NameNotFoundException {
246 try {
247 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
248 if (pi != null) {
249 return pi;
250 }
251 } catch (RemoteException e) {
252 throw new RuntimeException("Package manager has died", e);
253 }
254
255 throw new NameNotFoundException(group);
256 }
257
258 @Override
259 public PermissionGroupInfo getPermissionGroupInfo(String name,
260 int flags) throws NameNotFoundException {
261 try {
262 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
263 if (pgi != null) {
264 return pgi;
265 }
266 } catch (RemoteException e) {
267 throw new RuntimeException("Package manager has died", e);
268 }
269
270 throw new NameNotFoundException(name);
271 }
272
273 @Override
274 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
275 try {
276 return mPM.getAllPermissionGroups(flags);
277 } catch (RemoteException e) {
278 throw new RuntimeException("Package manager has died", e);
279 }
280 }
281
282 @Override
283 public ApplicationInfo getApplicationInfo(String packageName, int flags)
284 throws NameNotFoundException {
285 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700286 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800287 if (ai != null) {
Narayan Kamathcaa71192014-07-16 11:06:43 +0100288 // This is a temporary hack. Callers must use
289 // createPackageContext(packageName).getApplicationInfo() to
290 // get the right paths.
291 maybeAdjustApplicationInfo(ai);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800292 return ai;
293 }
294 } catch (RemoteException e) {
295 throw new RuntimeException("Package manager has died", e);
296 }
297
298 throw new NameNotFoundException(packageName);
299 }
300
Narayan Kamathcaa71192014-07-16 11:06:43 +0100301 private static void maybeAdjustApplicationInfo(ApplicationInfo info) {
302 // If we're dealing with a multi-arch application that has both
303 // 32 and 64 bit shared libraries, we might need to choose the secondary
304 // depending on what the current runtime's instruction set is.
305 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
306 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
jgu214741cd92014-12-17 17:23:29 -0500307
308 // Get the instruction set that the libraries of secondary Abi is supported.
309 // In presence of a native bridge this might be different than the one secondary Abi used.
310 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
311 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
312 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
Narayan Kamathcaa71192014-07-16 11:06:43 +0100313
314 // If the runtimeIsa is the same as the primary isa, then we do nothing.
315 // Everything will be set up correctly because info.nativeLibraryDir will
316 // correspond to the right ISA.
317 if (runtimeIsa.equals(secondaryIsa)) {
318 info.nativeLibraryDir = info.secondaryNativeLibraryDir;
319 }
320 }
321 }
322
323
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800324 @Override
325 public ActivityInfo getActivityInfo(ComponentName className, int flags)
326 throws NameNotFoundException {
327 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700328 ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800329 if (ai != null) {
330 return ai;
331 }
332 } catch (RemoteException e) {
333 throw new RuntimeException("Package manager has died", e);
334 }
335
336 throw new NameNotFoundException(className.toString());
337 }
338
339 @Override
340 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
341 throws NameNotFoundException {
342 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700343 ActivityInfo ai = mPM.getReceiverInfo(className, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800344 if (ai != null) {
345 return ai;
346 }
347 } catch (RemoteException e) {
348 throw new RuntimeException("Package manager has died", e);
349 }
350
351 throw new NameNotFoundException(className.toString());
352 }
353
354 @Override
355 public ServiceInfo getServiceInfo(ComponentName className, int flags)
356 throws NameNotFoundException {
357 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700358 ServiceInfo si = mPM.getServiceInfo(className, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800359 if (si != null) {
360 return si;
361 }
362 } catch (RemoteException e) {
363 throw new RuntimeException("Package manager has died", e);
364 }
365
366 throw new NameNotFoundException(className.toString());
367 }
368
369 @Override
370 public ProviderInfo getProviderInfo(ComponentName className, int flags)
371 throws NameNotFoundException {
372 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700373 ProviderInfo pi = mPM.getProviderInfo(className, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800374 if (pi != null) {
375 return pi;
376 }
377 } catch (RemoteException e) {
378 throw new RuntimeException("Package manager has died", e);
379 }
380
381 throw new NameNotFoundException(className.toString());
382 }
383
384 @Override
385 public String[] getSystemSharedLibraryNames() {
386 try {
387 return mPM.getSystemSharedLibraryNames();
388 } catch (RemoteException e) {
389 throw new RuntimeException("Package manager has died", e);
390 }
391 }
392
393 @Override
394 public FeatureInfo[] getSystemAvailableFeatures() {
395 try {
396 return mPM.getSystemAvailableFeatures();
397 } catch (RemoteException e) {
398 throw new RuntimeException("Package manager has died", e);
399 }
400 }
401
402 @Override
403 public boolean hasSystemFeature(String name) {
404 try {
405 return mPM.hasSystemFeature(name);
406 } catch (RemoteException e) {
407 throw new RuntimeException("Package manager has died", e);
408 }
409 }
410
411 @Override
412 public int checkPermission(String permName, String pkgName) {
413 try {
Svetoslavc6d1c342015-02-26 14:44:43 -0800414 return mPM.checkPermission(permName, pkgName, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800415 } catch (RemoteException e) {
416 throw new RuntimeException("Package manager has died", e);
417 }
418 }
419
420 @Override
421 public boolean addPermission(PermissionInfo info) {
422 try {
423 return mPM.addPermission(info);
424 } catch (RemoteException e) {
425 throw new RuntimeException("Package manager has died", e);
426 }
427 }
428
429 @Override
430 public boolean addPermissionAsync(PermissionInfo info) {
431 try {
432 return mPM.addPermissionAsync(info);
433 } catch (RemoteException e) {
434 throw new RuntimeException("Package manager has died", e);
435 }
436 }
437
438 @Override
439 public void removePermission(String name) {
440 try {
441 mPM.removePermission(name);
442 } catch (RemoteException e) {
443 throw new RuntimeException("Package manager has died", e);
444 }
445 }
446
447 @Override
Svetoslavc6d1c342015-02-26 14:44:43 -0800448 public void grantPermission(String packageName, String permissionName, UserHandle user) {
Dianne Hackborne639da72012-02-21 15:11:13 -0800449 try {
Svetoslavc6d1c342015-02-26 14:44:43 -0800450 mPM.grantPermission(packageName, permissionName, user.getIdentifier());
Dianne Hackborne639da72012-02-21 15:11:13 -0800451 } catch (RemoteException e) {
452 throw new RuntimeException("Package manager has died", e);
453 }
454 }
455
456 @Override
Svetoslavc6d1c342015-02-26 14:44:43 -0800457 public void revokePermission(String packageName, String permissionName, UserHandle user) {
Dianne Hackborne639da72012-02-21 15:11:13 -0800458 try {
Svetoslavc6d1c342015-02-26 14:44:43 -0800459 mPM.revokePermission(packageName, permissionName, user.getIdentifier());
Dianne Hackborne639da72012-02-21 15:11:13 -0800460 } catch (RemoteException e) {
461 throw new RuntimeException("Package manager has died", e);
462 }
463 }
464
465 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800466 public int checkSignatures(String pkg1, String pkg2) {
467 try {
468 return mPM.checkSignatures(pkg1, pkg2);
469 } catch (RemoteException e) {
470 throw new RuntimeException("Package manager has died", e);
471 }
472 }
473
474 @Override
475 public int checkSignatures(int uid1, int uid2) {
476 try {
477 return mPM.checkUidSignatures(uid1, uid2);
478 } catch (RemoteException e) {
479 throw new RuntimeException("Package manager has died", e);
480 }
481 }
482
483 @Override
484 public String[] getPackagesForUid(int uid) {
485 try {
486 return mPM.getPackagesForUid(uid);
487 } catch (RemoteException e) {
488 throw new RuntimeException("Package manager has died", e);
489 }
490 }
491
492 @Override
493 public String getNameForUid(int uid) {
494 try {
495 return mPM.getNameForUid(uid);
496 } catch (RemoteException e) {
497 throw new RuntimeException("Package manager has died", e);
498 }
499 }
500
501 @Override
502 public int getUidForSharedUser(String sharedUserName)
503 throws NameNotFoundException {
504 try {
505 int uid = mPM.getUidForSharedUser(sharedUserName);
506 if(uid != -1) {
507 return uid;
508 }
509 } catch (RemoteException e) {
510 throw new RuntimeException("Package manager has died", e);
511 }
512 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
513 }
514
Kenny Roote6cd0c72011-05-19 12:48:14 -0700515 @SuppressWarnings("unchecked")
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800516 @Override
517 public List<PackageInfo> getInstalledPackages(int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700518 return getInstalledPackages(flags, mContext.getUserId());
Amith Yamasani151ec4c2012-09-07 19:25:16 -0700519 }
520
521 /** @hide */
522 @Override
523 public List<PackageInfo> getInstalledPackages(int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800524 try {
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -0800525 ParceledListSlice<PackageInfo> slice = mPM.getInstalledPackages(flags, userId);
526 return slice.getList();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800527 } catch (RemoteException e) {
528 throw new RuntimeException("Package manager has died", e);
529 }
530 }
531
Kenny Roote6cd0c72011-05-19 12:48:14 -0700532 @SuppressWarnings("unchecked")
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800533 @Override
Dianne Hackborne7991752013-01-16 17:56:46 -0800534 public List<PackageInfo> getPackagesHoldingPermissions(
535 String[] permissions, int flags) {
536 final int userId = mContext.getUserId();
537 try {
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -0800538 ParceledListSlice<PackageInfo> slice = mPM.getPackagesHoldingPermissions(
539 permissions, flags, userId);
540 return slice.getList();
Dianne Hackborne7991752013-01-16 17:56:46 -0800541 } catch (RemoteException e) {
542 throw new RuntimeException("Package manager has died", e);
543 }
544 }
545
546 @SuppressWarnings("unchecked")
547 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800548 public List<ApplicationInfo> getInstalledApplications(int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700549 final int userId = mContext.getUserId();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800550 try {
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -0800551 ParceledListSlice<ApplicationInfo> slice = mPM.getInstalledApplications(flags, userId);
552 return slice.getList();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800553 } catch (RemoteException e) {
554 throw new RuntimeException("Package manager has died", e);
555 }
556 }
557
558 @Override
559 public ResolveInfo resolveActivity(Intent intent, int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700560 return resolveActivityAsUser(intent, flags, mContext.getUserId());
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700561 }
562
563 @Override
564 public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800565 try {
566 return mPM.resolveIntent(
567 intent,
568 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700569 flags,
570 userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800571 } catch (RemoteException e) {
572 throw new RuntimeException("Package manager has died", e);
573 }
574 }
575
576 @Override
577 public List<ResolveInfo> queryIntentActivities(Intent intent,
578 int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700579 return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId());
Amith Yamasani151ec4c2012-09-07 19:25:16 -0700580 }
581
582 /** @hide Same as above but for a specific user */
583 @Override
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700584 public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
Amith Yamasani151ec4c2012-09-07 19:25:16 -0700585 int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800586 try {
587 return mPM.queryIntentActivities(
588 intent,
589 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Amith Yamasani483f3b02012-03-13 16:08:00 -0700590 flags,
Amith Yamasani151ec4c2012-09-07 19:25:16 -0700591 userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800592 } catch (RemoteException e) {
593 throw new RuntimeException("Package manager has died", e);
594 }
595 }
596
597 @Override
598 public List<ResolveInfo> queryIntentActivityOptions(
599 ComponentName caller, Intent[] specifics, Intent intent,
600 int flags) {
601 final ContentResolver resolver = mContext.getContentResolver();
602
603 String[] specificTypes = null;
604 if (specifics != null) {
605 final int N = specifics.length;
606 for (int i=0; i<N; i++) {
607 Intent sp = specifics[i];
608 if (sp != null) {
609 String t = sp.resolveTypeIfNeeded(resolver);
610 if (t != null) {
611 if (specificTypes == null) {
612 specificTypes = new String[N];
613 }
614 specificTypes[i] = t;
615 }
616 }
617 }
618 }
619
620 try {
621 return mPM.queryIntentActivityOptions(caller, specifics,
622 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700623 flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800624 } catch (RemoteException e) {
625 throw new RuntimeException("Package manager has died", e);
626 }
627 }
628
Amith Yamasanif203aee2012-08-29 18:41:53 -0700629 /**
630 * @hide
631 */
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800632 @Override
Amith Yamasanif203aee2012-08-29 18:41:53 -0700633 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800634 try {
635 return mPM.queryIntentReceivers(
636 intent,
637 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Amith Yamasani483f3b02012-03-13 16:08:00 -0700638 flags,
Amith Yamasanif203aee2012-08-29 18:41:53 -0700639 userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800640 } catch (RemoteException e) {
641 throw new RuntimeException("Package manager has died", e);
642 }
643 }
644
645 @Override
Amith Yamasanif203aee2012-08-29 18:41:53 -0700646 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700647 return queryBroadcastReceivers(intent, flags, mContext.getUserId());
Amith Yamasanif203aee2012-08-29 18:41:53 -0700648 }
649
650 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800651 public ResolveInfo resolveService(Intent intent, int flags) {
652 try {
653 return mPM.resolveService(
654 intent,
655 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Amith Yamasani483f3b02012-03-13 16:08:00 -0700656 flags,
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700657 mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800658 } catch (RemoteException e) {
659 throw new RuntimeException("Package manager has died", e);
660 }
661 }
662
663 @Override
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700664 public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800665 try {
666 return mPM.queryIntentServices(
667 intent,
668 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
Amith Yamasani483f3b02012-03-13 16:08:00 -0700669 flags,
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700670 userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800671 } catch (RemoteException e) {
672 throw new RuntimeException("Package manager has died", e);
673 }
674 }
675
676 @Override
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700677 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700678 return queryIntentServicesAsUser(intent, flags, mContext.getUserId());
Svetoslav Ganov58d37b52012-09-18 12:04:19 -0700679 }
680
681 @Override
Jeff Sharkey85f5f812013-10-07 10:16:12 -0700682 public List<ResolveInfo> queryIntentContentProvidersAsUser(
683 Intent intent, int flags, int userId) {
684 try {
685 return mPM.queryIntentContentProviders(intent,
686 intent.resolveTypeIfNeeded(mContext.getContentResolver()), flags, userId);
687 } catch (RemoteException e) {
688 throw new RuntimeException("Package manager has died", e);
689 }
690 }
691
692 @Override
693 public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
694 return queryIntentContentProvidersAsUser(intent, flags, mContext.getUserId());
695 }
696
697 @Override
Alexandra Gherghina0363c3e2014-06-23 13:34:59 +0100698 public ProviderInfo resolveContentProvider(String name, int flags) {
699 return resolveContentProviderAsUser(name, flags, mContext.getUserId());
700 }
701
702 /** @hide **/
703 @Override
704 public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800705 try {
Alexandra Gherghina0363c3e2014-06-23 13:34:59 +0100706 return mPM.resolveContentProvider(name, flags, userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800707 } catch (RemoteException e) {
708 throw new RuntimeException("Package manager has died", e);
709 }
710 }
711
712 @Override
713 public List<ProviderInfo> queryContentProviders(String processName,
714 int uid, int flags) {
715 try {
716 return mPM.queryContentProviders(processName, uid, flags);
717 } catch (RemoteException e) {
718 throw new RuntimeException("Package manager has died", e);
719 }
720 }
721
722 @Override
723 public InstrumentationInfo getInstrumentationInfo(
724 ComponentName className, int flags)
725 throws NameNotFoundException {
726 try {
727 InstrumentationInfo ii = mPM.getInstrumentationInfo(
728 className, flags);
729 if (ii != null) {
730 return ii;
731 }
732 } catch (RemoteException e) {
733 throw new RuntimeException("Package manager has died", e);
734 }
735
736 throw new NameNotFoundException(className.toString());
737 }
738
739 @Override
740 public List<InstrumentationInfo> queryInstrumentation(
741 String targetPackage, int flags) {
742 try {
743 return mPM.queryInstrumentation(targetPackage, flags);
744 } catch (RemoteException e) {
745 throw new RuntimeException("Package manager has died", e);
746 }
747 }
748
Alan Viveretteecd585a2015-04-13 10:32:51 -0700749 @Nullable
750 @Override
751 public Drawable getDrawable(String packageName, @DrawableRes int resId,
752 @Nullable ApplicationInfo appInfo) {
753 final ResourceName name = new ResourceName(packageName, resId);
754 final Drawable cachedIcon = getCachedIcon(name);
755 if (cachedIcon != null) {
756 return cachedIcon;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800757 }
Alan Viveretteecd585a2015-04-13 10:32:51 -0700758
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800759 if (appInfo == null) {
760 try {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700761 appInfo = getApplicationInfo(packageName, sDefaultFlags);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800762 } catch (NameNotFoundException e) {
763 return null;
764 }
765 }
Alan Viveretteecd585a2015-04-13 10:32:51 -0700766
767 if (resId != 0) {
768 try {
769 final Resources r = getResourcesForApplication(appInfo);
770 final Drawable dr = r.getDrawable(resId, null);
771 if (dr != null) {
772 putCachedIcon(name, dr);
773 }
774
775 if (false) {
776 RuntimeException e = new RuntimeException("here");
777 e.fillInStackTrace();
778 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resId)
779 + " from package " + packageName
780 + ": app scale=" + r.getCompatibilityInfo().applicationScale
781 + ", caller scale=" + mContext.getResources()
782 .getCompatibilityInfo().applicationScale,
783 e);
784 }
Ricky Wai3ce46252015-04-15 16:12:22 +0100785 if (DEBUG_ICONS) {
Alan Viveretteecd585a2015-04-13 10:32:51 -0700786 Log.v(TAG, "Getting drawable 0x"
787 + Integer.toHexString(resId) + " from " + r
788 + ": " + dr);
Ricky Wai3ce46252015-04-15 16:12:22 +0100789 }
790 return dr;
Alan Viveretteecd585a2015-04-13 10:32:51 -0700791 } catch (NameNotFoundException e) {
792 Log.w("PackageManager", "Failure retrieving resources for "
793 + appInfo.packageName);
794 } catch (Resources.NotFoundException e) {
795 Log.w("PackageManager", "Failure retrieving resources for "
796 + appInfo.packageName + ": " + e.getMessage());
797 } catch (Exception e) {
798 // If an exception was thrown, fall through to return
799 // default icon.
800 Log.w("PackageManager", "Failure retrieving icon 0x"
801 + Integer.toHexString(resId) + " in package "
802 + packageName, e);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800803 }
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800804 }
Alan Viveretteecd585a2015-04-13 10:32:51 -0700805
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800806 return null;
807 }
808
809 @Override public Drawable getActivityIcon(ComponentName activityName)
810 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700811 return getActivityInfo(activityName, sDefaultFlags).loadIcon(this);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800812 }
813
814 @Override public Drawable getActivityIcon(Intent intent)
815 throws NameNotFoundException {
816 if (intent.getComponent() != null) {
817 return getActivityIcon(intent.getComponent());
818 }
819
820 ResolveInfo info = resolveActivity(
821 intent, PackageManager.MATCH_DEFAULT_ONLY);
822 if (info != null) {
823 return info.activityInfo.loadIcon(this);
824 }
825
Romain Guy39fe17c2011-11-30 10:34:07 -0800826 throw new NameNotFoundException(intent.toUri(0));
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800827 }
828
829 @Override public Drawable getDefaultActivityIcon() {
830 return Resources.getSystem().getDrawable(
831 com.android.internal.R.drawable.sym_def_app_icon);
832 }
833
834 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
835 return info.loadIcon(this);
836 }
837
838 @Override public Drawable getApplicationIcon(String packageName)
839 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700840 return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags));
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800841 }
842
843 @Override
Jose Limaf78e3122014-03-06 12:13:15 -0800844 public Drawable getActivityBanner(ComponentName activityName)
845 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700846 return getActivityInfo(activityName, sDefaultFlags).loadBanner(this);
Jose Limaf78e3122014-03-06 12:13:15 -0800847 }
848
849 @Override
850 public Drawable getActivityBanner(Intent intent)
851 throws NameNotFoundException {
852 if (intent.getComponent() != null) {
853 return getActivityBanner(intent.getComponent());
854 }
855
856 ResolveInfo info = resolveActivity(
857 intent, PackageManager.MATCH_DEFAULT_ONLY);
858 if (info != null) {
859 return info.activityInfo.loadBanner(this);
860 }
861
862 throw new NameNotFoundException(intent.toUri(0));
863 }
864
865 @Override
866 public Drawable getApplicationBanner(ApplicationInfo info) {
867 return info.loadBanner(this);
868 }
869
870 @Override
871 public Drawable getApplicationBanner(String packageName)
872 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700873 return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags));
Jose Limaf78e3122014-03-06 12:13:15 -0800874 }
875
876 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800877 public Drawable getActivityLogo(ComponentName activityName)
878 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700879 return getActivityInfo(activityName, sDefaultFlags).loadLogo(this);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800880 }
881
882 @Override
883 public Drawable getActivityLogo(Intent intent)
884 throws NameNotFoundException {
885 if (intent.getComponent() != null) {
886 return getActivityLogo(intent.getComponent());
887 }
888
889 ResolveInfo info = resolveActivity(
890 intent, PackageManager.MATCH_DEFAULT_ONLY);
891 if (info != null) {
892 return info.activityInfo.loadLogo(this);
893 }
894
895 throw new NameNotFoundException(intent.toUri(0));
896 }
897
898 @Override
899 public Drawable getApplicationLogo(ApplicationInfo info) {
900 return info.loadLogo(this);
901 }
902
903 @Override
904 public Drawable getApplicationLogo(String packageName)
905 throws NameNotFoundException {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700906 return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags));
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800907 }
908
Svetoslavc7d62f02014-09-04 15:39:54 -0700909 @Override
910 public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
911 final int badgeResId = getBadgeResIdForUser(user.getIdentifier());
912 if (badgeResId == 0) {
913 return icon;
914 }
915 Drawable badgeIcon = getDrawable("system", badgeResId, null);
916 return getBadgedDrawable(icon, badgeIcon, null, true);
917 }
918
919 @Override
920 public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
921 Rect badgeLocation, int badgeDensity) {
922 Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity);
923 if (badgeDrawable == null) {
924 return drawable;
925 }
926 return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
927 }
928
929 @Override
930 public Drawable getUserBadgeForDensity(UserHandle user, int density) {
931 UserInfo userInfo = getUserIfProfile(user.getIdentifier());
932 if (userInfo != null && userInfo.isManagedProfile()) {
933 if (density <= 0) {
934 density = mContext.getResources().getDisplayMetrics().densityDpi;
935 }
936 return Resources.getSystem().getDrawableForDensity(
937 com.android.internal.R.drawable.ic_corp_badge, density);
938 }
939 return null;
940 }
941
942 @Override
943 public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
944 UserInfo userInfo = getUserIfProfile(user.getIdentifier());
945 if (userInfo != null && userInfo.isManagedProfile()) {
946 return Resources.getSystem().getString(
947 com.android.internal.R.string.managed_profile_label_badge, label);
948 }
949 return label;
950 }
951
Alan Viveretteecd585a2015-04-13 10:32:51 -0700952 @Override
953 public Resources getResourcesForActivity(ComponentName activityName)
954 throws NameNotFoundException {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800955 return getResourcesForApplication(
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700956 getActivityInfo(activityName, sDefaultFlags).applicationInfo);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800957 }
958
Alan Viveretteecd585a2015-04-13 10:32:51 -0700959 @Override
960 public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
961 throws NameNotFoundException {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800962 if (app.packageName.equals("system")) {
963 return mContext.mMainThread.getSystemContext().getResources();
964 }
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700965 final boolean sameUid = (app.uid == Process.myUid());
Alan Viveretteecd585a2015-04-13 10:32:51 -0700966 final Resources r = mContext.mMainThread.getTopLevelResources(
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700967 sameUid ? app.sourceDir : app.publicSourceDir,
968 sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700969 app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
970 null, mContext.mPackageInfo);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800971 if (r != null) {
972 return r;
973 }
974 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
975 }
976
Alan Viveretteecd585a2015-04-13 10:32:51 -0700977 @Override
978 public Resources getResourcesForApplication(String appPackageName)
979 throws NameNotFoundException {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800980 return getResourcesForApplication(
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700981 getApplicationInfo(appPackageName, sDefaultFlags));
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800982 }
983
Amith Yamasani98edc952012-09-25 14:09:27 -0700984 /** @hide */
985 @Override
986 public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
987 throws NameNotFoundException {
Jeff Sharkeyded653b2012-09-27 19:09:24 -0700988 if (userId < 0) {
989 throw new IllegalArgumentException(
990 "Call does not support special user #" + userId);
991 }
992 if ("system".equals(appPackageName)) {
993 return mContext.mMainThread.getSystemContext().getResources();
994 }
Amith Yamasani98edc952012-09-25 14:09:27 -0700995 try {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -0700996 ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
Amith Yamasani98edc952012-09-25 14:09:27 -0700997 if (ai != null) {
998 return getResourcesForApplication(ai);
999 }
1000 } catch (RemoteException e) {
1001 throw new RuntimeException("Package manager has died", e);
1002 }
1003 throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
1004 }
1005
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001006 int mCachedSafeMode = -1;
1007 @Override public boolean isSafeMode() {
1008 try {
1009 if (mCachedSafeMode < 0) {
1010 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
1011 }
1012 return mCachedSafeMode != 0;
1013 } catch (RemoteException e) {
1014 throw new RuntimeException("Package manager has died", e);
1015 }
1016 }
1017
1018 static void configurationChanged() {
1019 synchronized (sSync) {
1020 sIconCache.clear();
1021 sStringCache.clear();
1022 }
1023 }
1024
1025 ApplicationPackageManager(ContextImpl context,
1026 IPackageManager pm) {
1027 mContext = context;
1028 mPM = pm;
1029 }
1030
Alan Viveretteecd585a2015-04-13 10:32:51 -07001031 @Nullable
1032 private Drawable getCachedIcon(@NonNull ResourceName name) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001033 synchronized (sSync) {
Alan Viveretteecd585a2015-04-13 10:32:51 -07001034 final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001035 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
1036 + name + ": " + wr);
1037 if (wr != null) { // we have the activity
Alan Viveretteecd585a2015-04-13 10:32:51 -07001038 final Drawable.ConstantState state = wr.get();
Romain Guy39fe17c2011-11-30 10:34:07 -08001039 if (state != null) {
1040 if (DEBUG_ICONS) {
1041 Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
1042 }
1043 // Note: It's okay here to not use the newDrawable(Resources) variant
1044 // of the API. The ConstantState comes from a drawable that was
1045 // originally created by passing the proper app Resources instance
1046 // which means the state should already contain the proper
1047 // resources specific information (like density.) See
1048 // BitmapDrawable.BitmapState for instance.
1049 return state.newDrawable();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001050 }
1051 // our entry has been purged
1052 sIconCache.remove(name);
1053 }
1054 }
1055 return null;
1056 }
1057
Alan Viveretteecd585a2015-04-13 10:32:51 -07001058 private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001059 synchronized (sSync) {
Alan Viveretteecd585a2015-04-13 10:32:51 -07001060 sIconCache.put(name, new WeakReference<>(dr.getConstantState()));
Romain Guy39fe17c2011-11-30 10:34:07 -08001061 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001062 }
1063 }
1064
Romain Guy39fe17c2011-11-30 10:34:07 -08001065 static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001066 boolean immediateGc = false;
1067 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
1068 immediateGc = true;
1069 }
1070 if (pkgList != null && (pkgList.length > 0)) {
1071 boolean needCleanup = false;
1072 for (String ssp : pkgList) {
1073 synchronized (sSync) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001074 for (int i=sIconCache.size()-1; i>=0; i--) {
1075 ResourceName nm = sIconCache.keyAt(i);
1076 if (nm.packageName.equals(ssp)) {
1077 //Log.i(TAG, "Removing cached drawable for " + nm);
1078 sIconCache.removeAt(i);
1079 needCleanup = true;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001080 }
1081 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001082 for (int i=sStringCache.size()-1; i>=0; i--) {
1083 ResourceName nm = sStringCache.keyAt(i);
1084 if (nm.packageName.equals(ssp)) {
1085 //Log.i(TAG, "Removing cached string for " + nm);
1086 sStringCache.removeAt(i);
1087 needCleanup = true;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001088 }
1089 }
1090 }
1091 }
1092 if (needCleanup || hasPkgInfo) {
1093 if (immediateGc) {
1094 // Schedule an immediate gc.
1095 Runtime.getRuntime().gc();
1096 } else {
1097 ActivityThread.currentActivityThread().scheduleGcIdler();
1098 }
1099 }
1100 }
1101 }
1102
1103 private static final class ResourceName {
1104 final String packageName;
1105 final int iconId;
1106
1107 ResourceName(String _packageName, int _iconId) {
1108 packageName = _packageName;
1109 iconId = _iconId;
1110 }
1111
1112 ResourceName(ApplicationInfo aInfo, int _iconId) {
1113 this(aInfo.packageName, _iconId);
1114 }
1115
1116 ResourceName(ComponentInfo cInfo, int _iconId) {
1117 this(cInfo.applicationInfo.packageName, _iconId);
1118 }
1119
1120 ResourceName(ResolveInfo rInfo, int _iconId) {
1121 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
1122 }
1123
1124 @Override
1125 public boolean equals(Object o) {
1126 if (this == o) return true;
1127 if (o == null || getClass() != o.getClass()) return false;
1128
1129 ResourceName that = (ResourceName) o;
1130
1131 if (iconId != that.iconId) return false;
1132 return !(packageName != null ?
1133 !packageName.equals(that.packageName) : that.packageName != null);
1134
1135 }
1136
1137 @Override
1138 public int hashCode() {
1139 int result;
1140 result = packageName.hashCode();
1141 result = 31 * result + iconId;
1142 return result;
1143 }
1144
1145 @Override
1146 public String toString() {
1147 return "{ResourceName " + packageName + " / " + iconId + "}";
1148 }
1149 }
1150
1151 private CharSequence getCachedString(ResourceName name) {
1152 synchronized (sSync) {
1153 WeakReference<CharSequence> wr = sStringCache.get(name);
1154 if (wr != null) { // we have the activity
1155 CharSequence cs = wr.get();
1156 if (cs != null) {
1157 return cs;
1158 }
1159 // our entry has been purged
1160 sStringCache.remove(name);
1161 }
1162 }
1163 return null;
1164 }
1165
1166 private void putCachedString(ResourceName name, CharSequence cs) {
1167 synchronized (sSync) {
1168 sStringCache.put(name, new WeakReference<CharSequence>(cs));
1169 }
1170 }
1171
1172 @Override
Tor Norbye7b9c9122013-05-30 16:48:33 -07001173 public CharSequence getText(String packageName, @StringRes int resid,
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001174 ApplicationInfo appInfo) {
1175 ResourceName name = new ResourceName(packageName, resid);
1176 CharSequence text = getCachedString(name);
1177 if (text != null) {
1178 return text;
1179 }
1180 if (appInfo == null) {
1181 try {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -07001182 appInfo = getApplicationInfo(packageName, sDefaultFlags);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001183 } catch (NameNotFoundException e) {
1184 return null;
1185 }
1186 }
1187 try {
1188 Resources r = getResourcesForApplication(appInfo);
1189 text = r.getText(resid);
1190 putCachedString(name, text);
1191 return text;
1192 } catch (NameNotFoundException e) {
Dianne Hackbornaec68bb2014-08-20 15:25:13 -07001193 Log.w("PackageManager", "Failure retrieving resources for "
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001194 + appInfo.packageName);
1195 } catch (RuntimeException e) {
1196 // If an exception was thrown, fall through to return
1197 // default icon.
1198 Log.w("PackageManager", "Failure retrieving text 0x"
1199 + Integer.toHexString(resid) + " in package "
1200 + packageName, e);
1201 }
1202 return null;
1203 }
1204
1205 @Override
Tor Norbye7b9c9122013-05-30 16:48:33 -07001206 public XmlResourceParser getXml(String packageName, @XmlRes int resid,
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001207 ApplicationInfo appInfo) {
1208 if (appInfo == null) {
1209 try {
Adam Lesinskid00bb5e2014-10-07 12:14:45 -07001210 appInfo = getApplicationInfo(packageName, sDefaultFlags);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001211 } catch (NameNotFoundException e) {
1212 return null;
1213 }
1214 }
1215 try {
1216 Resources r = getResourcesForApplication(appInfo);
1217 return r.getXml(resid);
1218 } catch (RuntimeException e) {
1219 // If an exception was thrown, fall through to return
1220 // default icon.
1221 Log.w("PackageManager", "Failure retrieving xml 0x"
1222 + Integer.toHexString(resid) + " in package "
1223 + packageName, e);
1224 } catch (NameNotFoundException e) {
Alon Albert3fa51e32010-11-11 09:24:04 -08001225 Log.w("PackageManager", "Failure retrieving resources for "
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001226 + appInfo.packageName);
1227 }
1228 return null;
1229 }
1230
1231 @Override
1232 public CharSequence getApplicationLabel(ApplicationInfo info) {
1233 return info.loadLabel(this);
1234 }
1235
1236 @Override
1237 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1238 String installerPackageName) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001239 final VerificationParams verificationParams = new VerificationParams(null, null,
1240 null, VerificationParams.NO_UID, null);
1241 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1242 installerPackageName, verificationParams, null);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001243 }
1244
1245 @Override
Kenny Root5ab21572011-07-27 11:11:19 -07001246 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
1247 int flags, String installerPackageName, Uri verificationURI,
Rich Canningse1d7c712012-08-08 12:46:06 -07001248 ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001249 final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
1250 null, VerificationParams.NO_UID, manifestDigest);
1251 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1252 installerPackageName, verificationParams, encryptionParams);
Kenny Root5ab21572011-07-27 11:11:19 -07001253 }
1254
1255 @Override
John Spurlock8a985d22014-02-25 09:40:05 -05001256 public void installPackageWithVerificationAndEncryption(Uri packageURI,
rich cannings706e8ba2012-08-20 13:20:14 -07001257 IPackageInstallObserver observer, int flags, String installerPackageName,
1258 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001259 installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1260 installerPackageName, verificationParams, encryptionParams);
Christopher Tatef1977b42014-03-24 16:25:51 -07001261 }
1262
Christopher Tatef1977b42014-03-24 16:25:51 -07001263 @Override
1264 public void installPackage(Uri packageURI, PackageInstallObserver observer,
1265 int flags, String installerPackageName) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001266 final VerificationParams verificationParams = new VerificationParams(null, null,
1267 null, VerificationParams.NO_UID, null);
1268 installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null);
Christopher Tatef1977b42014-03-24 16:25:51 -07001269 }
1270
1271 @Override
1272 public void installPackageWithVerification(Uri packageURI,
1273 PackageInstallObserver observer, int flags, String installerPackageName,
1274 Uri verificationURI, ManifestDigest manifestDigest,
1275 ContainerEncryptionParams encryptionParams) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001276 final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
1277 null, VerificationParams.NO_UID, manifestDigest);
1278 installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
1279 encryptionParams);
Christopher Tatef1977b42014-03-24 16:25:51 -07001280 }
1281
1282 @Override
1283 public void installPackageWithVerificationAndEncryption(Uri packageURI,
1284 PackageInstallObserver observer, int flags, String installerPackageName,
1285 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001286 installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
1287 encryptionParams);
1288 }
1289
1290 private void installCommon(Uri packageURI,
1291 PackageInstallObserver observer, int flags, String installerPackageName,
1292 VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1293 if (!"file".equals(packageURI.getScheme())) {
1294 throw new UnsupportedOperationException("Only file:// URIs are supported");
1295 }
1296 if (encryptionParams != null) {
1297 throw new UnsupportedOperationException("ContainerEncryptionParams not supported");
1298 }
1299
1300 final String originPath = packageURI.getPath();
Christopher Tatef1977b42014-03-24 16:25:51 -07001301 try {
Jeff Sharkey513a0742014-07-08 17:10:32 -07001302 mPM.installPackage(originPath, observer.getBinder(), flags, installerPackageName,
1303 verificationParams, null);
1304 } catch (RemoteException ignored) {
rich cannings706e8ba2012-08-20 13:20:14 -07001305 }
1306 }
1307
1308 @Override
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001309 public int installExistingPackage(String packageName)
1310 throws NameNotFoundException {
1311 try {
Amith Yamasani67df64b2012-12-14 12:09:36 -08001312 int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001313 if (res == INSTALL_FAILED_INVALID_URI) {
1314 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1315 }
1316 return res;
1317 } catch (RemoteException e) {
1318 // Should never happen!
1319 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1320 }
1321 }
1322
1323 @Override
Kenny Root3a9b5fb2011-09-20 14:15:38 -07001324 public void verifyPendingInstall(int id, int response) {
Kenny Root5ab21572011-07-27 11:11:19 -07001325 try {
Kenny Root3a9b5fb2011-09-20 14:15:38 -07001326 mPM.verifyPendingInstall(id, response);
Kenny Root5ab21572011-07-27 11:11:19 -07001327 } catch (RemoteException e) {
1328 // Should never happen!
1329 }
1330 }
1331
1332 @Override
rich canningsd9ef3e52012-08-22 14:28:05 -07001333 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1334 long millisecondsToDelay) {
1335 try {
1336 mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1337 } catch (RemoteException e) {
1338 // Should never happen!
1339 }
1340 }
1341
1342 @Override
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -08001343 public void verifyIntentFilter(int id, int verificationCode, List<String> outFailedDomains) {
1344 try {
1345 mPM.verifyIntentFilter(id, verificationCode, outFailedDomains);
1346 } catch (RemoteException e) {
1347 // Should never happen!
1348 }
1349 }
1350
1351 @Override
1352 public int getIntentVerificationStatus(String packageName, int userId) {
1353 try {
1354 return mPM.getIntentVerificationStatus(packageName, userId);
1355 } catch (RemoteException e) {
1356 // Should never happen!
1357 return PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1358 }
1359 }
1360
1361 @Override
1362 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
1363 try {
1364 return mPM.updateIntentVerificationStatus(packageName, status, userId);
1365 } catch (RemoteException e) {
1366 // Should never happen!
1367 return false;
1368 }
1369 }
1370
1371 @Override
1372 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
1373 try {
1374 return mPM.getIntentFilterVerifications(packageName);
1375 } catch (RemoteException e) {
1376 // Should never happen!
1377 return null;
1378 }
1379 }
1380
1381 @Override
Fabrice Di Meglio07885952015-04-06 19:41:28 -07001382 public List<IntentFilter> getAllIntentFilters(String packageName) {
1383 try {
1384 return mPM.getAllIntentFilters(packageName);
1385 } catch (RemoteException e) {
1386 // Should never happen!
1387 return null;
1388 }
1389 }
1390
1391 @Override
Fabrice Di Meglio62271722015-04-10 17:24:02 -07001392 public String getDefaultBrowserPackageName(int userId) {
1393 try {
1394 return mPM.getDefaultBrowserPackageName(userId);
1395 } catch (RemoteException e) {
1396 // Should never happen!
1397 return null;
1398 }
1399 }
1400
1401 @Override
1402 public boolean setDefaultBrowserPackageName(String packageName, int userId) {
1403 try {
1404 return mPM.setDefaultBrowserPackageName(packageName, userId);
1405 } catch (RemoteException e) {
1406 // Should never happen!
1407 return false;
1408 }
1409 }
1410
1411 @Override
Dianne Hackborn880119b2010-11-18 22:26:40 -08001412 public void setInstallerPackageName(String targetPackage,
1413 String installerPackageName) {
1414 try {
1415 mPM.setInstallerPackageName(targetPackage, installerPackageName);
1416 } catch (RemoteException e) {
1417 // Should never happen!
1418 }
1419 }
1420
1421 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001422 public String getInstallerPackageName(String packageName) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001423 try {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001424 return mPM.getInstallerPackageName(packageName);
1425 } catch (RemoteException e) {
1426 // Should never happen!
1427 }
1428 return null;
1429 }
1430
1431 @Override
1432 public int getMoveStatus(int moveId) {
1433 try {
1434 return mPM.getMoveStatus(moveId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001435 } catch (RemoteException e) {
Jeff Sharkeyb2b9ab82015-04-05 21:10:42 -07001436 throw e.rethrowAsRuntimeException();
1437 }
1438 }
1439
1440 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001441 public void registerMoveCallback(MoveCallback callback, Handler handler) {
1442 synchronized (mDelegates) {
1443 final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback,
1444 handler.getLooper());
1445 try {
1446 mPM.registerMoveCallback(delegate);
1447 } catch (RemoteException e) {
1448 throw e.rethrowAsRuntimeException();
1449 }
1450 mDelegates.add(delegate);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001451 }
1452 }
1453
1454 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001455 public void unregisterMoveCallback(MoveCallback callback) {
1456 synchronized (mDelegates) {
1457 for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
1458 final MoveCallbackDelegate delegate = i.next();
1459 if (delegate.mCallback == callback) {
1460 try {
1461 mPM.unregisterMoveCallback(delegate);
1462 } catch (RemoteException e) {
1463 throw e.rethrowAsRuntimeException();
1464 }
1465 i.remove();
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001466 }
1467 }
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001468 }
1469 }
1470
1471 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001472 public int movePackage(String packageName, VolumeInfo vol) {
1473 try {
1474 final String volumeUuid;
1475 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1476 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1477 } else if (vol.isPrimaryPhysical()) {
1478 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1479 } else {
1480 volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1481 }
1482
1483 return mPM.movePackage(packageName, volumeUuid);
1484 } catch (RemoteException e) {
1485 throw e.rethrowAsRuntimeException();
1486 }
1487 }
1488
1489 @Override
1490 public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001491 final StorageManager storage = mContext.getSystemService(StorageManager.class);
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001492 if (app.isInternal()) {
1493 return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
1494 } else if (app.isExternalAsec()) {
1495 return storage.getPrimaryPhysicalVolume();
1496 } else {
1497 return storage.findVolumeByUuid(app.volumeUuid);
1498 }
1499 }
1500
1501 @Override
1502 public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
1503 final StorageManager storage = mContext.getSystemService(StorageManager.class);
1504 final VolumeInfo currentVol = getPackageCurrentVolume(app);
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001505 final List<VolumeInfo> vols = storage.getVolumes();
1506 final List<VolumeInfo> candidates = new ArrayList<>();
1507 for (VolumeInfo vol : vols) {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001508 if (Objects.equals(vol, currentVol) || isPackageCandidateVolume(app, vol)) {
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001509 candidates.add(vol);
1510 }
1511 }
1512 return candidates;
1513 }
1514
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001515 private static boolean isPackageCandidateVolume(ApplicationInfo app, VolumeInfo vol) {
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001516 // Private internal is always an option
1517 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1518 return true;
1519 }
1520
1521 // System apps and apps demanding internal storage can't be moved
1522 // anywhere else
1523 if (app.isSystemApp()
1524 || app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
1525 return false;
1526 }
1527
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001528 // Gotta be able to write there
1529 if (!vol.isMountedWritable()) {
1530 return false;
1531 }
1532
1533 // Moving into an ASEC on public primary is only option internal
1534 if (vol.isPrimaryPhysical()) {
1535 return app.isInternal();
Jeff Sharkeye2d45be2015-04-15 17:14:12 -07001536 }
1537
1538 // Otherwise we can move to any private volume
1539 return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
1540 }
1541
1542 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001543 public int movePrimaryStorage(VolumeInfo vol) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001544 try {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001545 final String volumeUuid;
1546 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
1547 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
1548 } else if (vol.isPrimaryPhysical()) {
1549 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
1550 } else {
1551 volumeUuid = Preconditions.checkNotNull(vol.fsUuid);
1552 }
1553
1554 return mPM.movePrimaryStorage(volumeUuid);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001555 } catch (RemoteException e) {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001556 throw e.rethrowAsRuntimeException();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001557 }
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001558 }
1559
Jeff Sharkey275e3e42015-04-24 16:10:32 -07001560 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001561 public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
1562 final StorageManager storage = mContext.getSystemService(StorageManager.class);
1563 final String volumeUuid = storage.getPrimaryStorageUuid();
1564 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
1565 return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
1566 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
1567 return storage.getPrimaryPhysicalVolume();
1568 } else {
1569 return storage.findVolumeByUuid(volumeUuid);
1570 }
1571 }
1572
Jeff Sharkey275e3e42015-04-24 16:10:32 -07001573 @Override
Jeff Sharkey620b32b2015-04-23 19:36:02 -07001574 public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
1575 final StorageManager storage = mContext.getSystemService(StorageManager.class);
1576 final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
1577 final List<VolumeInfo> vols = storage.getVolumes();
1578 final List<VolumeInfo> candidates = new ArrayList<>();
1579 for (VolumeInfo vol : vols) {
1580 if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
1581 candidates.add(vol);
1582 }
1583 }
1584 return candidates;
1585 }
1586
1587 private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) {
1588 // Private internal is always an option
1589 if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
1590 return true;
1591 }
1592
1593 // Gotta be able to write there
1594 if (!vol.isMountedWritable()) {
1595 return false;
1596 }
1597
1598 // We can move to public volumes on legacy devices
1599 if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.getDisk().isDefaultPrimary()) {
1600 return true;
1601 }
1602
1603 // Otherwise we can move to any private volume
1604 return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001605 }
1606
1607 @Override
1608 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1609 try {
Amith Yamasani67df64b2012-12-14 12:09:36 -08001610 mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001611 } catch (RemoteException e) {
1612 // Should never happen!
1613 }
1614 }
Jeff Sharkeyfbd0e9f2014-08-06 16:34:34 -07001615
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001616 @Override
1617 public void clearApplicationUserData(String packageName,
1618 IPackageDataObserver observer) {
1619 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001620 mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001621 } catch (RemoteException e) {
1622 // Should never happen!
1623 }
1624 }
1625 @Override
1626 public void deleteApplicationCacheFiles(String packageName,
1627 IPackageDataObserver observer) {
1628 try {
1629 mPM.deleteApplicationCacheFiles(packageName, observer);
1630 } catch (RemoteException e) {
1631 // Should never happen!
1632 }
1633 }
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001634
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001635 @Override
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001636 public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
1637 IPackageDataObserver observer) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001638 try {
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001639 mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, observer);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001640 } catch (RemoteException e) {
1641 // Should never happen!
1642 }
1643 }
1644
1645 @Override
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001646 public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001647 try {
Jeff Sharkey529f91f2015-04-18 20:23:13 -07001648 mPM.freeStorage(volumeUuid, freeStorageSize, pi);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001649 } catch (RemoteException e) {
1650 // Should never happen!
1651 }
1652 }
1653
1654 @Override
Dianne Hackborn0c380492012-08-20 17:23:30 -07001655 public void getPackageSizeInfo(String packageName, int userHandle,
1656 IPackageStatsObserver observer) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001657 try {
Dianne Hackborn0c380492012-08-20 17:23:30 -07001658 mPM.getPackageSizeInfo(packageName, userHandle, observer);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001659 } catch (RemoteException e) {
1660 // Should never happen!
1661 }
1662 }
1663 @Override
1664 public void addPackageToPreferred(String packageName) {
1665 try {
1666 mPM.addPackageToPreferred(packageName);
1667 } catch (RemoteException e) {
1668 // Should never happen!
1669 }
1670 }
1671
1672 @Override
1673 public void removePackageFromPreferred(String packageName) {
1674 try {
1675 mPM.removePackageFromPreferred(packageName);
1676 } catch (RemoteException e) {
1677 // Should never happen!
1678 }
1679 }
1680
1681 @Override
1682 public List<PackageInfo> getPreferredPackages(int flags) {
1683 try {
1684 return mPM.getPreferredPackages(flags);
1685 } catch (RemoteException e) {
1686 // Should never happen!
1687 }
1688 return new ArrayList<PackageInfo>();
1689 }
1690
1691 @Override
1692 public void addPreferredActivity(IntentFilter filter,
1693 int match, ComponentName[] set, ComponentName activity) {
1694 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001695 mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
Amith Yamasania3f133a2012-08-09 17:11:28 -07001696 } catch (RemoteException e) {
1697 // Should never happen!
1698 }
1699 }
1700
1701 @Override
1702 public void addPreferredActivity(IntentFilter filter, int match,
1703 ComponentName[] set, ComponentName activity, int userId) {
1704 try {
1705 mPM.addPreferredActivity(filter, match, set, activity, userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001706 } catch (RemoteException e) {
1707 // Should never happen!
1708 }
1709 }
1710
1711 @Override
1712 public void replacePreferredActivity(IntentFilter filter,
1713 int match, ComponentName[] set, ComponentName activity) {
1714 try {
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001715 mPM.replacePreferredActivity(filter, match, set, activity, UserHandle.myUserId());
1716 } catch (RemoteException e) {
1717 // Should never happen!
1718 }
1719 }
1720
1721 @Override
1722 public void replacePreferredActivityAsUser(IntentFilter filter,
1723 int match, ComponentName[] set, ComponentName activity,
1724 int userId) {
1725 try {
1726 mPM.replacePreferredActivity(filter, match, set, activity, userId);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001727 } catch (RemoteException e) {
1728 // Should never happen!
1729 }
1730 }
1731
1732 @Override
1733 public void clearPackagePreferredActivities(String packageName) {
1734 try {
1735 mPM.clearPackagePreferredActivities(packageName);
1736 } catch (RemoteException e) {
1737 // Should never happen!
1738 }
1739 }
1740
1741 @Override
1742 public int getPreferredActivities(List<IntentFilter> outFilters,
1743 List<ComponentName> outActivities, String packageName) {
1744 try {
1745 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1746 } catch (RemoteException e) {
1747 // Should never happen!
1748 }
1749 return 0;
1750 }
1751
1752 @Override
Christopher Tatea2a0850d2013-09-05 16:38:58 -07001753 public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
1754 try {
1755 return mPM.getHomeActivities(outActivities);
1756 } catch (RemoteException e) {
1757 // Should never happen!
1758 }
1759 return null;
1760 }
1761
1762 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001763 public void setComponentEnabledSetting(ComponentName componentName,
1764 int newState, int flags) {
1765 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001766 mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001767 } catch (RemoteException e) {
1768 // Should never happen!
1769 }
1770 }
1771
1772 @Override
1773 public int getComponentEnabledSetting(ComponentName componentName) {
1774 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001775 return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001776 } catch (RemoteException e) {
1777 // Should never happen!
1778 }
1779 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1780 }
1781
1782 @Override
1783 public void setApplicationEnabledSetting(String packageName,
1784 int newState, int flags) {
1785 try {
Dianne Hackborn3fa3c28a2013-03-26 16:15:41 -07001786 mPM.setApplicationEnabledSetting(packageName, newState, flags,
Dianne Hackborn95d78532013-09-11 09:51:14 -07001787 mContext.getUserId(), mContext.getOpPackageName());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001788 } catch (RemoteException e) {
1789 // Should never happen!
1790 }
1791 }
1792
1793 @Override
1794 public int getApplicationEnabledSetting(String packageName) {
1795 try {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001796 return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001797 } catch (RemoteException e) {
1798 // Should never happen!
1799 }
1800 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1801 }
1802
Amith Yamasani655d0e22013-06-12 14:19:10 -07001803 @Override
Amith Yamasanie5bcff62014-07-19 15:44:09 -07001804 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
Amith Yamasani655d0e22013-06-12 14:19:10 -07001805 UserHandle user) {
1806 try {
Amith Yamasanie5bcff62014-07-19 15:44:09 -07001807 return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
Amith Yamasani655d0e22013-06-12 14:19:10 -07001808 user.getIdentifier());
1809 } catch (RemoteException re) {
1810 // Should never happen!
1811 }
1812 return false;
1813 }
1814
1815 @Override
Amith Yamasanie5bcff62014-07-19 15:44:09 -07001816 public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
Amith Yamasani655d0e22013-06-12 14:19:10 -07001817 try {
Amith Yamasanie5bcff62014-07-19 15:44:09 -07001818 return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
Amith Yamasani655d0e22013-06-12 14:19:10 -07001819 } catch (RemoteException re) {
1820 // Should never happen!
1821 }
1822 return false;
1823 }
1824
dcashmanc6f22492014-08-14 09:54:51 -07001825 /** @hide */
dcashman9d2f4412014-06-09 09:27:54 -07001826 @Override
1827 public KeySet getKeySetByAlias(String packageName, String alias) {
1828 Preconditions.checkNotNull(packageName);
1829 Preconditions.checkNotNull(alias);
dcashmanc6f22492014-08-14 09:54:51 -07001830 KeySet ks;
dcashman9d2f4412014-06-09 09:27:54 -07001831 try {
dcashmanc6f22492014-08-14 09:54:51 -07001832 ks = mPM.getKeySetByAlias(packageName, alias);
dcashman9d2f4412014-06-09 09:27:54 -07001833 } catch (RemoteException e) {
1834 return null;
1835 }
dcashmanc6f22492014-08-14 09:54:51 -07001836 return ks;
dcashman9d2f4412014-06-09 09:27:54 -07001837 }
1838
dcashmanc6f22492014-08-14 09:54:51 -07001839 /** @hide */
dcashman9d2f4412014-06-09 09:27:54 -07001840 @Override
1841 public KeySet getSigningKeySet(String packageName) {
1842 Preconditions.checkNotNull(packageName);
dcashmanc6f22492014-08-14 09:54:51 -07001843 KeySet ks;
dcashman9d2f4412014-06-09 09:27:54 -07001844 try {
dcashmanc6f22492014-08-14 09:54:51 -07001845 ks = mPM.getSigningKeySet(packageName);
dcashman9d2f4412014-06-09 09:27:54 -07001846 } catch (RemoteException e) {
1847 return null;
1848 }
dcashmanc6f22492014-08-14 09:54:51 -07001849 return ks;
dcashman9d2f4412014-06-09 09:27:54 -07001850 }
1851
dcashmanc6f22492014-08-14 09:54:51 -07001852 /** @hide */
dcashman9d2f4412014-06-09 09:27:54 -07001853 @Override
1854 public boolean isSignedBy(String packageName, KeySet ks) {
1855 Preconditions.checkNotNull(packageName);
1856 Preconditions.checkNotNull(ks);
dcashman9d2f4412014-06-09 09:27:54 -07001857 try {
dcashmanc6f22492014-08-14 09:54:51 -07001858 return mPM.isPackageSignedByKeySet(packageName, ks);
dcashman9d2f4412014-06-09 09:27:54 -07001859 } catch (RemoteException e) {
1860 return false;
1861 }
1862 }
1863
dcashmanc6f22492014-08-14 09:54:51 -07001864 /** @hide */
dcashman9d2f4412014-06-09 09:27:54 -07001865 @Override
1866 public boolean isSignedByExactly(String packageName, KeySet ks) {
1867 Preconditions.checkNotNull(packageName);
1868 Preconditions.checkNotNull(ks);
dcashman9d2f4412014-06-09 09:27:54 -07001869 try {
dcashmanc6f22492014-08-14 09:54:51 -07001870 return mPM.isPackageSignedByKeySetExactly(packageName, ks);
dcashman9d2f4412014-06-09 09:27:54 -07001871 } catch (RemoteException e) {
1872 return false;
1873 }
1874 }
1875
Kenny Root0aaa0d92011-09-12 16:42:55 -07001876 /**
1877 * @hide
1878 */
1879 @Override
1880 public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1881 try {
1882 return mPM.getVerifierDeviceIdentity();
1883 } catch (RemoteException e) {
1884 // Should never happen!
1885 }
1886 return null;
1887 }
1888
Jeff Hao9f60c082014-10-28 18:51:07 -07001889 /**
1890 * @hide
1891 */
1892 @Override
1893 public boolean isUpgrade() {
1894 try {
1895 return mPM.isUpgrade();
1896 } catch (RemoteException e) {
1897 return false;
1898 }
1899 }
1900
Jeff Sharkey3a44f3f2014-04-28 17:36:31 -07001901 @Override
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -07001902 public PackageInstaller getPackageInstaller() {
1903 synchronized (mLock) {
1904 if (mInstaller == null) {
1905 try {
Jeff Sharkeya0907432014-08-15 10:23:11 -07001906 mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(),
Jeff Sharkey16c8e3f2014-07-24 17:08:17 -07001907 mContext.getPackageName(), mContext.getUserId());
1908 } catch (RemoteException e) {
1909 throw e.rethrowAsRuntimeException();
1910 }
1911 }
1912 return mInstaller;
Jeff Sharkey3a44f3f2014-04-28 17:36:31 -07001913 }
1914 }
1915
Jeff Sharkey6c833e02014-07-14 22:44:30 -07001916 @Override
1917 public boolean isPackageAvailable(String packageName) {
1918 try {
1919 return mPM.isPackageAvailable(packageName, mContext.getUserId());
1920 } catch (RemoteException e) {
1921 throw e.rethrowAsRuntimeException();
1922 }
1923 }
1924
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001925 /**
1926 * @hide
1927 */
1928 @Override
Nicolas Prevot63798c52014-05-27 13:22:38 +01001929 public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
1930 int flags) {
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001931 try {
Nicolas Prevot3f7777f2014-07-24 15:58:39 +01001932 mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
Nicolas Prevot4b8d5822015-03-05 15:20:49 +00001933 sourceUserId, targetUserId, flags);
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001934 } catch (RemoteException e) {
1935 // Should never happen!
1936 }
1937 }
1938
1939 /**
1940 * @hide
1941 */
1942 @Override
Nicolas Prevot81948992014-05-16 18:25:26 +01001943 public void clearCrossProfileIntentFilters(int sourceUserId) {
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001944 try {
Nicolas Prevot4b8d5822015-03-05 15:20:49 +00001945 mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
Nicolas Prevotc79586e2014-05-06 12:47:57 +01001946 } catch (RemoteException e) {
1947 // Should never happen!
1948 }
1949 }
1950
Nicolas Prevot88cc3462014-05-14 14:51:48 +01001951 /**
1952 * @hide
1953 */
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +01001954 public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
Benjamin Franzec2d48b2014-10-01 15:38:43 +01001955 Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
1956 if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
1957 return dr;
1958 }
1959 return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
1960 }
1961
1962 /**
1963 * @hide
1964 */
1965 public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +01001966 if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
Alexandra Gherghina64d4dca2014-08-28 18:26:56 +01001967 Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
1968 if (bitmap == null) {
1969 return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false);
1970 }
1971 return new BitmapDrawable(bitmap);
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +01001972 }
Alexandra Gherghinadb811db2014-08-29 13:43:59 +01001973 Drawable dr = null;
1974 if (itemInfo.packageName != null) {
1975 dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
1976 }
Alexandra Gherghinaa71e3902014-07-25 20:03:47 +01001977 if (dr == null) {
Alexandra Gherghinaa7093142014-07-30 13:43:39 +01001978 dr = itemInfo.loadDefaultIcon(this);
Nicolas Prevot7f7b0c72014-06-23 15:59:38 +01001979 }
Benjamin Franzec2d48b2014-10-01 15:38:43 +01001980 return dr;
Svetoslavc7d62f02014-09-04 15:39:54 -07001981 }
1982
1983 private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
1984 Rect badgeLocation, boolean tryBadgeInPlace) {
1985 final int badgedWidth = drawable.getIntrinsicWidth();
1986 final int badgedHeight = drawable.getIntrinsicHeight();
1987 final boolean canBadgeInPlace = tryBadgeInPlace
1988 && (drawable instanceof BitmapDrawable)
1989 && ((BitmapDrawable) drawable).getBitmap().isMutable();
1990
1991 final Bitmap bitmap;
1992 if (canBadgeInPlace) {
1993 bitmap = ((BitmapDrawable) drawable).getBitmap();
1994 } else {
1995 bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
1996 }
1997 Canvas canvas = new Canvas(bitmap);
1998
1999 if (!canBadgeInPlace) {
2000 drawable.setBounds(0, 0, badgedWidth, badgedHeight);
2001 drawable.draw(canvas);
2002 }
2003
2004 if (badgeLocation != null) {
2005 if (badgeLocation.left < 0 || badgeLocation.top < 0
2006 || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
2007 throw new IllegalArgumentException("Badge location " + badgeLocation
2008 + " not in badged drawable bounds "
2009 + new Rect(0, 0, badgedWidth, badgedHeight));
2010 }
2011 badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
2012
2013 canvas.save();
2014 canvas.translate(badgeLocation.left, badgeLocation.top);
2015 badgeDrawable.draw(canvas);
2016 canvas.restore();
2017 } else {
2018 badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
2019 badgeDrawable.draw(canvas);
2020 }
2021
2022 if (!canBadgeInPlace) {
2023 BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
2024
2025 if (drawable instanceof BitmapDrawable) {
2026 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
2027 mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
2028 }
2029
2030 return mergedDrawable;
2031 }
2032
2033 return drawable;
2034 }
2035
2036 private int getBadgeResIdForUser(int userHandle) {
2037 // Return the framework-provided badge.
2038 UserInfo userInfo = getUserIfProfile(userHandle);
2039 if (userInfo != null && userInfo.isManagedProfile()) {
2040 return com.android.internal.R.drawable.ic_corp_icon_badge;
2041 }
2042 return 0;
2043 }
2044
2045 private UserInfo getUserIfProfile(int userHandle) {
Svetoslav7de2abb2014-09-05 11:28:00 -07002046 List<UserInfo> userProfiles = getUserManager().getProfiles(UserHandle.myUserId());
Svetoslavc7d62f02014-09-04 15:39:54 -07002047 for (UserInfo user : userProfiles) {
2048 if (user.id == userHandle) {
2049 return user;
2050 }
2051 }
2052 return null;
Nicolas Prevot88cc3462014-05-14 14:51:48 +01002053 }
2054
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002055 /** {@hide} */
2056 private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
2057 Handler.Callback {
Jeff Sharkeyb36586a2015-04-27 08:42:28 -07002058 private static final int MSG_STATUS_CHANGED = 1;
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002059
2060 final MoveCallback mCallback;
2061 final Handler mHandler;
2062
2063 public MoveCallbackDelegate(MoveCallback callback, Looper looper) {
2064 mCallback = callback;
2065 mHandler = new Handler(looper, this);
2066 }
2067
2068 @Override
2069 public boolean handleMessage(Message msg) {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002070 switch (msg.what) {
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002071 case MSG_STATUS_CHANGED:
Jeff Sharkeyb36586a2015-04-27 08:42:28 -07002072 final SomeArgs args = (SomeArgs) msg.obj;
2073 mCallback.onStatusChanged(args.argi1, (String) args.arg2, args.argi3,
2074 (long) args.arg4);
2075 args.recycle();
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002076 return true;
2077 }
2078 return false;
2079 }
2080
2081 @Override
Jeff Sharkeyb36586a2015-04-27 08:42:28 -07002082 public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
2083 final SomeArgs args = SomeArgs.obtain();
2084 args.argi1 = moveId;
2085 args.arg2 = moveTitle;
2086 args.argi3 = status;
2087 args.arg4 = estMillis;
2088 mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
Jeff Sharkey620b32b2015-04-23 19:36:02 -07002089 }
2090 }
2091
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08002092 private final ContextImpl mContext;
2093 private final IPackageManager mPM;
2094
2095 private static final Object sSync = new Object();
Dianne Hackbornadd005c2013-07-17 18:43:12 -07002096 private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
2097 = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
2098 private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
2099 = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08002100}