From 4e55418864390dbdd763d8d794bc46dc69f2913d Mon Sep 17 00:00:00 2001 From: Carmen Agimof Date: Wed, 20 Nov 2019 15:11:06 +0000 Subject: [PATCH] Do not try to do a restore at install if the user is not ready for backup. Bug: 144155744 This solves a bug which makes staged installs hang. This is happening because when installing, the PackageManager is waiting for a response to be sent back from the BackupManagerService after it finishes restoring. In the case of staged installs which happen at boot, isUserReadyForBackup is false, so the method does nothing and the PackageManager keeps on waiting on a response. Test: 1) atest RunBackupFrameworksServicesRoboTests and atest AutoRestoreHostSideTest 2) Manual: - Applied ag/9722795 - run `atest com.android.tests.rollback.host.StagedRollbackTest#testStagedInstallHang` - The log file doesn't contain any "Watchdog: *** WATCHDOG KILLING SYSTEM PROCESS: Blocked in handler on main thread (main)". Change-Id: I294c309b0c7e5a9e12bdbd0c3fc4946767f91cee --- core/java/android/app/backup/IBackupManager.aidl | 6 ++++++ .../android/server/backup/BackupManagerService.java | 11 ++++++++--- .../com/android/server/pm/PackageManagerService.java | 4 +++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl index 099272d8e3ec0..4940976133c5b 100644 --- a/core/java/android/app/backup/IBackupManager.aidl +++ b/core/java/android/app/backup/IBackupManager.aidl @@ -596,6 +596,12 @@ interface IBackupManager { @UnsupportedAppUsage boolean isBackupServiceActive(int whichUser); + /** + * Checks if the user is ready for backup or not. + * @param userId User id for which this operation should be performed. + */ + boolean isUserReadyForBackup(int userId); + /** * Ask the framework which dataset, if any, the given package's data would be * restored from if we were to install it right now. diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index e8c5299f47a38..3651a41439535 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -274,9 +274,14 @@ public class BackupManagerService extends IBackupManager.Stub { } } - // This method should not perform any I/O (e.g. do not call isBackupActivatedForUser), - // it's used in multiple places where I/O waits would cause system lock-ups. - private boolean isUserReadyForBackup(int userId) { + /** + * This method should not perform any I/O (e.g. do not call isBackupActivatedForUser), + * it's used in multiple places where I/O waits would cause system lock-ups. + * @param userId User id for which this operation should be performed. + * @return true if the user is ready for backup and false otherwise. + */ + @Override + public boolean isUserReadyForBackup(int userId) { return mUserServices.get(UserHandle.USER_SYSTEM) != null && mUserServices.get(userId) != null; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 4711ec00dcadb..53aa87993620c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -13483,10 +13483,12 @@ public class PackageManagerService extends IPackageManager.Stub } Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); try { - if (bm.isBackupServiceActive(userId)) { + if (bm.isUserReadyForBackup(userId)) { bm.restoreAtInstallForUser( userId, res.pkg.getAppInfoPackageName(), token); } else { + Slog.w(TAG, "User " + userId + " is not ready. Restore at install " + + "didn't take place."); return false; } } catch (RemoteException e) {