summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java324
1 files changed, 323 insertions, 1 deletions
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index 3722fefb12ad..c0e90f9232d6 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -35,6 +35,7 @@ import static org.mockito.Mockito.when;
import android.Manifest;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
@@ -77,6 +78,7 @@ import org.mockito.stubbing.Answer;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -413,6 +415,311 @@ public class CrashRecoveryTest {
verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
}
+ @Test
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testCrashLoopWithRescuePartyAndRollbackObserver() throws Exception {
+ PackageWatchdog watchdog = createWatchdog();
+ RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
+ RollbackPackageHealthObserver rollbackObserver =
+ setUpRollbackPackageHealthObserver(watchdog);
+ VersionedPackage versionedPackageA = new VersionedPackage(APP_A, VERSION_CODE);
+
+ when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
+ ApplicationInfo info = new ApplicationInfo();
+ info.flags |= ApplicationInfo.FLAG_PERSISTENT
+ | ApplicationInfo.FLAG_SYSTEM;
+ return info;
+ });
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: SCOPED_DEVICE_CONFIG_RESET
+ verify(rescuePartyObserver).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ verify(rollbackObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: ALL_DEVICE_CONFIG_RESET
+ verify(rescuePartyObserver).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+ verify(rollbackObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: WARM_REBOOT
+ verify(rescuePartyObserver).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+ verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+ verify(rollbackObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: Low impact rollback
+ verify(rollbackObserver).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+
+ // update available rollbacks to mock rollbacks being applied after the call to
+ // rollbackObserver.execute
+ when(mRollbackManager.getAvailableRollbacks()).thenReturn(
+ List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD reached. No more mitigations applied
+ verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+ verify(rollbackObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testCrashLoopWithRescuePartyAndRollbackObserverEnableDeprecateFlagReset()
+ throws Exception {
+ PackageWatchdog watchdog = createWatchdog();
+ RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
+ RollbackPackageHealthObserver rollbackObserver =
+ setUpRollbackPackageHealthObserver(watchdog);
+ VersionedPackage versionedPackageA = new VersionedPackage(APP_A, VERSION_CODE);
+
+ when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
+ ApplicationInfo info = new ApplicationInfo();
+ info.flags |= ApplicationInfo.FLAG_PERSISTENT
+ | ApplicationInfo.FLAG_SYSTEM;
+ return info;
+ });
+
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: WARM_REBOOT
+ verify(rescuePartyObserver).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ verify(rollbackObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: Low impact rollback
+ verify(rollbackObserver).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+ // update available rollbacks to mock rollbacks being applied after the call to
+ // rollbackObserver.execute
+ when(mRollbackManager.getAvailableRollbacks()).thenReturn(
+ List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageA), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD reached. No more mitigations applied
+ verify(rescuePartyObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ verify(rollbackObserver, never()).execute(versionedPackageA,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testCrashLoopSystemUIWithRescuePartyAndRollbackObserver() throws Exception {
+ PackageWatchdog watchdog = createWatchdog();
+ RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
+ RollbackPackageHealthObserver rollbackObserver =
+ setUpRollbackPackageHealthObserver(watchdog);
+ String systemUi = "com.android.systemui";
+ VersionedPackage versionedPackageUi = new VersionedPackage(
+ systemUi, VERSION_CODE);
+ RollbackInfo rollbackInfoUi = getRollbackInfo(systemUi, VERSION_CODE, 1,
+ PackageManager.ROLLBACK_USER_IMPACT_LOW);
+ when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_LOW,
+ ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL, rollbackInfoUi));
+
+ when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
+ ApplicationInfo info = new ApplicationInfo();
+ info.flags |= ApplicationInfo.FLAG_PERSISTENT
+ | ApplicationInfo.FLAG_SYSTEM;
+ return info;
+ });
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: SCOPED_DEVICE_CONFIG_RESET
+ verify(rescuePartyObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: ALL_DEVICE_CONFIG_RESET
+ verify(rescuePartyObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: WARM_REBOOT
+ verify(rescuePartyObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: Low impact rollback
+ verify(rollbackObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+ // update available rollbacks to mock rollbacks being applied after the call to
+ // rollbackObserver.execute
+ when(mRollbackManager.getAvailableRollbacks()).thenReturn(
+ List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: RESET_SETTINGS_UNTRUSTED_DEFAULTS
+ verify(rescuePartyObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 4);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 5);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: RESET_SETTINGS_UNTRUSTED_CHANGES
+ verify(rescuePartyObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 5);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 6);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: RESET_SETTINGS_TRUSTED_DEFAULTS
+ verify(rescuePartyObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 6);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 7);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: Factory reset. High impact rollbacks are performed only for boot loops.
+ verify(rescuePartyObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 7);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 8);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_DEPRECATE_FLAGS_AND_SETTINGS_RESETS)
+ public void testCrashLoopSystemUIWithRescuePartyAndRollbackObserverEnableDeprecateFlagReset()
+ throws Exception {
+ PackageWatchdog watchdog = createWatchdog();
+ RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
+ RollbackPackageHealthObserver rollbackObserver =
+ setUpRollbackPackageHealthObserver(watchdog);
+ String systemUi = "com.android.systemui";
+ VersionedPackage versionedPackageUi = new VersionedPackage(
+ systemUi, VERSION_CODE);
+ RollbackInfo rollbackInfoUi = getRollbackInfo(systemUi, VERSION_CODE, 1,
+ PackageManager.ROLLBACK_USER_IMPACT_LOW);
+ when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_LOW,
+ ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL, rollbackInfoUi));
+
+ when(mMockPackageManager.getApplicationInfo(anyString(), anyInt())).then(inv -> {
+ ApplicationInfo info = new ApplicationInfo();
+ info.flags |= ApplicationInfo.FLAG_PERSISTENT
+ | ApplicationInfo.FLAG_SYSTEM;
+ return info;
+ });
+
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: WARM_REBOOT
+ verify(rescuePartyObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: Low impact rollback
+ verify(rollbackObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 1);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+
+ // update available rollbacks to mock rollbacks being applied after the call to
+ // rollbackObserver.execute
+ when(mRollbackManager.getAvailableRollbacks()).thenReturn(
+ List.of(ROLLBACK_INFO_HIGH, ROLLBACK_INFO_MANUAL));
+
+ raiseFatalFailureAndDispatch(watchdog,
+ Arrays.asList(versionedPackageUi), PackageWatchdog.FAILURE_REASON_APP_CRASH);
+
+ // Mitigation: Factory reset. High impact rollbacks are performed only for boot loops.
+ verify(rescuePartyObserver).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ verify(rescuePartyObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 3);
+ verify(rollbackObserver, never()).execute(versionedPackageUi,
+ PackageWatchdog.FAILURE_REASON_APP_CRASH, 2);
+ }
+
RollbackPackageHealthObserver setUpRollbackPackageHealthObserver(PackageWatchdog watchdog) {
RollbackPackageHealthObserver rollbackObserver =
spy(new RollbackPackageHealthObserver(mSpyContext, mApexManager));
@@ -424,7 +731,6 @@ public class CrashRecoveryTest {
watchdog.registerHealthObserver(rollbackObserver);
return rollbackObserver;
}
-
RescuePartyObserver setUpRescuePartyObserver(PackageWatchdog watchdog) {
setCrashRecoveryPropRescueBootCount(0);
RescuePartyObserver rescuePartyObserver = spy(RescuePartyObserver.getInstance(mSpyContext));
@@ -686,4 +992,20 @@ public class CrashRecoveryTest {
mTestLooper.moveTimeForward(milliSeconds);
mTestLooper.dispatchAll();
}
+
+ private void raiseFatalFailureAndDispatch(PackageWatchdog watchdog,
+ List<VersionedPackage> packages, int failureReason) {
+ long triggerFailureCount = watchdog.getTriggerFailureCount();
+ if (failureReason == PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK
+ || failureReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
+ triggerFailureCount = 1;
+ }
+ for (int i = 0; i < triggerFailureCount; i++) {
+ watchdog.onPackageFailure(packages, failureReason);
+ }
+ mTestLooper.dispatchAll();
+ if (Flags.recoverabilityDetection()) {
+ moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS);
+ }
+ }
}