Loading services/core/java/com/android/server/RescueParty.java +275 −159 Original line number Diff line number Diff line Loading @@ -241,6 +241,7 @@ public class RescueParty { * opportunity to reset any settings depending on our rescue level. */ public static void onSettingsProviderPublished(Context context) { if (!Flags.deprecateFlagsAndSettingsResets()) { handleNativeRescuePartyResets(); ContentResolver contentResolver = context.getContentResolver(); DeviceConfig.setMonitorCallback( Loading @@ -248,6 +249,7 @@ public class RescueParty { Executors.newSingleThreadExecutor(), new RescuePartyMonitorCallback(context)); } } /** Loading @@ -256,6 +258,7 @@ public class RescueParty { * on modules of newer versions. */ public static void resetDeviceConfigForPackages(List<String> packageNames) { if (!Flags.deprecateFlagsAndSettingsResets()) { if (packageNames == null) { return; } Loading Loading @@ -299,9 +302,11 @@ public class RescueParty { } } } } private static Set<String> getPresetNamespacesForPackages(List<String> packageNames) { Set<String> resultSet = new ArraySet<String>(); if (!Flags.deprecateFlagsAndSettingsResets()) { try { String flagVal = DeviceConfig.getString(NAMESPACE_CONFIGURATION, NAMESPACE_TO_PACKAGE_MAPPING_FLAG, ""); Loading @@ -310,12 +315,12 @@ public class RescueParty { if (TextUtils.isEmpty(mappingEntries[i])) { continue; } String[] splittedEntry = mappingEntries[i].split(":"); if (splittedEntry.length != 2) { String[] splitEntry = mappingEntries[i].split(":"); if (splitEntry.length != 2) { throw new RuntimeException("Invalid mapping entry: " + mappingEntries[i]); } String namespace = splittedEntry[0]; String packageName = splittedEntry[1]; String namespace = splitEntry[0]; String packageName = splitEntry[1]; if (packageNames.contains(packageName)) { resultSet.add(namespace); Loading @@ -327,6 +332,9 @@ public class RescueParty { } finally { return resultSet; } } else { return resultSet; } } @VisibleForTesting Loading @@ -342,20 +350,27 @@ public class RescueParty { } public void onNamespaceUpdate(@NonNull String updatedNamespace) { if (!Flags.deprecateFlagsAndSettingsResets()) { startObservingPackages(mContext, updatedNamespace); } } public void onDeviceConfigAccess(@NonNull String callingPackage, @NonNull String namespace) { if (!Flags.deprecateFlagsAndSettingsResets()) { RescuePartyObserver.getInstance(mContext).recordDeviceConfigAccess( callingPackage, namespace); } } } private static void startObservingPackages(Context context, @NonNull String updatedNamespace) { if (!Flags.deprecateFlagsAndSettingsResets()) { RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context); Set<String> callingPackages = rescuePartyObserver.getCallingPackagesSet(updatedNamespace); Set<String> callingPackages = rescuePartyObserver.getCallingPackagesSet( updatedNamespace); if (callingPackages == null) { return; } Loading @@ -368,10 +383,13 @@ public class RescueParty { callingPackageList, DEFAULT_OBSERVING_DURATION_MS); } } private static void handleNativeRescuePartyResets() { if (!Flags.deprecateFlagsAndSettingsResets()) { if (SettingsToPropertiesMapper.isNativeFlagsResetPerformed()) { String[] resetNativeCategories = SettingsToPropertiesMapper.getResetNativeCategories(); String[] resetNativeCategories = SettingsToPropertiesMapper.getResetNativeCategories(); for (int i = 0; i < resetNativeCategories.length; i++) { // Don't let RescueParty reset the namespace for RescueParty switches. if (NAMESPACE_CONFIGURATION.equals(resetNativeCategories[i])) { Loading @@ -382,6 +400,7 @@ public class RescueParty { } } } } private static int getMaxRescueLevel(boolean mayPerformReboot) { if (Flags.recoverabilityDetection()) { Loading @@ -400,6 +419,13 @@ public class RescueParty { } } private static int getMaxRescueLevel() { if (!SystemProperties.getBoolean(PROP_DISABLE_FACTORY_RESET_FLAG, false)) { return Level.factoryReset(); } return Level.reboot(); } /** * Get the rescue level to perform if this is the n-th attempt at mitigating failure. * Loading @@ -409,6 +435,7 @@ public class RescueParty { * @return the rescue level for the n-th mitigation attempt. */ private static int getRescueLevel(int mitigationCount, boolean mayPerformReboot) { if (!Flags.deprecateFlagsAndSettingsResets()) { if (mitigationCount == 1) { return LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS; } else if (mitigationCount == 2) { Loading @@ -423,6 +450,16 @@ public class RescueParty { Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount); return LEVEL_NONE; } } else { if (mitigationCount == 1) { return Level.reboot(); } else if (mitigationCount >= 2) { return Math.min(getMaxRescueLevel(), Level.factoryReset()); } else { Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount); return LEVEL_NONE; } } } /** Loading Loading @@ -465,6 +502,22 @@ public class RescueParty { } } /** * Get the rescue level to perform if this is the n-th attempt at mitigating failure. * * @param mitigationCount the mitigation attempt number (1 = first attempt etc.). * @return the rescue level for the n-th mitigation attempt. */ private static @RescueLevels int getRescueLevel(int mitigationCount) { if (mitigationCount == 1) { return Level.reboot(); } else if (mitigationCount >= 2) { return Math.min(getMaxRescueLevel(), Level.factoryReset()); } else { return Level.none(); } } private static void executeRescueLevel(Context context, @Nullable String failedPackage, int level) { Slog.w(TAG, "Attempting rescue level " + levelToString(level)); Loading Loading @@ -537,13 +590,22 @@ public class RescueParty { executeWarmReboot(context, level, failedPackage); break; case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS: resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS, level); if (!Flags.deprecateFlagsAndSettingsResets()) { resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS, level); } break; case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES: resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES, level); if (!Flags.deprecateFlagsAndSettingsResets()) { resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES, level); } break; case RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS: resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS, level); if (!Flags.deprecateFlagsAndSettingsResets()) { resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS, level); } break; case RESCUE_LEVEL_FACTORY_RESET: // Before the completion of Reboot, if any crash happens then PackageWatchdog Loading @@ -560,6 +622,12 @@ public class RescueParty { private static void executeWarmReboot(Context context, int level, @Nullable String failedPackage) { if (Flags.deprecateFlagsAndSettingsResets()) { if (shouldThrottleReboot()) { return; } } // Request the reboot from a separate thread to avoid deadlock on PackageWatchdog // when device shutting down. setRebootProperty(true); Loading @@ -579,6 +647,11 @@ public class RescueParty { private static void executeFactoryReset(Context context, int level, @Nullable String failedPackage) { if (Flags.deprecateFlagsAndSettingsResets()) { if (shouldThrottleReboot()) { return; } } setFactoryResetProperty(true); long now = System.currentTimeMillis(); setLastFactoryResetTimeMs(now); Loading Loading @@ -655,6 +728,7 @@ public class RescueParty { private static void resetAllSettingsIfNecessary(Context context, int mode, int level) throws Exception { if (!Flags.deprecateFlagsAndSettingsResets()) { // No need to reset Settings again if they are already reset in the current level once. if (getMaxRescueLevelAttempted() >= level) { return; Loading @@ -681,6 +755,7 @@ public class RescueParty { throw res; } } } /** * Handle mitigation action for package failures. This observer will be register to Package Loading Loading @@ -731,8 +806,12 @@ public class RescueParty { if (!isDisabled() && (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING)) { if (Flags.recoverabilityDetection()) { if (!Flags.deprecateFlagsAndSettingsResets()) { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, mayPerformReboot(failedPackage), failedPackage)); } else { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount)); } } else { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, mayPerformReboot(failedPackage))); Loading @@ -750,10 +829,17 @@ public class RescueParty { } if (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING) { final int level = Flags.recoverabilityDetection() ? getRescueLevel(mitigationCount, mayPerformReboot(failedPackage), failedPackage) : getRescueLevel(mitigationCount, mayPerformReboot(failedPackage)); final int level; if (Flags.recoverabilityDetection()) { if (!Flags.deprecateFlagsAndSettingsResets()) { level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage), failedPackage); } else { level = getRescueLevel(mitigationCount); } } else { level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage)); } executeRescueLevel(mContext, failedPackage == null ? null : failedPackage.getPackageName(), level); return true; Loading Loading @@ -787,8 +873,12 @@ public class RescueParty { return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0; } if (Flags.recoverabilityDetection()) { if (!Flags.deprecateFlagsAndSettingsResets()) { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, true, /*failedPackage=*/ null)); } else { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount)); } } else { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, true)); } Loading @@ -800,9 +890,17 @@ public class RescueParty { return false; } boolean mayPerformReboot = !shouldThrottleReboot(); final int level = Flags.recoverabilityDetection() ? getRescueLevel(mitigationCount, mayPerformReboot, /*failedPackage=*/ null) : getRescueLevel(mitigationCount, mayPerformReboot); final int level; if (Flags.recoverabilityDetection()) { if (!Flags.deprecateFlagsAndSettingsResets()) { level = getRescueLevel(mitigationCount, mayPerformReboot, /*failedPackage=*/ null); } else { level = getRescueLevel(mitigationCount); } } else { level = getRescueLevel(mitigationCount, mayPerformReboot); } executeRescueLevel(mContext, /*failedPackage=*/ null, level); return true; } Loading @@ -828,18 +926,6 @@ public class RescueParty { return isPersistentSystemApp(failingPackage.getPackageName()); } /** * Returns {@code true} if Rescue Party is allowed to attempt a reboot or factory reset. * Will return {@code false} if a factory reset was already offered recently. */ private boolean shouldThrottleReboot() { Long lastResetTime = getLastFactoryResetTimeMs(); long now = System.currentTimeMillis(); long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG, DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN); return now < lastResetTime + TimeUnit.MINUTES.toMillis(throttleDurationMin); } private boolean isPersistentSystemApp(@NonNull String packageName) { PackageManager pm = mContext.getPackageManager(); try { Loading @@ -852,6 +938,7 @@ public class RescueParty { private synchronized void recordDeviceConfigAccess(@NonNull String callingPackage, @NonNull String namespace) { if (!Flags.deprecateFlagsAndSettingsResets()) { // Record it in calling packages to namespace map Set<String> namespaceSet = mCallingPackageNamespaceSetMap.get(callingPackage); if (namespaceSet == null) { Loading @@ -867,6 +954,7 @@ public class RescueParty { callingPackageSet.add(callingPackage); mNamespaceCallingPackageSetMap.put(namespace, callingPackageSet); } } private synchronized Set<String> getAffectedNamespaceSet(String failedPackage) { return mCallingPackageNamespaceSetMap.get(failedPackage); Loading @@ -881,6 +969,18 @@ public class RescueParty { } } /** * Returns {@code true} if Rescue Party is allowed to attempt a reboot or factory reset. * Will return {@code false} if a factory reset was already offered recently. */ private static boolean shouldThrottleReboot() { Long lastResetTime = getLastFactoryResetTimeMs(); long now = System.currentTimeMillis(); long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG, DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN); return now < lastResetTime + TimeUnit.MINUTES.toMillis(throttleDurationMin); } private static int[] getAllUserIds() { int systemUserId = UserHandle.SYSTEM.getIdentifier(); int[] userIds = { systemUserId }; Loading Loading @@ -919,6 +1019,22 @@ public class RescueParty { } } private static class Level { static int none() { return Flags.recoverabilityDetection() ? RESCUE_LEVEL_NONE : LEVEL_NONE; } static int reboot() { return Flags.recoverabilityDetection() ? RESCUE_LEVEL_WARM_REBOOT : LEVEL_WARM_REBOOT; } static int factoryReset() { return Flags.recoverabilityDetection() ? RESCUE_LEVEL_FACTORY_RESET : LEVEL_FACTORY_RESET; } } private static String levelToString(int level) { if (Flags.recoverabilityDetection()) { switch (level) { Loading services/core/java/com/android/server/rollback/Rollback.java +6 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.rollback; import static android.crashrecovery.flags.Flags.deprecateFlagsAndSettingsResets; import static com.android.server.rollback.RollbackManagerServiceImpl.sendFailure; import android.Manifest; Loading Loading @@ -622,8 +624,10 @@ class Rollback { parentSession.addChildSessionId(sessionId); } if (!deprecateFlagsAndSettingsResets()) { // Clear flags. RescueParty.resetDeviceConfigForPackages(packageNames); } Consumer<Intent> onResult = result -> { mHandler.post(() -> { Loading services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java +105 −183 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/RescueParty.java +275 −159 Original line number Diff line number Diff line Loading @@ -241,6 +241,7 @@ public class RescueParty { * opportunity to reset any settings depending on our rescue level. */ public static void onSettingsProviderPublished(Context context) { if (!Flags.deprecateFlagsAndSettingsResets()) { handleNativeRescuePartyResets(); ContentResolver contentResolver = context.getContentResolver(); DeviceConfig.setMonitorCallback( Loading @@ -248,6 +249,7 @@ public class RescueParty { Executors.newSingleThreadExecutor(), new RescuePartyMonitorCallback(context)); } } /** Loading @@ -256,6 +258,7 @@ public class RescueParty { * on modules of newer versions. */ public static void resetDeviceConfigForPackages(List<String> packageNames) { if (!Flags.deprecateFlagsAndSettingsResets()) { if (packageNames == null) { return; } Loading Loading @@ -299,9 +302,11 @@ public class RescueParty { } } } } private static Set<String> getPresetNamespacesForPackages(List<String> packageNames) { Set<String> resultSet = new ArraySet<String>(); if (!Flags.deprecateFlagsAndSettingsResets()) { try { String flagVal = DeviceConfig.getString(NAMESPACE_CONFIGURATION, NAMESPACE_TO_PACKAGE_MAPPING_FLAG, ""); Loading @@ -310,12 +315,12 @@ public class RescueParty { if (TextUtils.isEmpty(mappingEntries[i])) { continue; } String[] splittedEntry = mappingEntries[i].split(":"); if (splittedEntry.length != 2) { String[] splitEntry = mappingEntries[i].split(":"); if (splitEntry.length != 2) { throw new RuntimeException("Invalid mapping entry: " + mappingEntries[i]); } String namespace = splittedEntry[0]; String packageName = splittedEntry[1]; String namespace = splitEntry[0]; String packageName = splitEntry[1]; if (packageNames.contains(packageName)) { resultSet.add(namespace); Loading @@ -327,6 +332,9 @@ public class RescueParty { } finally { return resultSet; } } else { return resultSet; } } @VisibleForTesting Loading @@ -342,20 +350,27 @@ public class RescueParty { } public void onNamespaceUpdate(@NonNull String updatedNamespace) { if (!Flags.deprecateFlagsAndSettingsResets()) { startObservingPackages(mContext, updatedNamespace); } } public void onDeviceConfigAccess(@NonNull String callingPackage, @NonNull String namespace) { if (!Flags.deprecateFlagsAndSettingsResets()) { RescuePartyObserver.getInstance(mContext).recordDeviceConfigAccess( callingPackage, namespace); } } } private static void startObservingPackages(Context context, @NonNull String updatedNamespace) { if (!Flags.deprecateFlagsAndSettingsResets()) { RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context); Set<String> callingPackages = rescuePartyObserver.getCallingPackagesSet(updatedNamespace); Set<String> callingPackages = rescuePartyObserver.getCallingPackagesSet( updatedNamespace); if (callingPackages == null) { return; } Loading @@ -368,10 +383,13 @@ public class RescueParty { callingPackageList, DEFAULT_OBSERVING_DURATION_MS); } } private static void handleNativeRescuePartyResets() { if (!Flags.deprecateFlagsAndSettingsResets()) { if (SettingsToPropertiesMapper.isNativeFlagsResetPerformed()) { String[] resetNativeCategories = SettingsToPropertiesMapper.getResetNativeCategories(); String[] resetNativeCategories = SettingsToPropertiesMapper.getResetNativeCategories(); for (int i = 0; i < resetNativeCategories.length; i++) { // Don't let RescueParty reset the namespace for RescueParty switches. if (NAMESPACE_CONFIGURATION.equals(resetNativeCategories[i])) { Loading @@ -382,6 +400,7 @@ public class RescueParty { } } } } private static int getMaxRescueLevel(boolean mayPerformReboot) { if (Flags.recoverabilityDetection()) { Loading @@ -400,6 +419,13 @@ public class RescueParty { } } private static int getMaxRescueLevel() { if (!SystemProperties.getBoolean(PROP_DISABLE_FACTORY_RESET_FLAG, false)) { return Level.factoryReset(); } return Level.reboot(); } /** * Get the rescue level to perform if this is the n-th attempt at mitigating failure. * Loading @@ -409,6 +435,7 @@ public class RescueParty { * @return the rescue level for the n-th mitigation attempt. */ private static int getRescueLevel(int mitigationCount, boolean mayPerformReboot) { if (!Flags.deprecateFlagsAndSettingsResets()) { if (mitigationCount == 1) { return LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS; } else if (mitigationCount == 2) { Loading @@ -423,6 +450,16 @@ public class RescueParty { Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount); return LEVEL_NONE; } } else { if (mitigationCount == 1) { return Level.reboot(); } else if (mitigationCount >= 2) { return Math.min(getMaxRescueLevel(), Level.factoryReset()); } else { Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount); return LEVEL_NONE; } } } /** Loading Loading @@ -465,6 +502,22 @@ public class RescueParty { } } /** * Get the rescue level to perform if this is the n-th attempt at mitigating failure. * * @param mitigationCount the mitigation attempt number (1 = first attempt etc.). * @return the rescue level for the n-th mitigation attempt. */ private static @RescueLevels int getRescueLevel(int mitigationCount) { if (mitigationCount == 1) { return Level.reboot(); } else if (mitigationCount >= 2) { return Math.min(getMaxRescueLevel(), Level.factoryReset()); } else { return Level.none(); } } private static void executeRescueLevel(Context context, @Nullable String failedPackage, int level) { Slog.w(TAG, "Attempting rescue level " + levelToString(level)); Loading Loading @@ -537,13 +590,22 @@ public class RescueParty { executeWarmReboot(context, level, failedPackage); break; case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS: resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS, level); if (!Flags.deprecateFlagsAndSettingsResets()) { resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS, level); } break; case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES: resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES, level); if (!Flags.deprecateFlagsAndSettingsResets()) { resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES, level); } break; case RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS: resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS, level); if (!Flags.deprecateFlagsAndSettingsResets()) { resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS, level); } break; case RESCUE_LEVEL_FACTORY_RESET: // Before the completion of Reboot, if any crash happens then PackageWatchdog Loading @@ -560,6 +622,12 @@ public class RescueParty { private static void executeWarmReboot(Context context, int level, @Nullable String failedPackage) { if (Flags.deprecateFlagsAndSettingsResets()) { if (shouldThrottleReboot()) { return; } } // Request the reboot from a separate thread to avoid deadlock on PackageWatchdog // when device shutting down. setRebootProperty(true); Loading @@ -579,6 +647,11 @@ public class RescueParty { private static void executeFactoryReset(Context context, int level, @Nullable String failedPackage) { if (Flags.deprecateFlagsAndSettingsResets()) { if (shouldThrottleReboot()) { return; } } setFactoryResetProperty(true); long now = System.currentTimeMillis(); setLastFactoryResetTimeMs(now); Loading Loading @@ -655,6 +728,7 @@ public class RescueParty { private static void resetAllSettingsIfNecessary(Context context, int mode, int level) throws Exception { if (!Flags.deprecateFlagsAndSettingsResets()) { // No need to reset Settings again if they are already reset in the current level once. if (getMaxRescueLevelAttempted() >= level) { return; Loading @@ -681,6 +755,7 @@ public class RescueParty { throw res; } } } /** * Handle mitigation action for package failures. This observer will be register to Package Loading Loading @@ -731,8 +806,12 @@ public class RescueParty { if (!isDisabled() && (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING)) { if (Flags.recoverabilityDetection()) { if (!Flags.deprecateFlagsAndSettingsResets()) { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, mayPerformReboot(failedPackage), failedPackage)); } else { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount)); } } else { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, mayPerformReboot(failedPackage))); Loading @@ -750,10 +829,17 @@ public class RescueParty { } if (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING) { final int level = Flags.recoverabilityDetection() ? getRescueLevel(mitigationCount, mayPerformReboot(failedPackage), failedPackage) : getRescueLevel(mitigationCount, mayPerformReboot(failedPackage)); final int level; if (Flags.recoverabilityDetection()) { if (!Flags.deprecateFlagsAndSettingsResets()) { level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage), failedPackage); } else { level = getRescueLevel(mitigationCount); } } else { level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage)); } executeRescueLevel(mContext, failedPackage == null ? null : failedPackage.getPackageName(), level); return true; Loading Loading @@ -787,8 +873,12 @@ public class RescueParty { return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0; } if (Flags.recoverabilityDetection()) { if (!Flags.deprecateFlagsAndSettingsResets()) { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, true, /*failedPackage=*/ null)); } else { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount)); } } else { return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, true)); } Loading @@ -800,9 +890,17 @@ public class RescueParty { return false; } boolean mayPerformReboot = !shouldThrottleReboot(); final int level = Flags.recoverabilityDetection() ? getRescueLevel(mitigationCount, mayPerformReboot, /*failedPackage=*/ null) : getRescueLevel(mitigationCount, mayPerformReboot); final int level; if (Flags.recoverabilityDetection()) { if (!Flags.deprecateFlagsAndSettingsResets()) { level = getRescueLevel(mitigationCount, mayPerformReboot, /*failedPackage=*/ null); } else { level = getRescueLevel(mitigationCount); } } else { level = getRescueLevel(mitigationCount, mayPerformReboot); } executeRescueLevel(mContext, /*failedPackage=*/ null, level); return true; } Loading @@ -828,18 +926,6 @@ public class RescueParty { return isPersistentSystemApp(failingPackage.getPackageName()); } /** * Returns {@code true} if Rescue Party is allowed to attempt a reboot or factory reset. * Will return {@code false} if a factory reset was already offered recently. */ private boolean shouldThrottleReboot() { Long lastResetTime = getLastFactoryResetTimeMs(); long now = System.currentTimeMillis(); long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG, DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN); return now < lastResetTime + TimeUnit.MINUTES.toMillis(throttleDurationMin); } private boolean isPersistentSystemApp(@NonNull String packageName) { PackageManager pm = mContext.getPackageManager(); try { Loading @@ -852,6 +938,7 @@ public class RescueParty { private synchronized void recordDeviceConfigAccess(@NonNull String callingPackage, @NonNull String namespace) { if (!Flags.deprecateFlagsAndSettingsResets()) { // Record it in calling packages to namespace map Set<String> namespaceSet = mCallingPackageNamespaceSetMap.get(callingPackage); if (namespaceSet == null) { Loading @@ -867,6 +954,7 @@ public class RescueParty { callingPackageSet.add(callingPackage); mNamespaceCallingPackageSetMap.put(namespace, callingPackageSet); } } private synchronized Set<String> getAffectedNamespaceSet(String failedPackage) { return mCallingPackageNamespaceSetMap.get(failedPackage); Loading @@ -881,6 +969,18 @@ public class RescueParty { } } /** * Returns {@code true} if Rescue Party is allowed to attempt a reboot or factory reset. * Will return {@code false} if a factory reset was already offered recently. */ private static boolean shouldThrottleReboot() { Long lastResetTime = getLastFactoryResetTimeMs(); long now = System.currentTimeMillis(); long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG, DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN); return now < lastResetTime + TimeUnit.MINUTES.toMillis(throttleDurationMin); } private static int[] getAllUserIds() { int systemUserId = UserHandle.SYSTEM.getIdentifier(); int[] userIds = { systemUserId }; Loading Loading @@ -919,6 +1019,22 @@ public class RescueParty { } } private static class Level { static int none() { return Flags.recoverabilityDetection() ? RESCUE_LEVEL_NONE : LEVEL_NONE; } static int reboot() { return Flags.recoverabilityDetection() ? RESCUE_LEVEL_WARM_REBOOT : LEVEL_WARM_REBOOT; } static int factoryReset() { return Flags.recoverabilityDetection() ? RESCUE_LEVEL_FACTORY_RESET : LEVEL_FACTORY_RESET; } } private static String levelToString(int level) { if (Flags.recoverabilityDetection()) { switch (level) { Loading
services/core/java/com/android/server/rollback/Rollback.java +6 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.server.rollback; import static android.crashrecovery.flags.Flags.deprecateFlagsAndSettingsResets; import static com.android.server.rollback.RollbackManagerServiceImpl.sendFailure; import android.Manifest; Loading Loading @@ -622,8 +624,10 @@ class Rollback { parentSession.addChildSessionId(sessionId); } if (!deprecateFlagsAndSettingsResets()) { // Clear flags. RescueParty.resetDeviceConfigForPackages(packageNames); } Consumer<Intent> onResult = result -> { mHandler.post(() -> { Loading
services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java +105 −183 File changed.Preview size limit exceeded, changes collapsed. Show changes