diff options
4 files changed, 52 insertions, 33 deletions
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index a35b57d9f0d5..b043d13f9da0 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -856,38 +856,42 @@ final class InstallPackageHelper { if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); final boolean succeeded = request.getReturnCode() == PackageManager.INSTALL_SUCCEEDED; - if (succeeded && doRestore) { - // Pass responsibility to the Backup Manager. It will perform a - // restore if appropriate, then pass responsibility back to the - // Package Manager to run the post-install observer callbacks - // and broadcasts. - doRestore = performBackupManagerRestore(userId, token, request); - } - - // If this is an update to a package that might be potentially downgraded, then we - // need to check with the rollback manager whether there's any userdata that might - // need to be snapshotted or restored for the package. - // - // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL. - if (succeeded && !doRestore && update) { - doRestore = performRollbackManagerRestore(userId, token, request); - } - - if (succeeded && doRestore && !request.hasPostInstallRunnable()) { - boolean hasNeverBeenRestored = - packageSetting != null && packageSetting.isPendingRestore(); - request.setPostInstallRunnable(() -> { - // Permissions should be restored on each user that has the app installed for the - // first time, unless it's an unarchive install for an archived app, in which case - // the permissions should be restored on each user that has the app updated. - int[] userIdsToRestorePermissions = hasNeverBeenRestored - ? request.getUpdateBroadcastUserIds() - : request.getFirstTimeBroadcastUserIds(); - for (int restorePermissionUserId : userIdsToRestorePermissions) { - mPm.restorePermissionsAndUpdateRolesForNewUserInstall(request.getName(), - restorePermissionUserId); - } - }); + if (succeeded) { + request.onRestoreStarted(); + if (doRestore) { + // Pass responsibility to the Backup Manager. It will perform a + // restore if appropriate, then pass responsibility back to the + // Package Manager to run the post-install observer callbacks + // and broadcasts. + doRestore = performBackupManagerRestore(userId, token, request); + } + + // If this is an update to a package that might be potentially downgraded, then we + // need to check with the rollback manager whether there's any userdata that might + // need to be snapshotted or restored for the package. + // + // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL. + if (!doRestore && update) { + doRestore = performRollbackManagerRestore(userId, token, request); + } + + if (doRestore && !request.hasPostInstallRunnable()) { + boolean hasNeverBeenRestored = + packageSetting != null && packageSetting.isPendingRestore(); + request.setPostInstallRunnable(() -> { + // Permissions should be restored on each user that has the app installed for + // the first time, unless it's an unarchive install for an archived app, in + // which case the permissions should be restored on each user that has the + // app updated. + int[] userIdsToRestorePermissions = hasNeverBeenRestored + ? request.getUpdateBroadcastUserIds() + : request.getFirstTimeBroadcastUserIds(); + for (int restorePermissionUserId : userIdsToRestorePermissions) { + mPm.restorePermissionsAndUpdateRolesForNewUserInstall(request.getName(), + restorePermissionUserId); + } + }); + } } if (doRestore) { diff --git a/services/core/java/com/android/server/pm/InstallRequest.java b/services/core/java/com/android/server/pm/InstallRequest.java index c96c160deb0f..fbf5db5d9635 100644 --- a/services/core/java/com/android/server/pm/InstallRequest.java +++ b/services/core/java/com/android/server/pm/InstallRequest.java @@ -1016,6 +1016,18 @@ final class InstallRequest { } } + public void onRestoreStarted() { + if (mPackageMetrics != null) { + mPackageMetrics.onStepStarted(PackageMetrics.STEP_RESTORE); + } + } + + public void onRestoreFinished() { + if (mPackageMetrics != null) { + mPackageMetrics.onStepFinished(PackageMetrics.STEP_RESTORE); + } + } + public void onDexoptFinished(DexoptResult dexoptResult) { // Only report external profile warnings when installing from adb. The goal is to warn app // developers if they have provided bad external profiles, so it's not beneficial to report diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java index 9916be680374..7b1eb58d25f4 100644 --- a/services/core/java/com/android/server/pm/PackageHandler.java +++ b/services/core/java/com/android/server/pm/PackageHandler.java @@ -99,6 +99,7 @@ final class PackageHandler extends Handler { } break; } + request.onRestoreFinished(); request.closeFreezer(); request.onInstallCompleted(); request.runPostInstallRunnable(); diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java index 856d6a726da5..994ee421790c 100644 --- a/services/core/java/com/android/server/pm/PackageMetrics.java +++ b/services/core/java/com/android/server/pm/PackageMetrics.java @@ -72,6 +72,7 @@ final class PackageMetrics { public static final int STEP_COMMIT = 4; public static final int STEP_DEXOPT = 5; public static final int STEP_FREEZE_INSTALL = 6; + public static final int STEP_RESTORE = 7; @IntDef(prefix = {"STEP_"}, value = { STEP_PREPARE, @@ -79,7 +80,8 @@ final class PackageMetrics { STEP_RECONCILE, STEP_COMMIT, STEP_DEXOPT, - STEP_FREEZE_INSTALL + STEP_FREEZE_INSTALL, + STEP_RESTORE }) @Retention(RetentionPolicy.SOURCE) public @interface StepInt { |