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.
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index ef184d2..0562c55 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -529,6 +529,11 @@
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addDataScheme("package");
mContext.registerReceiver(mBroadcastReceiver, filter);
+ // 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(mBroadcastReceiver, sdFilter);
}
private void parseLeftoverJournals() {
@@ -665,35 +670,53 @@
public void onReceive(Context context, Intent intent) {
if (DEBUG) Log.d(TAG, "Received broadcast " + intent);
- Uri uri = intent.getData();
- if (uri == null) {
- return;
- }
- String pkgName = uri.getSchemeSpecificPart();
- if (pkgName == null) {
- return;
- }
-
String action = intent.getAction();
- if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+ boolean replacing = false;
+ boolean added = false;
+ Bundle extras = intent.getExtras();
+ String pkgList[] = null;
+ if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
+ Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+ Uri uri = intent.getData();
+ if (uri == null) {
+ return;
+ }
+ String pkgName = uri.getSchemeSpecificPart();
+ if (pkgName != null) {
+ pkgList = new String[] { pkgName };
+ }
+ added = Intent.ACTION_PACKAGE_ADDED.equals(action);
+ replacing = extras.getBoolean(Intent.EXTRA_REPLACING, false);
+ } else if (Intent.ACTION_MEDIA_RESOURCES_AVAILABLE.equals(action)) {
+ added = true;
+ pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+ } else if (Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE.equals(action)) {
+ added = false;
+ pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+ }
+ if (pkgList == null || pkgList.length == 0) {
+ return;
+ }
+ if (added) {
synchronized (mBackupParticipants) {
- Bundle extras = intent.getExtras();
- if (extras != null && extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
- // The package was just upgraded
- updatePackageParticipantsLocked(pkgName);
- } else {
- // The package was just added
- addPackageParticipantsLocked(pkgName);
+ for (String pkgName : pkgList) {
+ if (replacing) {
+ // The package was just upgraded
+ updatePackageParticipantsLocked(pkgName);
+ } else {
+ // The package was just added
+ addPackageParticipantsLocked(pkgName);
+ }
}
}
- }
- else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
- Bundle extras = intent.getExtras();
- if (extras != null && extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
+ } else {
+ if (replacing) {
// The package is being updated. We'll receive a PACKAGE_ADDED shortly.
} else {
synchronized (mBackupParticipants) {
- removePackageParticipantsLocked(pkgName);
+ for (String pkgName : pkgList) {
+ removePackageParticipantsLocked(pkgName);
+ }
}
}
}