blob: bd42e3413ca7622f48126efb2071832ef9ea2faa [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
335 public int checkSignatures(String pkg1, String pkg2) {
336 try {
337 return mPM.checkSignatures(pkg1, pkg2);
338 } catch (RemoteException e) {
339 throw new RuntimeException("Package manager has died", e);
340 }
341 }
342
343 @Override
344 public int checkSignatures(int uid1, int uid2) {
345 try {
346 return mPM.checkUidSignatures(uid1, uid2);
347 } catch (RemoteException e) {
348 throw new RuntimeException("Package manager has died", e);
349 }
350 }
351
352 @Override
353 public String[] getPackagesForUid(int uid) {
354 try {
355 return mPM.getPackagesForUid(uid);
356 } catch (RemoteException e) {
357 throw new RuntimeException("Package manager has died", e);
358 }
359 }
360
361 @Override
362 public String getNameForUid(int uid) {
363 try {
364 return mPM.getNameForUid(uid);
365 } catch (RemoteException e) {
366 throw new RuntimeException("Package manager has died", e);
367 }
368 }
369
370 @Override
371 public int getUidForSharedUser(String sharedUserName)
372 throws NameNotFoundException {
373 try {
374 int uid = mPM.getUidForSharedUser(sharedUserName);
375 if(uid != -1) {
376 return uid;
377 }
378 } catch (RemoteException e) {
379 throw new RuntimeException("Package manager has died", e);
380 }
381 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
382 }
383
Kenny Roote6cd0c72011-05-19 12:48:14 -0700384 @SuppressWarnings("unchecked")
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800385 @Override
386 public List<PackageInfo> getInstalledPackages(int flags) {
387 try {
Kenny Roote6cd0c72011-05-19 12:48:14 -0700388 final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
389 PackageInfo lastItem = null;
390 ParceledListSlice<PackageInfo> slice;
391
392 do {
393 final String lastKey = lastItem != null ? lastItem.packageName : null;
394 slice = mPM.getInstalledPackages(flags, lastKey);
395 lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
396 } while (!slice.isLastSlice());
397
398 return packageInfos;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800399 } catch (RemoteException e) {
400 throw new RuntimeException("Package manager has died", e);
401 }
402 }
403
Kenny Roote6cd0c72011-05-19 12:48:14 -0700404 @SuppressWarnings("unchecked")
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800405 @Override
406 public List<ApplicationInfo> getInstalledApplications(int flags) {
407 try {
Kenny Roote6cd0c72011-05-19 12:48:14 -0700408 final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>();
409 ApplicationInfo lastItem = null;
410 ParceledListSlice<ApplicationInfo> slice;
411
412 do {
413 final String lastKey = lastItem != null ? lastItem.packageName : null;
414 slice = mPM.getInstalledApplications(flags, lastKey);
415 lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR);
416 } while (!slice.isLastSlice());
417
418 return applicationInfos;
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800419 } catch (RemoteException e) {
420 throw new RuntimeException("Package manager has died", e);
421 }
422 }
423
424 @Override
425 public ResolveInfo resolveActivity(Intent intent, int flags) {
426 try {
427 return mPM.resolveIntent(
428 intent,
429 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
430 flags);
431 } catch (RemoteException e) {
432 throw new RuntimeException("Package manager has died", e);
433 }
434 }
435
436 @Override
437 public List<ResolveInfo> queryIntentActivities(Intent intent,
438 int flags) {
439 try {
440 return mPM.queryIntentActivities(
441 intent,
442 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
443 flags);
444 } catch (RemoteException e) {
445 throw new RuntimeException("Package manager has died", e);
446 }
447 }
448
449 @Override
450 public List<ResolveInfo> queryIntentActivityOptions(
451 ComponentName caller, Intent[] specifics, Intent intent,
452 int flags) {
453 final ContentResolver resolver = mContext.getContentResolver();
454
455 String[] specificTypes = null;
456 if (specifics != null) {
457 final int N = specifics.length;
458 for (int i=0; i<N; i++) {
459 Intent sp = specifics[i];
460 if (sp != null) {
461 String t = sp.resolveTypeIfNeeded(resolver);
462 if (t != null) {
463 if (specificTypes == null) {
464 specificTypes = new String[N];
465 }
466 specificTypes[i] = t;
467 }
468 }
469 }
470 }
471
472 try {
473 return mPM.queryIntentActivityOptions(caller, specifics,
474 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
475 flags);
476 } catch (RemoteException e) {
477 throw new RuntimeException("Package manager has died", e);
478 }
479 }
480
481 @Override
482 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
483 try {
484 return mPM.queryIntentReceivers(
485 intent,
486 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
487 flags);
488 } catch (RemoteException e) {
489 throw new RuntimeException("Package manager has died", e);
490 }
491 }
492
493 @Override
494 public ResolveInfo resolveService(Intent intent, int flags) {
495 try {
496 return mPM.resolveService(
497 intent,
498 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
499 flags);
500 } catch (RemoteException e) {
501 throw new RuntimeException("Package manager has died", e);
502 }
503 }
504
505 @Override
506 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
507 try {
508 return mPM.queryIntentServices(
509 intent,
510 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
511 flags);
512 } catch (RemoteException e) {
513 throw new RuntimeException("Package manager has died", e);
514 }
515 }
516
517 @Override
518 public ProviderInfo resolveContentProvider(String name,
519 int flags) {
520 try {
521 return mPM.resolveContentProvider(name, flags);
522 } catch (RemoteException e) {
523 throw new RuntimeException("Package manager has died", e);
524 }
525 }
526
527 @Override
528 public List<ProviderInfo> queryContentProviders(String processName,
529 int uid, int flags) {
530 try {
531 return mPM.queryContentProviders(processName, uid, flags);
532 } catch (RemoteException e) {
533 throw new RuntimeException("Package manager has died", e);
534 }
535 }
536
537 @Override
538 public InstrumentationInfo getInstrumentationInfo(
539 ComponentName className, int flags)
540 throws NameNotFoundException {
541 try {
542 InstrumentationInfo ii = mPM.getInstrumentationInfo(
543 className, flags);
544 if (ii != null) {
545 return ii;
546 }
547 } catch (RemoteException e) {
548 throw new RuntimeException("Package manager has died", e);
549 }
550
551 throw new NameNotFoundException(className.toString());
552 }
553
554 @Override
555 public List<InstrumentationInfo> queryInstrumentation(
556 String targetPackage, int flags) {
557 try {
558 return mPM.queryInstrumentation(targetPackage, flags);
559 } catch (RemoteException e) {
560 throw new RuntimeException("Package manager has died", e);
561 }
562 }
563
564 @Override public Drawable getDrawable(String packageName, int resid,
565 ApplicationInfo appInfo) {
566 ResourceName name = new ResourceName(packageName, resid);
567 Drawable dr = getCachedIcon(name);
568 if (dr != null) {
569 return dr;
570 }
571 if (appInfo == null) {
572 try {
573 appInfo = getApplicationInfo(packageName, 0);
574 } catch (NameNotFoundException e) {
575 return null;
576 }
577 }
578 try {
579 Resources r = getResourcesForApplication(appInfo);
580 dr = r.getDrawable(resid);
581 if (false) {
582 RuntimeException e = new RuntimeException("here");
583 e.fillInStackTrace();
584 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
585 + " from package " + packageName
586 + ": app scale=" + r.getCompatibilityInfo().applicationScale
587 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
588 e);
589 }
590 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
591 + Integer.toHexString(resid) + " from " + r
592 + ": " + dr);
593 putCachedIcon(name, dr);
594 return dr;
595 } catch (NameNotFoundException e) {
596 Log.w("PackageManager", "Failure retrieving resources for"
597 + appInfo.packageName);
Joe Onorato08f16542011-01-20 11:49:56 -0800598 } catch (Resources.NotFoundException e) {
599 Log.w("PackageManager", "Failure retrieving resources for"
600 + appInfo.packageName + ": " + e.getMessage());
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800601 } catch (RuntimeException e) {
602 // If an exception was thrown, fall through to return
603 // default icon.
604 Log.w("PackageManager", "Failure retrieving icon 0x"
605 + Integer.toHexString(resid) + " in package "
606 + packageName, e);
607 }
608 return null;
609 }
610
611 @Override public Drawable getActivityIcon(ComponentName activityName)
612 throws NameNotFoundException {
613 return getActivityInfo(activityName, 0).loadIcon(this);
614 }
615
616 @Override public Drawable getActivityIcon(Intent intent)
617 throws NameNotFoundException {
618 if (intent.getComponent() != null) {
619 return getActivityIcon(intent.getComponent());
620 }
621
622 ResolveInfo info = resolveActivity(
623 intent, PackageManager.MATCH_DEFAULT_ONLY);
624 if (info != null) {
625 return info.activityInfo.loadIcon(this);
626 }
627
628 throw new NameNotFoundException(intent.toURI());
629 }
630
631 @Override public Drawable getDefaultActivityIcon() {
632 return Resources.getSystem().getDrawable(
633 com.android.internal.R.drawable.sym_def_app_icon);
634 }
635
636 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
637 return info.loadIcon(this);
638 }
639
640 @Override public Drawable getApplicationIcon(String packageName)
641 throws NameNotFoundException {
642 return getApplicationIcon(getApplicationInfo(packageName, 0));
643 }
644
645 @Override
646 public Drawable getActivityLogo(ComponentName activityName)
647 throws NameNotFoundException {
648 return getActivityInfo(activityName, 0).loadLogo(this);
649 }
650
651 @Override
652 public Drawable getActivityLogo(Intent intent)
653 throws NameNotFoundException {
654 if (intent.getComponent() != null) {
655 return getActivityLogo(intent.getComponent());
656 }
657
658 ResolveInfo info = resolveActivity(
659 intent, PackageManager.MATCH_DEFAULT_ONLY);
660 if (info != null) {
661 return info.activityInfo.loadLogo(this);
662 }
663
664 throw new NameNotFoundException(intent.toUri(0));
665 }
666
667 @Override
668 public Drawable getApplicationLogo(ApplicationInfo info) {
669 return info.loadLogo(this);
670 }
671
672 @Override
673 public Drawable getApplicationLogo(String packageName)
674 throws NameNotFoundException {
675 return getApplicationLogo(getApplicationInfo(packageName, 0));
676 }
677
678 @Override public Resources getResourcesForActivity(
679 ComponentName activityName) throws NameNotFoundException {
680 return getResourcesForApplication(
681 getActivityInfo(activityName, 0).applicationInfo);
682 }
683
684 @Override public Resources getResourcesForApplication(
685 ApplicationInfo app) throws NameNotFoundException {
686 if (app.packageName.equals("system")) {
687 return mContext.mMainThread.getSystemContext().getResources();
688 }
689 Resources r = mContext.mMainThread.getTopLevelResources(
690 app.uid == Process.myUid() ? app.sourceDir
691 : app.publicSourceDir, mContext.mPackageInfo);
692 if (r != null) {
693 return r;
694 }
695 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
696 }
697
698 @Override public Resources getResourcesForApplication(
699 String appPackageName) throws NameNotFoundException {
700 return getResourcesForApplication(
701 getApplicationInfo(appPackageName, 0));
702 }
703
704 int mCachedSafeMode = -1;
705 @Override public boolean isSafeMode() {
706 try {
707 if (mCachedSafeMode < 0) {
708 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
709 }
710 return mCachedSafeMode != 0;
711 } catch (RemoteException e) {
712 throw new RuntimeException("Package manager has died", e);
713 }
714 }
715
716 static void configurationChanged() {
717 synchronized (sSync) {
718 sIconCache.clear();
719 sStringCache.clear();
720 }
721 }
722
723 ApplicationPackageManager(ContextImpl context,
724 IPackageManager pm) {
725 mContext = context;
726 mPM = pm;
727 }
728
729 private Drawable getCachedIcon(ResourceName name) {
730 synchronized (sSync) {
731 WeakReference<Drawable> wr = sIconCache.get(name);
732 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
733 + name + ": " + wr);
734 if (wr != null) { // we have the activity
735 Drawable dr = wr.get();
736 if (dr != null) {
737 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
738 + name + ": " + dr);
739 return dr;
740 }
741 // our entry has been purged
742 sIconCache.remove(name);
743 }
744 }
745 return null;
746 }
747
748 private void putCachedIcon(ResourceName name, Drawable dr) {
749 synchronized (sSync) {
750 sIconCache.put(name, new WeakReference<Drawable>(dr));
751 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
752 + name + ": " + dr);
753 }
754 }
755
756 static final void handlePackageBroadcast(int cmd, String[] pkgList,
757 boolean hasPkgInfo) {
758 boolean immediateGc = false;
759 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
760 immediateGc = true;
761 }
762 if (pkgList != null && (pkgList.length > 0)) {
763 boolean needCleanup = false;
764 for (String ssp : pkgList) {
765 synchronized (sSync) {
766 if (sIconCache.size() > 0) {
767 Iterator<ResourceName> it = sIconCache.keySet().iterator();
768 while (it.hasNext()) {
769 ResourceName nm = it.next();
770 if (nm.packageName.equals(ssp)) {
771 //Log.i(TAG, "Removing cached drawable for " + nm);
772 it.remove();
773 needCleanup = true;
774 }
775 }
776 }
777 if (sStringCache.size() > 0) {
778 Iterator<ResourceName> it = sStringCache.keySet().iterator();
779 while (it.hasNext()) {
780 ResourceName nm = it.next();
781 if (nm.packageName.equals(ssp)) {
782 //Log.i(TAG, "Removing cached string for " + nm);
783 it.remove();
784 needCleanup = true;
785 }
786 }
787 }
788 }
789 }
790 if (needCleanup || hasPkgInfo) {
791 if (immediateGc) {
792 // Schedule an immediate gc.
793 Runtime.getRuntime().gc();
794 } else {
795 ActivityThread.currentActivityThread().scheduleGcIdler();
796 }
797 }
798 }
799 }
800
801 private static final class ResourceName {
802 final String packageName;
803 final int iconId;
804
805 ResourceName(String _packageName, int _iconId) {
806 packageName = _packageName;
807 iconId = _iconId;
808 }
809
810 ResourceName(ApplicationInfo aInfo, int _iconId) {
811 this(aInfo.packageName, _iconId);
812 }
813
814 ResourceName(ComponentInfo cInfo, int _iconId) {
815 this(cInfo.applicationInfo.packageName, _iconId);
816 }
817
818 ResourceName(ResolveInfo rInfo, int _iconId) {
819 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
820 }
821
822 @Override
823 public boolean equals(Object o) {
824 if (this == o) return true;
825 if (o == null || getClass() != o.getClass()) return false;
826
827 ResourceName that = (ResourceName) o;
828
829 if (iconId != that.iconId) return false;
830 return !(packageName != null ?
831 !packageName.equals(that.packageName) : that.packageName != null);
832
833 }
834
835 @Override
836 public int hashCode() {
837 int result;
838 result = packageName.hashCode();
839 result = 31 * result + iconId;
840 return result;
841 }
842
843 @Override
844 public String toString() {
845 return "{ResourceName " + packageName + " / " + iconId + "}";
846 }
847 }
848
849 private CharSequence getCachedString(ResourceName name) {
850 synchronized (sSync) {
851 WeakReference<CharSequence> wr = sStringCache.get(name);
852 if (wr != null) { // we have the activity
853 CharSequence cs = wr.get();
854 if (cs != null) {
855 return cs;
856 }
857 // our entry has been purged
858 sStringCache.remove(name);
859 }
860 }
861 return null;
862 }
863
864 private void putCachedString(ResourceName name, CharSequence cs) {
865 synchronized (sSync) {
866 sStringCache.put(name, new WeakReference<CharSequence>(cs));
867 }
868 }
869
870 @Override
871 public CharSequence getText(String packageName, int resid,
872 ApplicationInfo appInfo) {
873 ResourceName name = new ResourceName(packageName, resid);
874 CharSequence text = getCachedString(name);
875 if (text != null) {
876 return text;
877 }
878 if (appInfo == null) {
879 try {
880 appInfo = getApplicationInfo(packageName, 0);
881 } catch (NameNotFoundException e) {
882 return null;
883 }
884 }
885 try {
886 Resources r = getResourcesForApplication(appInfo);
887 text = r.getText(resid);
888 putCachedString(name, text);
889 return text;
890 } catch (NameNotFoundException e) {
891 Log.w("PackageManager", "Failure retrieving resources for"
892 + appInfo.packageName);
893 } catch (RuntimeException e) {
894 // If an exception was thrown, fall through to return
895 // default icon.
896 Log.w("PackageManager", "Failure retrieving text 0x"
897 + Integer.toHexString(resid) + " in package "
898 + packageName, e);
899 }
900 return null;
901 }
902
903 @Override
904 public XmlResourceParser getXml(String packageName, int resid,
905 ApplicationInfo appInfo) {
906 if (appInfo == null) {
907 try {
908 appInfo = getApplicationInfo(packageName, 0);
909 } catch (NameNotFoundException e) {
910 return null;
911 }
912 }
913 try {
914 Resources r = getResourcesForApplication(appInfo);
915 return r.getXml(resid);
916 } catch (RuntimeException e) {
917 // If an exception was thrown, fall through to return
918 // default icon.
919 Log.w("PackageManager", "Failure retrieving xml 0x"
920 + Integer.toHexString(resid) + " in package "
921 + packageName, e);
922 } catch (NameNotFoundException e) {
Alon Albert3fa51e32010-11-11 09:24:04 -0800923 Log.w("PackageManager", "Failure retrieving resources for "
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800924 + appInfo.packageName);
925 }
926 return null;
927 }
928
929 @Override
930 public CharSequence getApplicationLabel(ApplicationInfo info) {
931 return info.loadLabel(this);
932 }
933
934 @Override
935 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
936 String installerPackageName) {
937 try {
938 mPM.installPackage(packageURI, observer, flags, installerPackageName);
939 } catch (RemoteException e) {
940 // Should never happen!
941 }
942 }
943
944 @Override
Kenny Root5ab21572011-07-27 11:11:19 -0700945 public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
946 int flags, String installerPackageName, Uri verificationURI,
947 ManifestDigest manifestDigest) {
948 try {
949 mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
950 verificationURI, manifestDigest);
951 } catch (RemoteException e) {
952 // Should never happen!
953 }
954 }
955
956 @Override
957 public void verifyPendingInstall(int id, boolean verified, String failureMessage) {
958 try {
959 mPM.verifyPendingInstall(id, verified, failureMessage);
960 } catch (RemoteException e) {
961 // Should never happen!
962 }
963 }
964
965 @Override
Dianne Hackborn880119b2010-11-18 22:26:40 -0800966 public void setInstallerPackageName(String targetPackage,
967 String installerPackageName) {
968 try {
969 mPM.setInstallerPackageName(targetPackage, installerPackageName);
970 } catch (RemoteException e) {
971 // Should never happen!
972 }
973 }
974
975 @Override
Brad Fitzpatrick390dae12010-11-10 08:27:28 -0800976 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
977 try {
978 mPM.movePackage(packageName, observer, flags);
979 } catch (RemoteException e) {
980 // Should never happen!
981 }
982 }
983
984 @Override
985 public String getInstallerPackageName(String packageName) {
986 try {
987 return mPM.getInstallerPackageName(packageName);
988 } catch (RemoteException e) {
989 // Should never happen!
990 }
991 return null;
992 }
993
994 @Override
995 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
996 try {
997 mPM.deletePackage(packageName, observer, flags);
998 } catch (RemoteException e) {
999 // Should never happen!
1000 }
1001 }
1002 @Override
1003 public void clearApplicationUserData(String packageName,
1004 IPackageDataObserver observer) {
1005 try {
1006 mPM.clearApplicationUserData(packageName, observer);
1007 } catch (RemoteException e) {
1008 // Should never happen!
1009 }
1010 }
1011 @Override
1012 public void deleteApplicationCacheFiles(String packageName,
1013 IPackageDataObserver observer) {
1014 try {
1015 mPM.deleteApplicationCacheFiles(packageName, observer);
1016 } catch (RemoteException e) {
1017 // Should never happen!
1018 }
1019 }
1020 @Override
1021 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
1022 try {
1023 mPM.freeStorageAndNotify(idealStorageSize, observer);
1024 } catch (RemoteException e) {
1025 // Should never happen!
1026 }
1027 }
1028
1029 @Override
1030 public void freeStorage(long freeStorageSize, IntentSender pi) {
1031 try {
1032 mPM.freeStorage(freeStorageSize, pi);
1033 } catch (RemoteException e) {
1034 // Should never happen!
1035 }
1036 }
1037
1038 @Override
1039 public void getPackageSizeInfo(String packageName,
1040 IPackageStatsObserver observer) {
1041 try {
1042 mPM.getPackageSizeInfo(packageName, observer);
1043 } catch (RemoteException e) {
1044 // Should never happen!
1045 }
1046 }
1047 @Override
1048 public void addPackageToPreferred(String packageName) {
1049 try {
1050 mPM.addPackageToPreferred(packageName);
1051 } catch (RemoteException e) {
1052 // Should never happen!
1053 }
1054 }
1055
1056 @Override
1057 public void removePackageFromPreferred(String packageName) {
1058 try {
1059 mPM.removePackageFromPreferred(packageName);
1060 } catch (RemoteException e) {
1061 // Should never happen!
1062 }
1063 }
1064
1065 @Override
1066 public List<PackageInfo> getPreferredPackages(int flags) {
1067 try {
1068 return mPM.getPreferredPackages(flags);
1069 } catch (RemoteException e) {
1070 // Should never happen!
1071 }
1072 return new ArrayList<PackageInfo>();
1073 }
1074
1075 @Override
1076 public void addPreferredActivity(IntentFilter filter,
1077 int match, ComponentName[] set, ComponentName activity) {
1078 try {
1079 mPM.addPreferredActivity(filter, match, set, activity);
1080 } catch (RemoteException e) {
1081 // Should never happen!
1082 }
1083 }
1084
1085 @Override
1086 public void replacePreferredActivity(IntentFilter filter,
1087 int match, ComponentName[] set, ComponentName activity) {
1088 try {
1089 mPM.replacePreferredActivity(filter, match, set, activity);
1090 } catch (RemoteException e) {
1091 // Should never happen!
1092 }
1093 }
1094
1095 @Override
1096 public void clearPackagePreferredActivities(String packageName) {
1097 try {
1098 mPM.clearPackagePreferredActivities(packageName);
1099 } catch (RemoteException e) {
1100 // Should never happen!
1101 }
1102 }
1103
1104 @Override
1105 public int getPreferredActivities(List<IntentFilter> outFilters,
1106 List<ComponentName> outActivities, String packageName) {
1107 try {
1108 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1109 } catch (RemoteException e) {
1110 // Should never happen!
1111 }
1112 return 0;
1113 }
1114
1115 @Override
1116 public void setComponentEnabledSetting(ComponentName componentName,
1117 int newState, int flags) {
1118 try {
1119 mPM.setComponentEnabledSetting(componentName, newState, flags);
1120 } catch (RemoteException e) {
1121 // Should never happen!
1122 }
1123 }
1124
1125 @Override
1126 public int getComponentEnabledSetting(ComponentName componentName) {
1127 try {
1128 return mPM.getComponentEnabledSetting(componentName);
1129 } catch (RemoteException e) {
1130 // Should never happen!
1131 }
1132 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1133 }
1134
1135 @Override
1136 public void setApplicationEnabledSetting(String packageName,
1137 int newState, int flags) {
1138 try {
1139 mPM.setApplicationEnabledSetting(packageName, newState, flags);
1140 } catch (RemoteException e) {
1141 // Should never happen!
1142 }
1143 }
1144
1145 @Override
1146 public int getApplicationEnabledSetting(String packageName) {
1147 try {
1148 return mPM.getApplicationEnabledSetting(packageName);
1149 } catch (RemoteException e) {
1150 // Should never happen!
1151 }
1152 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1153 }
1154
Amith Yamasani4b2e9342011-03-31 12:38:53 -07001155 // Multi-user support
1156
1157 /**
1158 * @hide
1159 */
1160 @Override
1161 public UserInfo createUser(String name, int flags) {
Amith Yamasani0b285492011-04-14 17:35:23 -07001162 try {
1163 return mPM.createUser(name, flags);
1164 } catch (RemoteException e) {
1165 // Should never happen!
1166 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -07001167 return null;
1168 }
1169
1170 /**
1171 * @hide
1172 */
1173 @Override
1174 public List<UserInfo> getUsers() {
1175 // TODO:
1176 // Dummy code, always returns just the primary user
1177 ArrayList<UserInfo> users = new ArrayList<UserInfo>();
1178 UserInfo primary = new UserInfo(0, "Root!",
1179 UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
1180 users.add(primary);
1181 return users;
1182 }
1183
1184 /**
1185 * @hide
1186 */
1187 @Override
1188 public boolean removeUser(int id) {
Amith Yamasani0b285492011-04-14 17:35:23 -07001189 try {
1190 return mPM.removeUser(id);
1191 } catch (RemoteException e) {
1192 return false;
1193 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -07001194 }
1195
1196 /**
1197 * @hide
1198 */
1199 @Override
1200 public void updateUserName(int id, String name) {
1201 // TODO:
1202 }
1203
1204 /**
1205 * @hide
1206 */
1207 @Override
1208 public void updateUserFlags(int id, int flags) {
1209 // TODO:
1210 }
1211
Kenny Root0aaa0d92011-09-12 16:42:55 -07001212 /**
1213 * @hide
1214 */
1215 @Override
1216 public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1217 try {
1218 return mPM.getVerifierDeviceIdentity();
1219 } catch (RemoteException e) {
1220 // Should never happen!
1221 }
1222 return null;
1223 }
1224
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08001225 private final ContextImpl mContext;
1226 private final IPackageManager mPM;
1227
1228 private static final Object sSync = new Object();
1229 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
1230 = new HashMap<ResourceName, WeakReference<Drawable> >();
1231 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
1232 = new HashMap<ResourceName, WeakReference<CharSequence> >();
1233}