blob: 758ce094cf6c2338e127223346a86fac29410537 [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
19import android.content.ComponentName;
20import android.content.ContentResolver;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.content.IntentSender;
24import android.content.pm.ActivityInfo;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.ComponentInfo;
27import android.content.pm.FeatureInfo;
28import android.content.pm.IPackageDataObserver;
29import android.content.pm.IPackageDeleteObserver;
30import android.content.pm.IPackageInstallObserver;
31import android.content.pm.IPackageManager;
32import android.content.pm.IPackageMoveObserver;
33import android.content.pm.IPackageStatsObserver;
34import android.content.pm.InstrumentationInfo;
35import android.content.pm.PackageInfo;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080036import android.content.pm.PackageManager;
Kenny Roote6cd0c72011-05-19 12:48:14 -070037import android.content.pm.ParceledListSlice;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080038import android.content.pm.PermissionGroupInfo;
39import android.content.pm.PermissionInfo;
40import android.content.pm.ProviderInfo;
41import android.content.pm.ResolveInfo;
42import android.content.pm.ServiceInfo;
Amith Yamasani4b2e9342011-03-31 12:38:53 -070043import android.content.pm.UserInfo;
Kenny Root5ab21572011-07-27 11:11:19 -070044import android.content.pm.ManifestDigest;
Kenny Root0aaa0d92011-09-12 16:42:55 -070045import android.content.pm.VerifierDeviceIdentity;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -080046import android.content.res.Resources;
47import android.content.res.XmlResourceParser;
48import android.graphics.drawable.Drawable;
49import android.net.Uri;
50import android.os.Process;
51import android.os.RemoteException;
52import android.util.Log;
53
54import java.lang.ref.WeakReference;
55import java.util.ArrayList;
56import java.util.HashMap;
57import java.util.Iterator;
58import java.util.List;
59
60/*package*/
61final class ApplicationPackageManager extends PackageManager {
62 private static final String TAG = "ApplicationPackageManager";
63 private final static boolean DEBUG = false;
64 private final static boolean DEBUG_ICONS = false;
65
66 @Override
67 public PackageInfo getPackageInfo(String packageName, int flags)
68 throws NameNotFoundException {
69 try {
70 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
71 if (pi != null) {
72 return pi;
73 }
74 } catch (RemoteException e) {
75 throw new RuntimeException("Package manager has died", e);
76 }
77
78 throw new NameNotFoundException(packageName);
79 }
80
81 @Override
82 public String[] currentToCanonicalPackageNames(String[] names) {
83 try {
84 return mPM.currentToCanonicalPackageNames(names);
85 } catch (RemoteException e) {
86 throw new RuntimeException("Package manager has died", e);
87 }
88 }
89
90 @Override
91 public String[] canonicalToCurrentPackageNames(String[] names) {
92 try {
93 return mPM.canonicalToCurrentPackageNames(names);
94 } catch (RemoteException e) {
95 throw new RuntimeException("Package manager has died", e);
96 }
97 }
98
99 @Override
100 public Intent getLaunchIntentForPackage(String packageName) {
101 // First see if the package has an INFO activity; the existence of
102 // such an activity is implied to be the desired front-door for the
103 // overall package (such as if it has multiple launcher entries).
104 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
105 intentToResolve.addCategory(Intent.CATEGORY_INFO);
106 intentToResolve.setPackage(packageName);
Dianne Hackborn19415762010-12-15 00:20:27 -0800107 List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800108
109 // Otherwise, try to find a main launcher activity.
Dianne Hackborn19415762010-12-15 00:20:27 -0800110 if (ris == null || ris.size() <= 0) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800111 // reuse the intent instance
112 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
113 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
114 intentToResolve.setPackage(packageName);
Dianne Hackborn19415762010-12-15 00:20:27 -0800115 ris = queryIntentActivities(intentToResolve, 0);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800116 }
Dianne Hackborn19415762010-12-15 00:20:27 -0800117 if (ris == null || ris.size() <= 0) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800118 return null;
119 }
120 Intent intent = new Intent(intentToResolve);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800121 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn19415762010-12-15 00:20:27 -0800122 intent.setClassName(ris.get(0).activityInfo.packageName,
123 ris.get(0).activityInfo.name);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800124 return intent;
125 }
126
127 @Override
128 public int[] getPackageGids(String packageName)
129 throws NameNotFoundException {
130 try {
131 int[] gids = mPM.getPackageGids(packageName);
132 if (gids == null || gids.length > 0) {
133 return gids;
134 }
135 } catch (RemoteException e) {
136 throw new RuntimeException("Package manager has died", e);
137 }
138
139 throw new NameNotFoundException(packageName);
140 }
141
142 @Override
143 public PermissionInfo getPermissionInfo(String name, int flags)
144 throws NameNotFoundException {
145 try {
146 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
147 if (pi != null) {
148 return pi;
149 }
150 } catch (RemoteException e) {
151 throw new RuntimeException("Package manager has died", e);
152 }
153
154 throw new NameNotFoundException(name);
155 }
156
157 @Override
158 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
159 throws NameNotFoundException {
160 try {
161 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
162 if (pi != null) {
163 return pi;
164 }
165 } catch (RemoteException e) {
166 throw new RuntimeException("Package manager has died", e);
167 }
168
169 throw new NameNotFoundException(group);
170 }
171
172 @Override
173 public PermissionGroupInfo getPermissionGroupInfo(String name,
174 int flags) throws NameNotFoundException {
175 try {
176 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
177 if (pgi != null) {
178 return pgi;
179 }
180 } catch (RemoteException e) {
181 throw new RuntimeException("Package manager has died", e);
182 }
183
184 throw new NameNotFoundException(name);
185 }
186
187 @Override
188 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
189 try {
190 return mPM.getAllPermissionGroups(flags);
191 } catch (RemoteException e) {
192 throw new RuntimeException("Package manager has died", e);
193 }
194 }
195
196 @Override
197 public ApplicationInfo getApplicationInfo(String packageName, int flags)
198 throws NameNotFoundException {
199 try {
200 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
201 if (ai != null) {
202 return ai;
203 }
204 } catch (RemoteException e) {
205 throw new RuntimeException("Package manager has died", e);
206 }
207
208 throw new NameNotFoundException(packageName);
209 }
210
211 @Override
212 public ActivityInfo getActivityInfo(ComponentName className, int flags)
213 throws NameNotFoundException {
214 try {
215 ActivityInfo ai = mPM.getActivityInfo(className, flags);
216 if (ai != null) {
217 return ai;
218 }
219 } catch (RemoteException e) {
220 throw new RuntimeException("Package manager has died", e);
221 }
222
223 throw new NameNotFoundException(className.toString());
224 }
225
226 @Override
227 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
228 throws NameNotFoundException {
229 try {
230 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
231 if (ai != null) {
232 return ai;
233 }
234 } catch (RemoteException e) {
235 throw new RuntimeException("Package manager has died", e);
236 }
237
238 throw new NameNotFoundException(className.toString());
239 }
240
241 @Override
242 public ServiceInfo getServiceInfo(ComponentName className, int flags)
243 throws NameNotFoundException {
244 try {
245 ServiceInfo si = mPM.getServiceInfo(className, flags);
246 if (si != null) {
247 return si;
248 }
249 } catch (RemoteException e) {
250 throw new RuntimeException("Package manager has died", e);
251 }
252
253 throw new NameNotFoundException(className.toString());
254 }
255
256 @Override
257 public ProviderInfo getProviderInfo(ComponentName className, int flags)
258 throws NameNotFoundException {
259 try {
260 ProviderInfo pi = mPM.getProviderInfo(className, flags);
261 if (pi != null) {
262 return pi;
263 }
264 } catch (RemoteException e) {
265 throw new RuntimeException("Package manager has died", e);
266 }
267
268 throw new NameNotFoundException(className.toString());
269 }
270
271 @Override
272 public String[] getSystemSharedLibraryNames() {
273 try {
274 return mPM.getSystemSharedLibraryNames();
275 } catch (RemoteException e) {
276 throw new RuntimeException("Package manager has died", e);
277 }
278 }
279
280 @Override
281 public FeatureInfo[] getSystemAvailableFeatures() {
282 try {
283 return mPM.getSystemAvailableFeatures();
284 } catch (RemoteException e) {
285 throw new RuntimeException("Package manager has died", e);
286 }
287 }
288
289 @Override
290 public boolean hasSystemFeature(String name) {
291 try {
292 return mPM.hasSystemFeature(name);
293 } catch (RemoteException e) {
294 throw new RuntimeException("Package manager has died", e);
295 }
296 }
297
298 @Override
299 public int checkPermission(String permName, String pkgName) {
300 try {
301 return mPM.checkPermission(permName, pkgName);
302 } catch (RemoteException e) {
303 throw new RuntimeException("Package manager has died", e);
304 }
305 }
306
307 @Override
308 public boolean addPermission(PermissionInfo info) {
309 try {
310 return mPM.addPermission(info);
311 } catch (RemoteException e) {
312 throw new RuntimeException("Package manager has died", e);
313 }
314 }
315
316 @Override
317 public boolean addPermissionAsync(PermissionInfo info) {
318 try {
319 return mPM.addPermissionAsync(info);
320 } catch (RemoteException e) {
321 throw new RuntimeException("Package manager has died", e);
322 }
323 }
324
325 @Override
326 public void removePermission(String name) {
327 try {
328 mPM.removePermission(name);
329 } catch (RemoteException e) {
330 throw new RuntimeException("Package manager has died", e);
331 }
332 }
333
334 @Override
Dianne Hackborne639da72012-02-21 15:11:13 -0800335 public void grantPermission(String packageName, String permissionName) {
336 try {
337 mPM.grantPermission(packageName, permissionName);
338 } catch (RemoteException e) {
339 throw new RuntimeException("Package manager has died", e);
340 }
341 }
342
343 @Override
344 public void revokePermission(String packageName, String permissionName) {
345 try {
346 mPM.revokePermission(packageName, permissionName);
347 } catch (RemoteException e) {
348 throw new RuntimeException("Package manager has died", e);
349 }
350 }
351
352 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800353 public int checkSignatures(String pkg1, String pkg2) {
354 try {
355 return mPM.checkSignatures(pkg1, pkg2);
356 } catch (RemoteException e) {
357 throw new RuntimeException("Package manager has died", e);
358 }
359 }
360
361 @Override
362 public int checkSignatures(int uid1, int uid2) {
363 try {
364 return mPM.checkUidSignatures(uid1, uid2);
365 } catch (RemoteException e) {
366 throw new RuntimeException("Package manager has died", e);
367 }
368 }
369
370 @Override
371 public String[] getPackagesForUid(int uid) {
372 try {
373 return mPM.getPackagesForUid(uid);
374 } catch (RemoteException e) {
375 throw new RuntimeException("Package manager has died", e);
376 }
377 }
378
379 @Override
380 public String getNameForUid(int uid) {
381 try {
382 return mPM.getNameForUid(uid);
383 } catch (RemoteException e) {
384 throw new RuntimeException("Package manager has died", e);
385 }
386 }
387
388 @Override
389 public int getUidForSharedUser(String sharedUserName)
390 throws NameNotFoundException {
391 try {
392 int uid = mPM.getUidForSharedUser(sharedUserName);
393 if(uid != -1) {
394 return uid;
395 }
396 } catch (RemoteException e) {
397 throw new RuntimeException("Package manager has died", e);
398 }
399 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
400 }
401
Kenny Roote6cd0c72011-05-19 12:48:14 -0700402 @SuppressWarnings("unchecked")
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800403 @Override
404 public List<PackageInfo> getInstalledPackages(int flags) {
405 try {
Kenny Roote6cd0c72011-05-19 12:48:14 -0700406 final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
407 PackageInfo lastItem = null;
408 ParceledListSlice<PackageInfo> slice;
409
410 do {
411 final String lastKey = lastItem != null ? lastItem.packageName : null;
412 slice = mPM.getInstalledPackages(flags, lastKey);
413 lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
414 } while (!slice.isLastSlice());
415
416 return packageInfos;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800417 } catch (RemoteException e) {
418 throw new RuntimeException("Package manager has died", e);
419 }
420 }
421
Kenny Roote6cd0c72011-05-19 12:48:14 -0700422 @SuppressWarnings("unchecked")
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800423 @Override
424 public List<ApplicationInfo> getInstalledApplications(int flags) {
425 try {
Kenny Roote6cd0c72011-05-19 12:48:14 -0700426 final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>();
427 ApplicationInfo lastItem = null;
428 ParceledListSlice<ApplicationInfo> slice;
429
430 do {
431 final String lastKey = lastItem != null ? lastItem.packageName : null;
432 slice = mPM.getInstalledApplications(flags, lastKey);
433 lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR);
434 } while (!slice.isLastSlice());
435
436 return applicationInfos;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800437 } catch (RemoteException e) {
438 throw new RuntimeException("Package manager has died", e);
439 }
440 }
441
442 @Override
443 public ResolveInfo resolveActivity(Intent intent, int flags) {
444 try {
445 return mPM.resolveIntent(
446 intent,
447 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
448 flags);
449 } catch (RemoteException e) {
450 throw new RuntimeException("Package manager has died", e);
451 }
452 }
453
454 @Override
455 public List<ResolveInfo> queryIntentActivities(Intent intent,
456 int flags) {
457 try {
458 return mPM.queryIntentActivities(
459 intent,
460 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
461 flags);
462 } catch (RemoteException e) {
463 throw new RuntimeException("Package manager has died", e);
464 }
465 }
466
467 @Override
468 public List<ResolveInfo> queryIntentActivityOptions(
469 ComponentName caller, Intent[] specifics, Intent intent,
470 int flags) {
471 final ContentResolver resolver = mContext.getContentResolver();
472
473 String[] specificTypes = null;
474 if (specifics != null) {
475 final int N = specifics.length;
476 for (int i=0; i<N; i++) {
477 Intent sp = specifics[i];
478 if (sp != null) {
479 String t = sp.resolveTypeIfNeeded(resolver);
480 if (t != null) {
481 if (specificTypes == null) {
482 specificTypes = new String[N];
483 }
484 specificTypes[i] = t;
485 }
486 }
487 }
488 }
489
490 try {
491 return mPM.queryIntentActivityOptions(caller, specifics,
492 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
493 flags);
494 } catch (RemoteException e) {
495 throw new RuntimeException("Package manager has died", e);
496 }
497 }
498
499 @Override
500 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
501 try {
502 return mPM.queryIntentReceivers(
503 intent,
504 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
505 flags);
506 } catch (RemoteException e) {
507 throw new RuntimeException("Package manager has died", e);
508 }
509 }
510
511 @Override
512 public ResolveInfo resolveService(Intent intent, int flags) {
513 try {
514 return mPM.resolveService(
515 intent,
516 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
517 flags);
518 } catch (RemoteException e) {
519 throw new RuntimeException("Package manager has died", e);
520 }
521 }
522
523 @Override
524 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
525 try {
526 return mPM.queryIntentServices(
527 intent,
528 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
529 flags);
530 } catch (RemoteException e) {
531 throw new RuntimeException("Package manager has died", e);
532 }
533 }
534
535 @Override
536 public ProviderInfo resolveContentProvider(String name,
537 int flags) {
538 try {
539 return mPM.resolveContentProvider(name, flags);
540 } catch (RemoteException e) {
541 throw new RuntimeException("Package manager has died", e);
542 }
543 }
544
545 @Override
546 public List<ProviderInfo> queryContentProviders(String processName,
547 int uid, int flags) {
548 try {
549 return mPM.queryContentProviders(processName, uid, flags);
550 } catch (RemoteException e) {
551 throw new RuntimeException("Package manager has died", e);
552 }
553 }
554
555 @Override
556 public InstrumentationInfo getInstrumentationInfo(
557 ComponentName className, int flags)
558 throws NameNotFoundException {
559 try {
560 InstrumentationInfo ii = mPM.getInstrumentationInfo(
561 className, flags);
562 if (ii != null) {
563 return ii;
564 }
565 } catch (RemoteException e) {
566 throw new RuntimeException("Package manager has died", e);
567 }
568
569 throw new NameNotFoundException(className.toString());
570 }
571
572 @Override
573 public List<InstrumentationInfo> queryInstrumentation(
574 String targetPackage, int flags) {
575 try {
576 return mPM.queryInstrumentation(targetPackage, flags);
577 } catch (RemoteException e) {
578 throw new RuntimeException("Package manager has died", e);
579 }
580 }
581
582 @Override public Drawable getDrawable(String packageName, int resid,
583 ApplicationInfo appInfo) {
584 ResourceName name = new ResourceName(packageName, resid);
585 Drawable dr = getCachedIcon(name);
586 if (dr != null) {
587 return dr;
588 }
589 if (appInfo == null) {
590 try {
591 appInfo = getApplicationInfo(packageName, 0);
592 } catch (NameNotFoundException e) {
593 return null;
594 }
595 }
596 try {
597 Resources r = getResourcesForApplication(appInfo);
598 dr = r.getDrawable(resid);
599 if (false) {
600 RuntimeException e = new RuntimeException("here");
601 e.fillInStackTrace();
602 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
603 + " from package " + packageName
604 + ": app scale=" + r.getCompatibilityInfo().applicationScale
605 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
606 e);
607 }
608 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
609 + Integer.toHexString(resid) + " from " + r
610 + ": " + dr);
611 putCachedIcon(name, dr);
612 return dr;
613 } catch (NameNotFoundException e) {
614 Log.w("PackageManager", "Failure retrieving resources for"
615 + appInfo.packageName);
Joe Onorato08f16542011-01-20 11:49:56 -0800616 } catch (Resources.NotFoundException e) {
617 Log.w("PackageManager", "Failure retrieving resources for"
618 + appInfo.packageName + ": " + e.getMessage());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800619 } catch (RuntimeException e) {
620 // If an exception was thrown, fall through to return
621 // default icon.
622 Log.w("PackageManager", "Failure retrieving icon 0x"
623 + Integer.toHexString(resid) + " in package "
624 + packageName, e);
625 }
626 return null;
627 }
628
629 @Override public Drawable getActivityIcon(ComponentName activityName)
630 throws NameNotFoundException {
631 return getActivityInfo(activityName, 0).loadIcon(this);
632 }
633
634 @Override public Drawable getActivityIcon(Intent intent)
635 throws NameNotFoundException {
636 if (intent.getComponent() != null) {
637 return getActivityIcon(intent.getComponent());
638 }
639
640 ResolveInfo info = resolveActivity(
641 intent, PackageManager.MATCH_DEFAULT_ONLY);
642 if (info != null) {
643 return info.activityInfo.loadIcon(this);
644 }
645
Romain Guy39fe17c2011-11-30 10:34:07 -0800646 throw new NameNotFoundException(intent.toUri(0));
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800647 }
648
649 @Override public Drawable getDefaultActivityIcon() {
650 return Resources.getSystem().getDrawable(
651 com.android.internal.R.drawable.sym_def_app_icon);
652 }
653
654 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
655 return info.loadIcon(this);
656 }
657
658 @Override public Drawable getApplicationIcon(String packageName)
659 throws NameNotFoundException {
660 return getApplicationIcon(getApplicationInfo(packageName, 0));
661 }
662
663 @Override
664 public Drawable getActivityLogo(ComponentName activityName)
665 throws NameNotFoundException {
666 return getActivityInfo(activityName, 0).loadLogo(this);
667 }
668
669 @Override
670 public Drawable getActivityLogo(Intent intent)
671 throws NameNotFoundException {
672 if (intent.getComponent() != null) {
673 return getActivityLogo(intent.getComponent());
674 }
675
676 ResolveInfo info = resolveActivity(
677 intent, PackageManager.MATCH_DEFAULT_ONLY);
678 if (info != null) {
679 return info.activityInfo.loadLogo(this);
680 }
681
682 throw new NameNotFoundException(intent.toUri(0));
683 }
684
685 @Override
686 public Drawable getApplicationLogo(ApplicationInfo info) {
687 return info.loadLogo(this);
688 }
689
690 @Override
691 public Drawable getApplicationLogo(String packageName)
692 throws NameNotFoundException {
693 return getApplicationLogo(getApplicationInfo(packageName, 0));
694 }
695
696 @Override public Resources getResourcesForActivity(
697 ComponentName activityName) throws NameNotFoundException {
698 return getResourcesForApplication(
699 getActivityInfo(activityName, 0).applicationInfo);
700 }
701
702 @Override public Resources getResourcesForApplication(
703 ApplicationInfo app) throws NameNotFoundException {
704 if (app.packageName.equals("system")) {
705 return mContext.mMainThread.getSystemContext().getResources();
706 }
707 Resources r = mContext.mMainThread.getTopLevelResources(
708 app.uid == Process.myUid() ? app.sourceDir
709 : app.publicSourceDir, mContext.mPackageInfo);
710 if (r != null) {
711 return r;
712 }
713 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
714 }
715
716 @Override public Resources getResourcesForApplication(
717 String appPackageName) throws NameNotFoundException {
718 return getResourcesForApplication(
719 getApplicationInfo(appPackageName, 0));
720 }
721
722 int mCachedSafeMode = -1;
723 @Override public boolean isSafeMode() {
724 try {
725 if (mCachedSafeMode < 0) {
726 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
727 }
728 return mCachedSafeMode != 0;
729 } catch (RemoteException e) {
730 throw new RuntimeException("Package manager has died", e);
731 }
732 }
733
734 static void configurationChanged() {
735 synchronized (sSync) {
736 sIconCache.clear();
737 sStringCache.clear();
738 }
739 }
740
741 ApplicationPackageManager(ContextImpl context,
742 IPackageManager pm) {
743 mContext = context;
744 mPM = pm;
745 }
746
747 private Drawable getCachedIcon(ResourceName name) {
748 synchronized (sSync) {
Romain Guy39fe17c2011-11-30 10:34:07 -0800749 WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800750 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
751 + name + ": " + wr);
752 if (wr != null) { // we have the activity
Romain Guy39fe17c2011-11-30 10:34:07 -0800753 Drawable.ConstantState state = wr.get();
754 if (state != null) {
755 if (DEBUG_ICONS) {
756 Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
757 }
758 // Note: It's okay here to not use the newDrawable(Resources) variant
759 // of the API. The ConstantState comes from a drawable that was
760 // originally created by passing the proper app Resources instance
761 // which means the state should already contain the proper
762 // resources specific information (like density.) See
763 // BitmapDrawable.BitmapState for instance.
764 return state.newDrawable();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800765 }
766 // our entry has been purged
767 sIconCache.remove(name);
768 }
769 }
770 return null;
771 }
772
773 private void putCachedIcon(ResourceName name, Drawable dr) {
774 synchronized (sSync) {
Romain Guy39fe17c2011-11-30 10:34:07 -0800775 sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState()));
776 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800777 }
778 }
779
Romain Guy39fe17c2011-11-30 10:34:07 -0800780 static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800781 boolean immediateGc = false;
782 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
783 immediateGc = true;
784 }
785 if (pkgList != null && (pkgList.length > 0)) {
786 boolean needCleanup = false;
787 for (String ssp : pkgList) {
788 synchronized (sSync) {
789 if (sIconCache.size() > 0) {
790 Iterator<ResourceName> it = sIconCache.keySet().iterator();
791 while (it.hasNext()) {
792 ResourceName nm = it.next();
793 if (nm.packageName.equals(ssp)) {
794 //Log.i(TAG, "Removing cached drawable for " + nm);
795 it.remove();
796 needCleanup = true;
797 }
798 }
799 }
800 if (sStringCache.size() > 0) {
801 Iterator<ResourceName> it = sStringCache.keySet().iterator();
802 while (it.hasNext()) {
803 ResourceName nm = it.next();
804 if (nm.packageName.equals(ssp)) {
805 //Log.i(TAG, "Removing cached string for " + nm);
806 it.remove();
807 needCleanup = true;
808 }
809 }
810 }
811 }
812 }
813 if (needCleanup || hasPkgInfo) {
814 if (immediateGc) {
815 // Schedule an immediate gc.
816 Runtime.getRuntime().gc();
817 } else {
818 ActivityThread.currentActivityThread().scheduleGcIdler();
819 }
820 }
821 }
822 }
823
824 private static final class ResourceName {
825 final String packageName;
826 final int iconId;
827
828 ResourceName(String _packageName, int _iconId) {
829 packageName = _packageName;
830 iconId = _iconId;
831 }
832
833 ResourceName(ApplicationInfo aInfo, int _iconId) {
834 this(aInfo.packageName, _iconId);
835 }
836
837 ResourceName(ComponentInfo cInfo, int _iconId) {
838 this(cInfo.applicationInfo.packageName, _iconId);
839 }
840
841 ResourceName(ResolveInfo rInfo, int _iconId) {
842 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
843 }
844
845 @Override
846 public boolean equals(Object o) {
847 if (this == o) return true;
848 if (o == null || getClass() != o.getClass()) return false;
849
850 ResourceName that = (ResourceName) o;
851
852 if (iconId != that.iconId) return false;
853 return !(packageName != null ?
854 !packageName.equals(that.packageName) : that.packageName != null);
855
856 }
857
858 @Override
859 public int hashCode() {
860 int result;
861 result = packageName.hashCode();
862 result = 31 * result + iconId;
863 return result;
864 }
865
866 @Override
867 public String toString() {
868 return "{ResourceName " + packageName + " / " + iconId + "}";
869 }
870 }
871
872 private CharSequence getCachedString(ResourceName name) {
873 synchronized (sSync) {
874 WeakReference<CharSequence> wr = sStringCache.get(name);
875 if (wr != null) { // we have the activity
876 CharSequence cs = wr.get();
877 if (cs != null) {
878 return cs;
879 }
880 // our entry has been purged
881 sStringCache.remove(name);
882 }
883 }
884 return null;
885 }
886
887 private void putCachedString(ResourceName name, CharSequence cs) {
888 synchronized (sSync) {
889 sStringCache.put(name, new WeakReference<CharSequence>(cs));
890 }
891 }
892
893 @Override
894 public CharSequence getText(String packageName, int resid,
895 ApplicationInfo appInfo) {
896 ResourceName name = new ResourceName(packageName, resid);
897 CharSequence text = getCachedString(name);
898 if (text != null) {
899 return text;
900 }
901 if (appInfo == null) {
902 try {
903 appInfo = getApplicationInfo(packageName, 0);
904 } catch (NameNotFoundException e) {
905 return null;
906 }
907 }
908 try {
909 Resources r = getResourcesForApplication(appInfo);
910 text = r.getText(resid);
911 putCachedString(name, text);
912 return text;
913 } catch (NameNotFoundException e) {
914 Log.w("PackageManager", "Failure retrieving resources for"
915 + appInfo.packageName);
916 } catch (RuntimeException e) {
917 // If an exception was thrown, fall through to return
918 // default icon.
919 Log.w("PackageManager", "Failure retrieving text 0x"
920 + Integer.toHexString(resid) + " in package "
921 + packageName, e);
922 }
923 return null;
924 }
925
926 @Override
927 public XmlResourceParser getXml(String packageName, int resid,
928 ApplicationInfo appInfo) {
929 if (appInfo == null) {
930 try {
931 appInfo = getApplicationInfo(packageName, 0);
932 } catch (NameNotFoundException e) {
933 return null;
934 }
935 }
936 try {
937 Resources r = getResourcesForApplication(appInfo);
938 return r.getXml(resid);
939 } catch (RuntimeException e) {
940 // If an exception was thrown, fall through to return
941 // default icon.
942 Log.w("PackageManager", "Failure retrieving xml 0x"
943 + Integer.toHexString(resid) + " in package "
944 + packageName, e);
945 } catch (NameNotFoundException e) {
Alon Albert3fa51e32010-11-11 09:24:04 -0800946 Log.w("PackageManager", "Failure retrieving resources for "
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800947 + appInfo.packageName);
948 }
949 return null;
950 }
951
952 @Override
953 public CharSequence getApplicationLabel(ApplicationInfo info) {
954 return info.loadLabel(this);
955 }
956
957 @Override
958 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
959 String installerPackageName) {
960 try {
961 mPM.installPackage(packageURI, observer, flags, installerPackageName);
962 } catch (RemoteException e) {
963 // Should never happen!
964 }
965 }
966
967 @Override
Kenny Root5ab21572011-07-27 11:11:19 -0700968 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
969 int flags, String installerPackageName, Uri verificationURI,
970 ManifestDigest manifestDigest) {
971 try {
972 mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
973 verificationURI, manifestDigest);
974 } catch (RemoteException e) {
975 // Should never happen!
976 }
977 }
978
979 @Override
Kenny Root3a9b5fb2011-09-20 14:15:38 -0700980 public void verifyPendingInstall(int id, int response) {
Kenny Root5ab21572011-07-27 11:11:19 -0700981 try {
Kenny Root3a9b5fb2011-09-20 14:15:38 -0700982 mPM.verifyPendingInstall(id, response);
Kenny Root5ab21572011-07-27 11:11:19 -0700983 } catch (RemoteException e) {
984 // Should never happen!
985 }
986 }
987
988 @Override
Dianne Hackborn880119b2010-11-18 22:26:40 -0800989 public void setInstallerPackageName(String targetPackage,
990 String installerPackageName) {
991 try {
992 mPM.setInstallerPackageName(targetPackage, installerPackageName);
993 } catch (RemoteException e) {
994 // Should never happen!
995 }
996 }
997
998 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800999 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
1000 try {
1001 mPM.movePackage(packageName, observer, flags);
1002 } catch (RemoteException e) {
1003 // Should never happen!
1004 }
1005 }
1006
1007 @Override
1008 public String getInstallerPackageName(String packageName) {
1009 try {
1010 return mPM.getInstallerPackageName(packageName);
1011 } catch (RemoteException e) {
1012 // Should never happen!
1013 }
1014 return null;
1015 }
1016
1017 @Override
1018 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1019 try {
1020 mPM.deletePackage(packageName, observer, flags);
1021 } catch (RemoteException e) {
1022 // Should never happen!
1023 }
1024 }
1025 @Override
1026 public void clearApplicationUserData(String packageName,
1027 IPackageDataObserver observer) {
1028 try {
1029 mPM.clearApplicationUserData(packageName, observer);
1030 } catch (RemoteException e) {
1031 // Should never happen!
1032 }
1033 }
1034 @Override
1035 public void deleteApplicationCacheFiles(String packageName,
1036 IPackageDataObserver observer) {
1037 try {
1038 mPM.deleteApplicationCacheFiles(packageName, observer);
1039 } catch (RemoteException e) {
1040 // Should never happen!
1041 }
1042 }
1043 @Override
1044 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
1045 try {
1046 mPM.freeStorageAndNotify(idealStorageSize, observer);
1047 } catch (RemoteException e) {
1048 // Should never happen!
1049 }
1050 }
1051
1052 @Override
1053 public void freeStorage(long freeStorageSize, IntentSender pi) {
1054 try {
1055 mPM.freeStorage(freeStorageSize, pi);
1056 } catch (RemoteException e) {
1057 // Should never happen!
1058 }
1059 }
1060
1061 @Override
1062 public void getPackageSizeInfo(String packageName,
1063 IPackageStatsObserver observer) {
1064 try {
1065 mPM.getPackageSizeInfo(packageName, observer);
1066 } catch (RemoteException e) {
1067 // Should never happen!
1068 }
1069 }
1070 @Override
1071 public void addPackageToPreferred(String packageName) {
1072 try {
1073 mPM.addPackageToPreferred(packageName);
1074 } catch (RemoteException e) {
1075 // Should never happen!
1076 }
1077 }
1078
1079 @Override
1080 public void removePackageFromPreferred(String packageName) {
1081 try {
1082 mPM.removePackageFromPreferred(packageName);
1083 } catch (RemoteException e) {
1084 // Should never happen!
1085 }
1086 }
1087
1088 @Override
1089 public List<PackageInfo> getPreferredPackages(int flags) {
1090 try {
1091 return mPM.getPreferredPackages(flags);
1092 } catch (RemoteException e) {
1093 // Should never happen!
1094 }
1095 return new ArrayList<PackageInfo>();
1096 }
1097
1098 @Override
1099 public void addPreferredActivity(IntentFilter filter,
1100 int match, ComponentName[] set, ComponentName activity) {
1101 try {
1102 mPM.addPreferredActivity(filter, match, set, activity);
1103 } catch (RemoteException e) {
1104 // Should never happen!
1105 }
1106 }
1107
1108 @Override
1109 public void replacePreferredActivity(IntentFilter filter,
1110 int match, ComponentName[] set, ComponentName activity) {
1111 try {
1112 mPM.replacePreferredActivity(filter, match, set, activity);
1113 } catch (RemoteException e) {
1114 // Should never happen!
1115 }
1116 }
1117
1118 @Override
1119 public void clearPackagePreferredActivities(String packageName) {
1120 try {
1121 mPM.clearPackagePreferredActivities(packageName);
1122 } catch (RemoteException e) {
1123 // Should never happen!
1124 }
1125 }
1126
1127 @Override
1128 public int getPreferredActivities(List<IntentFilter> outFilters,
1129 List<ComponentName> outActivities, String packageName) {
1130 try {
1131 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1132 } catch (RemoteException e) {
1133 // Should never happen!
1134 }
1135 return 0;
1136 }
1137
1138 @Override
1139 public void setComponentEnabledSetting(ComponentName componentName,
1140 int newState, int flags) {
1141 try {
1142 mPM.setComponentEnabledSetting(componentName, newState, flags);
1143 } catch (RemoteException e) {
1144 // Should never happen!
1145 }
1146 }
1147
1148 @Override
1149 public int getComponentEnabledSetting(ComponentName componentName) {
1150 try {
1151 return mPM.getComponentEnabledSetting(componentName);
1152 } catch (RemoteException e) {
1153 // Should never happen!
1154 }
1155 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1156 }
1157
1158 @Override
1159 public void setApplicationEnabledSetting(String packageName,
1160 int newState, int flags) {
1161 try {
1162 mPM.setApplicationEnabledSetting(packageName, newState, flags);
1163 } catch (RemoteException e) {
1164 // Should never happen!
1165 }
1166 }
1167
1168 @Override
1169 public int getApplicationEnabledSetting(String packageName) {
1170 try {
1171 return mPM.getApplicationEnabledSetting(packageName);
1172 } catch (RemoteException e) {
1173 // Should never happen!
1174 }
1175 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1176 }
1177
Amith Yamasani4b2e9342011-03-31 12:38:53 -07001178 // Multi-user support
1179
1180 /**
1181 * @hide
1182 */
1183 @Override
1184 public UserInfo createUser(String name, int flags) {
Amith Yamasani0b285492011-04-14 17:35:23 -07001185 try {
1186 return mPM.createUser(name, flags);
1187 } catch (RemoteException e) {
1188 // Should never happen!
1189 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -07001190 return null;
1191 }
1192
1193 /**
1194 * @hide
1195 */
1196 @Override
1197 public List<UserInfo> getUsers() {
Amith Yamasani742a6712011-05-04 14:49:28 -07001198 try {
1199 return mPM.getUsers();
1200 } catch (RemoteException re) {
1201 ArrayList<UserInfo> users = new ArrayList<UserInfo>();
1202 UserInfo primary = new UserInfo(0, "Root!", UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
1203 users.add(primary);
1204 return users;
1205 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -07001206 }
1207
1208 /**
1209 * @hide
1210 */
1211 @Override
1212 public boolean removeUser(int id) {
Amith Yamasani0b285492011-04-14 17:35:23 -07001213 try {
1214 return mPM.removeUser(id);
1215 } catch (RemoteException e) {
1216 return false;
1217 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -07001218 }
1219
1220 /**
1221 * @hide
1222 */
1223 @Override
1224 public void updateUserName(int id, String name) {
1225 // TODO:
1226 }
1227
1228 /**
1229 * @hide
1230 */
1231 @Override
1232 public void updateUserFlags(int id, int flags) {
1233 // TODO:
1234 }
1235
Kenny Root0aaa0d92011-09-12 16:42:55 -07001236 /**
1237 * @hide
1238 */
1239 @Override
1240 public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1241 try {
1242 return mPM.getVerifierDeviceIdentity();
1243 } catch (RemoteException e) {
1244 // Should never happen!
1245 }
1246 return null;
1247 }
1248
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001249 private final ContextImpl mContext;
1250 private final IPackageManager mPM;
1251
1252 private static final Object sSync = new Object();
Romain Guy39fe17c2011-11-30 10:34:07 -08001253 private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
1254 = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>();
1255 private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache
1256 = new HashMap<ResourceName, WeakReference<CharSequence>>();
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001257}