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