Skip to content

Commit 0bacfd2

Browse files
author
Christopher Tate
committed
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
1 parent 51938e2 commit 0bacfd2

File tree

1 file changed

+55
-57
lines changed

1 file changed

+55
-57
lines changed

services/java/com/android/server/BackupManagerService.java

Lines changed: 55 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ class BackupManagerService extends IBackupManager.Stub {
195195
boolean mProvisioned;
196196
boolean mAutoRestore;
197197
PowerManager.WakeLock mWakelock;
198-
HandlerThread mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND);
198+
HandlerThread mHandlerThread;
199199
BackupHandler mBackupHandler;
200200
PendingIntent mRunBackupIntent, mRunInitIntent;
201201
BroadcastReceiver mRunBackupReceiver, mRunInitReceiver;
@@ -1310,24 +1310,18 @@ public void onReceive(Context context, Intent intent) {
13101310
}
13111311
if (added) {
13121312
synchronized (mBackupParticipants) {
1313-
for (String pkgName : pkgList) {
1314-
if (replacing) {
1315-
// The package was just upgraded
1316-
updatePackageParticipantsLocked(pkgName);
1317-
} else {
1318-
// The package was just added
1319-
addPackageParticipantsLocked(pkgName);
1320-
}
1313+
if (replacing) {
1314+
updatePackageParticipantsLocked(pkgList);
1315+
} else {
1316+
addPackageParticipantsLocked(pkgList);
13211317
}
13221318
}
13231319
} else {
13241320
if (replacing) {
13251321
// The package is being updated. We'll receive a PACKAGE_ADDED shortly.
13261322
} else {
13271323
synchronized (mBackupParticipants) {
1328-
for (String pkgName : pkgList) {
1329-
removePackageParticipantsLocked(pkgName);
1330-
}
1324+
removePackageParticipantsLocked(pkgList);
13311325
}
13321326
}
13331327
}
@@ -1349,26 +1343,26 @@ public void onServiceDisconnected(ComponentName name) {
13491343
}
13501344
};
13511345

