diff options
author | Suchi Amalapurapu <asuchitra@google.com> | 2010-01-28 09:57:30 -0800 |
---|---|---|
committer | Suchi Amalapurapu <asuchitra@google.com> | 2010-02-02 18:33:29 -0800 |
commit | 08675a3376819a82aa5ab344bc3e7b1635c30b05 (patch) | |
tree | 9a16e6be377fe367639ef9e02c5421e0ce9b9044 /core | |
parent | 57405b93f194851eb2187a8ed3362be18a483a17 (diff) | |
download | frameworks_base-08675a3376819a82aa5ab344bc3e7b1635c30b05.zip frameworks_base-08675a3376819a82aa5ab344bc3e7b1635c30b05.tar.gz frameworks_base-08675a3376819a82aa5ab344bc3e7b1635c30b05.tar.bz2 |
Apps on sdcard: Add new broadcasts
Add new broadcasts ACTION_MEDIA_RESOURCES_AVAILABLE and
ACTION_MEDIA_RESOURCES_UNAVAILABLE that get broadcast by
PackageManagerService when sdcard gets mounted/unmounted
by MountService so that packages on sdcard get recognized by
various system services as being installed/available or
removed/unavailable by the system.
The broadcasts are sent before the actual package cleanup which includes
mounting/unmounting the packages and we force a gc right after so
that any lingering file references to resources on sdcard get
released.
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/app/ApplicationContext.java | 71 | ||||
-rw-r--r-- | core/java/android/content/Intent.java | 77 | ||||
-rw-r--r-- | core/java/android/content/pm/RegisteredServicesCache.java | 5 | ||||
-rw-r--r-- | core/java/android/server/search/SearchManagerService.java | 9 |
4 files changed, 139 insertions, 23 deletions
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java index 7455bac..cf6e0e7 100644 --- a/core/java/android/app/ApplicationContext.java +++ b/core/java/android/app/ApplicationContext.java @@ -2164,6 +2164,11 @@ class ApplicationContext extends Context { filter.addDataScheme("package"); mContext.registerReceiverInternal(sPackageRemovedReceiver, filter, null, null, null); + // Register for events related to sdcard installation. + IntentFilter sdFilter = new IntentFilter(); + sdFilter.addAction(Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE); + mContext.registerReceiverInternal(sPackageRemovedReceiver, + sdFilter, null, null, null); } } } @@ -2181,32 +2186,56 @@ class ApplicationContext extends Context { private static final class PackageRemovedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - Uri data = intent.getData(); - String ssp; - if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { + String pkgList[] = null; + String action = intent.getAction(); + boolean immediateGc = false; + if (Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE.equals(action)) { + pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); + immediateGc = true; + } else { + Uri data = intent.getData(); + if (data != null) { + String ssp = data.getSchemeSpecificPart(); + if (ssp != null) { + pkgList = new String[] { ssp }; + } + } + } + if (pkgList != null && (pkgList.length > 0)) { boolean needCleanup = false; - synchronized (sSync) { - Iterator<ResourceName> it = sIconCache.keySet().iterator(); - while (it.hasNext()) { - ResourceName nm = it.next(); - if (nm.packageName.equals(ssp)) { - //Log.i(TAG, "Removing cached drawable for " + nm); - it.remove(); - needCleanup = true; + boolean hasPkgInfo = false; + for (String ssp : pkgList) { + synchronized (sSync) { + Iterator<ResourceName> it = sIconCache.keySet().iterator(); + while (it.hasNext()) { + ResourceName nm = it.next(); + if (nm.packageName.equals(ssp)) { + //Log.i(TAG, "Removing cached drawable for " + nm); + it.remove(); + needCleanup = true; + } } - } - it = sStringCache.keySet().iterator(); - while (it.hasNext()) { - ResourceName nm = it.next(); - if (nm.packageName.equals(ssp)) { - //Log.i(TAG, "Removing cached string for " + nm); - it.remove(); - needCleanup = true; + it = sStringCache.keySet().iterator(); + while (it.hasNext()) { + ResourceName nm = it.next(); + if (nm.packageName.equals(ssp)) { + //Log.i(TAG, "Removing cached string for " + nm); + it.remove(); + needCleanup = true; + } } } + if (!hasPkgInfo) { + hasPkgInfo = ActivityThread.currentActivityThread().hasPackageInfo(ssp); + } } - if (needCleanup || ActivityThread.currentActivityThread().hasPackageInfo(ssp)) { - ActivityThread.currentActivityThread().scheduleGcIdler(); + if (needCleanup || hasPkgInfo) { + if (immediateGc) { + // Schedule an immediate gc. + Runtime.getRuntime().gc(); + } else { + ActivityThread.currentActivityThread().scheduleGcIdler(); + } } } } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index bbd359b..e957e20 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1355,6 +1355,60 @@ public class Intent implements Parcelable, Cloneable { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED"; + + /** + * Broadcast Action: Resources for a set of packages (which were + * previously unavailable) are currently + * available since the media on which they exist is available. + * The extra data {@link #EXTRA_CHANGED_PACKAGE_LIST} contains a + * list of packages whose availability changed. + * The extra data {@link #EXTRA_CHANGED_UID_LIST} contains a + * list of uids of packages whose availability changed. + * Note that the + * packages in this list do <em>not</em> receive this broadcast. + * The specified set of packages are now available on the system. + * <p>Includes the following extras: + * <ul> + * <li> {@link #EXTRA_CHANGED_PACKAGE_LIST} is the set of packages + * whose resources(were previously unavailable) are currently available. + * {@link #EXTRA_CHANGED_UID_LIST} is the set of uids of the + * packages whose resources(were previously unavailable) + * are currently available. + * </ul> + * + * <p class="note">This is a protected intent that can only be sent + * by the system. + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_MEDIA_RESOURCES_AVAILABLE = + "android.intent.action.MEDIA_RESOURCES_AVAILABILE"; + + /** + * Broadcast Action: Resources for a set of packages are currently + * unavailable since the media on which they exist is unavailable. + * The extra data {@link #EXTRA_CHANGED_PACKAGE_LIST} contains a + * list of packages whose availability changed. + * The extra data {@link #EXTRA_CHANGED_UID_LIST} contains a + * list of uids of packages whose availability changed. + * The specified set of packages can no longer be + * launched and are practically unavailable on the system. + * <p>Inclues the following extras: + * <ul> + * <li> {@link #EXTRA_CHANGED_PACKAGE_LIST} is the set of packages + * whose resources are no longer available. + * {@link #EXTRA_CHANGED_UID_LIST} is the set of packages + * whose resources are no longer available. + * </ul> + * + * <p class="note">This is a protected intent that can only be sent + * by the system. + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_MEDIA_RESOURCES_UNAVAILABLE = + "android.intent.action.MEDIA_RESOURCES_UNAVAILABILE"; + /** * Broadcast Action: The current system wallpaper has changed. See * {@link android.app.WallpaperManager} for retrieving the new wallpaper. @@ -2136,13 +2190,34 @@ public class Intent implements Parcelable, Cloneable { "android.intent.extra.changed_component_name"; /** - * This field is part of {@link android.content.Intent#ACTION_PACKAGE_CHANGED} + * This field is part of {@link android.content.Intent#ACTION_PACKAGE_CHANGED}, * and contains a string array of all of the components that have changed. */ public static final String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list"; /** + * This field is part of + * {@link android.content.Intent#ACTION_MEDIA_RESOURCES_AVAILABLE}, + * {@link android.content.Intent#ACTION_MEDIA_RESOURCES_UNAVAILABLE} + * and contains a string array of all of the components that have changed. + * @hide + */ + public static final String EXTRA_CHANGED_PACKAGE_LIST = + "android.intent.extra.changed_package_list"; + + /** + * This field is part of + * {@link android.content.Intent#ACTION_MEDIA_RESOURCES_AVAILABLE}, + * {@link android.content.Intent#ACTION_MEDIA_RESOURCES_UNAVAILABLE} + * and contains an integer array of uids of all of the components + * that have changed. + * @hide + */ + public static final String EXTRA_CHANGED_UID_LIST = + "android.intent.extra.changed_uid_list"; + + /** * @hide * Magic extra system code can use when binding, to give a label for * who it is that has bound to a service. This is an integer giving diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index b819fa0..7362394 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -115,6 +115,11 @@ public abstract class RegisteredServicesCache<V> { intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); mContext.registerReceiver(receiver, intentFilter); + // Register for events related to sdcard installation. + IntentFilter sdFilter = new IntentFilter(); + sdFilter.addAction(Intent.ACTION_MEDIA_RESOURCES_AVAILABLE); + sdFilter.addAction(Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE); + mContext.registerReceiver(receiver, sdFilter); } public void dump(FileDescriptor fd, PrintWriter fout, String[] args) { diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java index 9953b56..324fbaa 100644 --- a/core/java/android/server/search/SearchManagerService.java +++ b/core/java/android/server/search/SearchManagerService.java @@ -73,6 +73,11 @@ public class SearchManagerService extends ISearchManager.Stub { packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); packageFilter.addDataScheme("package"); mContext.registerReceiver(mPackageChangedReceiver, packageFilter); + // Register for events related to sdcard installation. + IntentFilter sdFilter = new IntentFilter(); + sdFilter.addAction(Intent.ACTION_MEDIA_RESOURCES_AVAILABLE); + sdFilter.addAction(Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE); + mContext.registerReceiver(mPackageChangedReceiver, sdFilter); } private synchronized Searchables getSearchables() { @@ -90,7 +95,9 @@ public class SearchManagerService extends ISearchManager.Stub { if (Intent.ACTION_PACKAGE_ADDED.equals(action) || Intent.ACTION_PACKAGE_REMOVED.equals(action) || - Intent.ACTION_PACKAGE_CHANGED.equals(action)) { + Intent.ACTION_PACKAGE_CHANGED.equals(action) || + Intent.ACTION_MEDIA_RESOURCES_AVAILABLE.equals(action) || + Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE.equals(action)) { if (DBG) Log.d(TAG, "Got " + action); // Update list of searchable activities getSearchables().buildSearchableList(); |