diff options
author | Christopher Tate <ctate@google.com> | 2012-01-11 14:41:19 -0800 |
---|---|---|
committer | Christopher Tate <ctate@google.com> | 2012-01-12 16:15:09 -0800 |
commit | 0bacfd2ba68d21a68a3df345b830bc2a1e515b5a (patch) | |
tree | 4ba0f1c83b94a9dfe2df611cb83f10c346e00cab /services/java/com | |
parent | 51938e26913a98aa8de0292e9be8ea9d9ebc67c3 (diff) | |
download | frameworks_base-0bacfd2ba68d21a68a3df345b830bc2a1e515b5a.zip frameworks_base-0bacfd2ba68d21a68a3df345b830bc2a1e515b5a.tar.gz frameworks_base-0bacfd2ba68d21a68a3df345b830bc2a1e515b5a.tar.bz2 |
Streamline package-installed handling by the Backup Manager
In particular, don't do O(asec_apps * installed_apps) work during the
broadcast receiver's operation. On devices with many installed apps
and a large number of them moved to ASECs, this was causing the system
process to become unresponsive and the watchdog to fire -- which in turn
would initiate a restart loop, as the same package-installed broadcast
would then be issued again once the package manager rescanned the ASEC
containers, ad infinitum. With this change, the expensive call to the
package manager is only made once rather than asec_apps times.
Bug 5850283
Change-Id: I14e280ea1fa6af19cebc58869a20fbb599c92c8c
Diffstat (limited to 'services/java/com')
-rw-r--r-- | services/java/com/android/server/BackupManagerService.java | 112 |
1 files changed, 55 insertions, 57 deletions
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 4ef8837..4d5e0a6 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -195,7 +195,7 @@ class BackupManagerService extends IBackupManager.Stub { boolean mProvisioned; boolean mAutoRestore; PowerManager.WakeLock mWakelock; - HandlerThread mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND); + HandlerThread mHandlerThread; BackupHandler mBackupHandler; PendingIntent mRunBackupIntent, mRunInitIntent; BroadcastReceiver mRunBackupReceiver, mRunInitReceiver; @@ -1310,14 +1310,10 @@ class BackupManagerService extends IBackupManager.Stub { } if (added) { synchronized (mBackupParticipants) { - for (String pkgName : pkgList) { - if (replacing) { - // The package was just upgraded - updatePackageParticipantsLocked(pkgName); - } else { - // The package was just added - addPackageParticipantsLocked(pkgName); - } + if (replacing) { + updatePackageParticipantsLocked(pkgList); + } else { + addPackageParticipantsLocked(pkgList); } } } else { @@ -1325,9 +1321,7 @@ class BackupManagerService extends IBackupManager.Stub { // The package is being updated. We'll receive a PACKAGE_ADDED shortly. } else { synchronized (mBackupParticipants) { - for (String pkgName : pkgList) { - removePackageParticipantsLocked(pkgName); - } + removePackageParticipantsLocked(pkgList); } } } @@ -1349,26 +1343,26 @@ class BackupManagerService extends IBackupManager.Stub { } }; - // Add the backup agents in the given package to our set of known backup participants. - // If 'packageName' is null, adds all backup agents in the whole system. - void addPackageParticipantsLocked(String packageName) { + // Add the backup agents in the given packages to our set of known backup participants. + // If 'packageNames' is null, adds all backup agents in the whole system. + void addPackageParticipantsLocked(String[] packageNames) { // Look for apps that define the android:backupAgent attribute - if (DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: " + packageName); List<PackageInfo> targetApps = allAgentPackages(); - addPackageParticipantsLockedInner(packageName, targetApps); + if (packageNames != null) { + if (DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: #" + packageNames.length); + for (String packageName : packageNames) { + addPackageParticipantsLockedInner(packageName, targetApps); + } + } else { + if (DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: all"); + addPackageParticipantsLockedInner(null, targetApps); + } } private void addPackageParticipantsLockedInner(String packageName, List<PackageInfo> targetPkgs) { if (MORE_DEBUG) { - Slog.v(TAG, "Adding " + targetPkgs.size() + " backup participants:"); - for (PackageInfo p : targetPkgs) { - Slog.v(TAG, " " + p + " agent=" + p.applicationInfo.backupAgentName - + " uid=" + p.applicationInfo.uid - + " killAfterRestore=" - + (((p.applicationInfo.flags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0) ? "true" : "false") - ); - } + Slog.v(TAG, "Examining " + packageName + " for backup agent"); } for (PackageInfo pkg : targetPkgs) { @@ -1380,6 +1374,7 @@ class BackupManagerService extends IBackupManager.Stub { mBackupParticipants.put(uid, set); } set.add(pkg.applicationInfo); + if (MORE_DEBUG) Slog.v(TAG, "Agent found; added"); // If we've never seen this app before, schedule a backup for it if (!mEverStoredApps.contains(pkg.packageName)) { @@ -1391,34 +1386,32 @@ class BackupManagerService extends IBackupManager.Stub { } } - // Remove the given package's entry from our known active set. If - // 'packageName' is null, *all* participating apps will be removed. - void removePackageParticipantsLocked(String packageName) { - if (DEBUG) Slog.v(TAG, "removePackageParticipantsLocked: " + packageName); - List<String> allApps = new ArrayList<String>(); - if (packageName != null) { - allApps.add(packageName); - } else { - // all apps with agents - List<PackageInfo> knownPackages = allAgentPackages(); - for (PackageInfo pkg : knownPackages) { - allApps.add(pkg.packageName); - } + // Remove the given packages' entries from our known active set. + void removePackageParticipantsLocked(String[] packageNames) { + if (packageNames == null) { + Slog.w(TAG, "removePackageParticipants with null list"); + return; + } + + if (DEBUG) Slog.v(TAG, "removePackageParticipantsLocked: #" + packageNames.length); + List<PackageInfo> knownPackages = allAgentPackages(); + for (String pkg : packageNames) { + removePackageParticipantsLockedInner(pkg, knownPackages); } - removePackageParticipantsLockedInner(packageName, allApps); } private void removePackageParticipantsLockedInner(String packageName, - List<String> allPackageNames) { + List<PackageInfo> allPackages) { if (MORE_DEBUG) { Slog.v(TAG, "removePackageParticipantsLockedInner (" + packageName - + ") removing " + allPackageNames.size() + " entries"); - for (String p : allPackageNames) { - Slog.v(TAG, " - " + p); + + ") removing from " + allPackages.size() + " entries"); + for (PackageInfo p : allPackages) { + Slog.v(TAG, " - " + p.packageName); } } - for (String pkg : allPackageNames) { - if (packageName == null || pkg.equals(packageName)) { + for (PackageInfo pkg : allPackages) { + if (packageName == null || pkg.packageName.equals(packageName)) { + /* int uid = -1; try { PackageInfo info = mPackageManager.getPackageInfo(packageName, 0); @@ -1427,22 +1420,28 @@ class BackupManagerService extends IBackupManager.Stub { // we don't know this package name, so just skip it for now continue; } + */ + final int uid = pkg.applicationInfo.uid; + if (MORE_DEBUG) Slog.i(TAG, " found pkg " + packageName + " uid=" + uid); HashSet<ApplicationInfo> set = mBackupParticipants.get(uid); if (set != null) { // Find the existing entry with the same package name, and remove it. // We can't just remove(app) because the instances are different. for (ApplicationInfo entry: set) { + if (MORE_DEBUG) Slog.i(TAG, " checking against " + entry.packageName); if (entry.packageName.equals(pkg)) { if (MORE_DEBUG) Slog.v(TAG, " removing participant " + pkg); set.remove(entry); - removeEverBackedUp(pkg); + removeEverBackedUp(pkg.packageName); break; } } if (set.size() == 0) { mBackupParticipants.delete(uid); } + } else { + if (MORE_DEBUG) Slog.i(TAG, " ... not found in uid mapping"); } } } @@ -1477,21 +1476,20 @@ class BackupManagerService extends IBackupManager.Stub { // Reset the given package's known backup participants. Unlike add/remove, the update // action cannot be passed a null package name. - void updatePackageParticipantsLocked(String packageName) { - if (packageName == null) { - Slog.e(TAG, "updatePackageParticipants called with null package name"); + void updatePackageParticipantsLocked(String[] packageNames) { + if (packageNames == null) { + Slog.e(TAG, "updatePackageParticipants called with null package list"); return; } - if (DEBUG) Slog.v(TAG, "updatePackageParticipantsLocked: " + packageName); + if (DEBUG) Slog.v(TAG, "updatePackageParticipantsLocked: #" + packageNames.length); - // brute force but small code size - List<PackageInfo> allApps = allAgentPackages(); - List<String> allAppNames = new ArrayList<String>(); - for (PackageInfo pkg : allApps) { - allAppNames.add(pkg.packageName); + if (packageNames.length > 0) { + List<PackageInfo> allApps = allAgentPackages(); + for (String packageName : packageNames) { + removePackageParticipantsLockedInner(packageName, allApps); + addPackageParticipantsLockedInner(packageName, allApps); + } } - removePackageParticipantsLockedInner(packageName, allAppNames); - addPackageParticipantsLockedInner(packageName, allApps); } // Called from the backup task: record that the given app has been successfully |