1352-
// Add the backup agents in the given package to our set of known backup participants.
1353-
// If 'packageName' is null, adds all backup agents in the whole system.
1354-
void addPackageParticipantsLocked(String packageName) {
1346+
// Add the backup agents in the given packages to our set of known backup participants.
1347+
// If 'packageNames' is null, adds all backup agents in the whole system.
1348+
void addPackageParticipantsLocked(String[] packageNames) {
13551349
// Look for apps that define the android:backupAgent attribute
1356-
if (DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: " + packageName);
13571350
List<PackageInfo> targetApps = allAgentPackages();
1358-
addPackageParticipantsLockedInner(packageName, targetApps);
1351+
if (packageNames != null) {
1352+
if (DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: #" + packageNames.length);
1353+
for (String packageName : packageNames) {
1354+
addPackageParticipantsLockedInner(packageName, targetApps);
1355+
}
1356+
} else {
1357+
if (DEBUG) Slog.v(TAG, "addPackageParticipantsLocked: all");
1358+
addPackageParticipantsLockedInner(null, targetApps);
1359+
}
13591360
}
13601361

13611362
private void addPackageParticipantsLockedInner(String packageName,
13621363
List<PackageInfo> targetPkgs) {
13631364
if (MORE_DEBUG) {
1364-
Slog.v(TAG, "Adding " + targetPkgs.size() + " backup participants:");
1365-
for (PackageInfo p : targetPkgs) {
1366-
Slog.v(TAG, " " + p + " agent=" + p.applicationInfo.backupAgentName
1367-
+ " uid=" + p.applicationInfo.uid
1368-
+ " killAfterRestore="
1369-
+ (((p.applicationInfo.flags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0) ? "true" : "false")
1370-
);
1371-
}
1365+
Slog.v(TAG, "Examining " + packageName + " for backup agent");
13721366
}
13731367

13741368
for (PackageInfo pkg : targetPkgs) {
@@ -1380,6 +1374,7 @@ private void addPackageParticipantsLockedInner(String packageName,
13801374
mBackupParticipants.put(uid, set);
13811375
}
13821376
set.add(pkg.applicationInfo);
1377+
if (MORE_DEBUG) Slog.v(TAG, "Agent found; added");
13831378

13841379
// If we've never seen this app before, schedule a backup for it
13851380
if (!mEverStoredApps.contains(pkg.packageName)) {
@@ -1391,34 +1386,32 @@ private void addPackageParticipantsLockedInner(String packageName,
13911386
}
13921387
}
13931388

1394-
// Remove the given package's entry from our known active set. If
1395-
// 'packageName' is null, *all* participating apps will be removed.
1396-
void removePackageParticipantsLocked(String packageName) {
1397-
if (DEBUG) Slog.v(TAG, "removePackageParticipantsLocked: " + packageName);
1398-
List<String> allApps = new ArrayList<String>();
1399-
if (packageName != null) {
1400-
allApps.add(packageName);
1401-
} else {
1402-
// all apps with agents
1403-
List<PackageInfo> knownPackages = allAgentPackages();
1404-
for (PackageInfo pkg : knownPackages) {
1405-
allApps.add(pkg.packageName);
1406-
}
1389+
// Remove the given packages' entries from our known active set.
1390+
void removePackageParticipantsLocked(String[] packageNames) {
1391+
if (packageNames == null) {
1392+
Slog.w(TAG, "removePackageParticipants with null list");
1393+
return;
1394+
}
1395+
1396+
if (DEBUG) Slog.v(TAG, "removePackageParticipantsLocked: #" + packageNames.length);
1397+
List<PackageInfo> knownPackages = allAgentPackages();
1398+
for (String pkg : packageNames) {
1399+
removePackageParticipantsLockedInner(pkg, knownPackages);
14071400
}
1408-
removePackageParticipantsLockedInner(packageName, allApps);
14091401
}
14101402

14111403
private void removePackageParticipantsLockedInner(String packageName,
1412-
List<String> allPackageNames) {
1404+
List<PackageInfo> allPackages) {
14131405
if (MORE_DEBUG) {
14141406
Slog.v(TAG, "removePackageParticipantsLockedInner (" + packageName
1415-
+ ") removing " + allPackageNames.size() + " entries");
1416-
for (String p : allPackageNames) {
1417-
Slog.v(TAG, " - " + p);
1407+
+ ") removing from " + allPackages.size() + " entries");
1408+
for (PackageInfo p : allPackages) {
1409+
Slog.v(TAG, " - " + p.packageName);
14181410
}
14191411
}
1420-
for (String pkg : allPackageNames) {
1421-
if (packageName == null || pkg.equals(packageName)) {
1412+
for (PackageInfo pkg : allPackages) {
1413+
if (packageName == null || pkg.packageName.equals(packageName)) {
1414+
/*
14221415
int uid = -1;
14231416
try {
14241417
PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
@@ -1427,22 +1420,28 @@ private void removePackageParticipantsLockedInner(String packageName,
14271420
// we don't know this package name, so just skip it for now
14281421
continue;
14291422
}
1423+
*/
1424+
final int uid = pkg.applicationInfo.uid;
1425+
if (MORE_DEBUG) Slog.i(TAG, " found pkg " + packageName + " uid=" + uid);
14301426

14311427
HashSet<ApplicationInfo> set = mBackupParticipants.get(uid);
14321428
if (set != null) {
14331429
// Find the existing entry with the same package name, and remove it.
14341430
// We can't just remove(app) because the instances are different.
14351431
for (ApplicationInfo entry: set) {
1432+
if (MORE_DEBUG) Slog.i(TAG, " checking against " + entry.packageName);
14361433
if (entry.packageName.equals(pkg)) {
14371434
if (MORE_DEBUG) Slog.v(TAG, " removing participant " + pkg);
14381435
set.remove(entry);
1439-
removeEverBackedUp(pkg);
1436+
removeEverBackedUp(pkg.packageName);
14401437
break;
14411438
}
14421439
}
14431440
if (set.size() == 0) {
14441441
mBackupParticipants.delete(uid);
14451442
}
1443+
} else {
1444+
if (MORE_DEBUG) Slog.i(TAG, " ... not found in uid mapping");
14461445
}
14471446
}
14481447
}
@@ -1477,21 +1476,20 @@ List<PackageInfo> allAgentPackages() {
14771476

14781477
// Reset the given package's known backup participants. Unlike add/remove, the update
14791478
// action cannot be passed a null package name.
1480-
void updatePackageParticipantsLocked(String packageName) {
1481-
if (packageName == null) {
1482-
Slog.e(TAG, "updatePackageParticipants called with null package name");
1479+
void updatePackageParticipantsLocked(String[] packageNames) {
1480+
if (packageNames == null) {
1481+
Slog.e(TAG, "updatePackageParticipants called with null package list");
14831482
return;
14841483
}
1485-
if (DEBUG) Slog.v(TAG, "updatePackageParticipantsLocked: " + packageName);
1484+
if (DEBUG) Slog.v(TAG, "updatePackageParticipantsLocked: #" + packageNames.length);
14861485

1487-
// brute force but small code size
1488-
List<PackageInfo> allApps = allAgentPackages();
1489-
List<String> allAppNames = new ArrayList<String>();
1490-
for (PackageInfo pkg : allApps) {
1491-
allAppNames.add(pkg.packageName);
1486+
if (packageNames.length > 0) {
1487+
List<PackageInfo> allApps = allAgentPackages();
1488+
for (String packageName : packageNames) {
1489+
removePackageParticipantsLockedInner(packageName, allApps);
1490+
addPackageParticipantsLockedInner(packageName, allApps);
1491+
}
14921492
}
1493-
removePackageParticipantsLockedInner(packageName, allAppNames);
1494-
addPackageParticipantsLockedInner(packageName, allApps);
14951493
}
14961494

14971495
// Called from the backup task: record that the given app has been successfully

0 commit comments

Comments
 (0)