1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; 20 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; 21 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyLong; 22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString; 23 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; 24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; 26 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; 27 import static com.android.server.RescueParty.LEVEL_FACTORY_RESET; 28 29 import static org.junit.Assert.assertEquals; 30 import static org.junit.Assert.assertTrue; 31 import static org.mockito.ArgumentMatchers.eq; 32 import static org.mockito.ArgumentMatchers.isNull; 33 import static org.mockito.Mockito.times; 34 35 import android.content.ContentResolver; 36 import android.content.Context; 37 import android.content.pm.VersionedPackage; 38 import android.os.Bundle; 39 import android.os.RecoverySystem; 40 import android.os.RemoteCallback; 41 import android.os.SystemProperties; 42 import android.os.UserHandle; 43 import android.provider.DeviceConfig; 44 import android.provider.Settings; 45 46 import com.android.dx.mockito.inline.extended.ExtendedMockito; 47 import com.android.server.PackageWatchdog.PackageHealthObserverImpact; 48 import com.android.server.RescueParty.RescuePartyObserver; 49 import com.android.server.am.SettingsToPropertiesMapper; 50 51 import org.junit.After; 52 import org.junit.Before; 53 import org.junit.Test; 54 import org.mockito.Answers; 55 import org.mockito.ArgumentCaptor; 56 import org.mockito.Captor; 57 import org.mockito.Mock; 58 import org.mockito.MockitoSession; 59 import org.mockito.quality.Strictness; 60 import org.mockito.stubbing.Answer; 61 62 import java.util.Arrays; 63 import java.util.HashMap; 64 import java.util.List; 65 66 /** 67 * Test RescueParty. 68 */ 69 public class RescuePartyTest { 70 private static final long CURRENT_NETWORK_TIME_MILLIS = 0L; 71 private static final String FAKE_NATIVE_NAMESPACE1 = "native1"; 72 private static final String FAKE_NATIVE_NAMESPACE2 = "native2"; 73 private static final String[] FAKE_RESET_NATIVE_NAMESPACES = 74 {FAKE_NATIVE_NAMESPACE1, FAKE_NATIVE_NAMESPACE2}; 75 76 private static VersionedPackage sFailingPackage = new VersionedPackage("com.package.name", 1); 77 private static final String PROP_DISABLE_RESCUE = "persist.sys.disable_rescue"; 78 private static final String CALLING_PACKAGE1 = "com.package.name1"; 79 private static final String CALLING_PACKAGE2 = "com.package.name2"; 80 private static final String NAMESPACE1 = "namespace1"; 81 private static final String NAMESPACE2 = "namespace2"; 82 private static final String PROP_DEVICE_CONFIG_DISABLE_FLAG = 83 "persist.device_config.configuration.disable_rescue_party"; 84 85 private MockitoSession mSession; 86 private HashMap<String, String> mSystemSettingsMap; 87 88 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 89 private Context mMockContext; 90 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 91 private PackageWatchdog mMockPackageWatchdog; 92 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 93 private ContentResolver mMockContentResolver; 94 95 @Captor 96 private ArgumentCaptor<RemoteCallback> mMonitorCallbackCaptor; 97 @Captor 98 private ArgumentCaptor<List<String>> mPackageListCaptor; 99 100 @Before setUp()101 public void setUp() throws Exception { 102 mSession = 103 ExtendedMockito.mockitoSession().initMocks( 104 this) 105 .strictness(Strictness.LENIENT) 106 .spyStatic(DeviceConfig.class) 107 .spyStatic(SystemProperties.class) 108 .spyStatic(Settings.Global.class) 109 .spyStatic(Settings.Secure.class) 110 .spyStatic(Settings.Config.class) 111 .spyStatic(SettingsToPropertiesMapper.class) 112 .spyStatic(RecoverySystem.class) 113 .spyStatic(RescueParty.class) 114 .spyStatic(PackageWatchdog.class) 115 .startMocking(); 116 mSystemSettingsMap = new HashMap<>(); 117 118 when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver); 119 // Reset observer instance to get new mock context on every run 120 RescuePartyObserver.reset(); 121 122 // Mock SystemProperties setter and various getters 123 doAnswer((Answer<Void>) invocationOnMock -> { 124 String key = invocationOnMock.getArgument(0); 125 String value = invocationOnMock.getArgument(1); 126 127 mSystemSettingsMap.put(key, value); 128 return null; 129 } 130 ).when(() -> SystemProperties.set(anyString(), anyString())); 131 132 doAnswer((Answer<Boolean>) invocationOnMock -> { 133 String key = invocationOnMock.getArgument(0); 134 boolean defaultValue = invocationOnMock.getArgument(1); 135 136 String storedValue = mSystemSettingsMap.get(key); 137 return storedValue == null ? defaultValue : Boolean.parseBoolean(storedValue); 138 } 139 ).when(() -> SystemProperties.getBoolean(anyString(), anyBoolean())); 140 141 doAnswer((Answer<Integer>) invocationOnMock -> { 142 String key = invocationOnMock.getArgument(0); 143 int defaultValue = invocationOnMock.getArgument(1); 144 145 String storedValue = mSystemSettingsMap.get(key); 146 return storedValue == null ? defaultValue : Integer.parseInt(storedValue); 147 } 148 ).when(() -> SystemProperties.getInt(anyString(), anyInt())); 149 150 doAnswer((Answer<Long>) invocationOnMock -> { 151 String key = invocationOnMock.getArgument(0); 152 long defaultValue = invocationOnMock.getArgument(1); 153 154 String storedValue = mSystemSettingsMap.get(key); 155 return storedValue == null ? defaultValue : Long.parseLong(storedValue); 156 } 157 ).when(() -> SystemProperties.getLong(anyString(), anyLong())); 158 159 // Mock DeviceConfig 160 doAnswer((Answer<Boolean>) invocationOnMock -> true) 161 .when(() -> DeviceConfig.setProperty(anyString(), anyString(), anyString(), 162 anyBoolean())); 163 doAnswer((Answer<Void>) invocationOnMock -> null) 164 .when(() -> DeviceConfig.resetToDefaults(anyInt(), anyString())); 165 166 // Mock PackageWatchdog 167 doAnswer((Answer<PackageWatchdog>) invocationOnMock -> mMockPackageWatchdog) 168 .when(() -> PackageWatchdog.getInstance(mMockContext)); 169 170 doReturn(CURRENT_NETWORK_TIME_MILLIS).when(() -> RescueParty.getElapsedRealtime()); 171 172 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, 173 Integer.toString(RescueParty.LEVEL_NONE)); 174 SystemProperties.set(RescueParty.PROP_RESCUE_BOOT_COUNT, Integer.toString(0)); 175 SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true)); 176 SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(false)); 177 } 178 179 @After tearDown()180 public void tearDown() throws Exception { 181 mSession.finishMocking(); 182 } 183 184 @Test testBootLoopDetectionWithExecutionForAllRescueLevels()185 public void testBootLoopDetectionWithExecutionForAllRescueLevels() { 186 noteBoot(); 187 188 verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null); 189 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS, 190 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 191 192 noteBoot(); 193 194 verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, /*resetNamespaces=*/ null); 195 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES, 196 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 197 198 noteBoot(); 199 200 verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/ null); 201 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS, 202 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 203 204 noteBoot(); 205 206 verify(() -> RecoverySystem.rebootPromptAndWipeUserData(mMockContext, RescueParty.TAG)); 207 assertEquals(LEVEL_FACTORY_RESET, 208 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 209 } 210 211 @Test testPersistentAppCrashDetectionWithExecutionForAllRescueLevels()212 public void testPersistentAppCrashDetectionWithExecutionForAllRescueLevels() { 213 notePersistentAppCrash(); 214 215 verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null); 216 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS, 217 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 218 219 notePersistentAppCrash(); 220 221 verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, /*resetNamespaces=*/ null); 222 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES, 223 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 224 225 notePersistentAppCrash(); 226 227 verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/ null); 228 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS, 229 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 230 231 notePersistentAppCrash(); 232 233 verify(() -> RecoverySystem.rebootPromptAndWipeUserData(mMockContext, RescueParty.TAG)); 234 assertEquals(LEVEL_FACTORY_RESET, 235 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 236 } 237 238 @Test testNonPersistentAppCrashDetectionWithScopedResets()239 public void testNonPersistentAppCrashDetectionWithScopedResets() { 240 RescueParty.onSettingsProviderPublished(mMockContext); 241 verify(() -> Settings.Config.registerMonitorCallback(eq(mMockContentResolver), 242 mMonitorCallbackCaptor.capture())); 243 244 // Record DeviceConfig accesses 245 RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); 246 RemoteCallback monitorCallback = mMonitorCallbackCaptor.getValue(); 247 monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE1)); 248 monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE1, NAMESPACE2)); 249 monitorCallback.sendResult(getConfigAccessBundle(CALLING_PACKAGE2, NAMESPACE2)); 250 // Fake DeviceConfig value changes 251 monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE1)); 252 verify(mMockPackageWatchdog).startObservingHealth(observer, 253 Arrays.asList(CALLING_PACKAGE1), RescueParty.DEFAULT_OBSERVING_DURATION_MS); 254 monitorCallback.sendResult(getConfigNamespaceUpdateBundle(NAMESPACE2)); 255 verify(mMockPackageWatchdog, times(2)).startObservingHealth(eq(observer), 256 mPackageListCaptor.capture(), 257 eq(RescueParty.DEFAULT_OBSERVING_DURATION_MS)); 258 assertTrue(mPackageListCaptor.getValue().containsAll( 259 Arrays.asList(CALLING_PACKAGE1, CALLING_PACKAGE2))); 260 // Perform and verify scoped resets 261 final String[] expectedResetNamespaces = new String[]{NAMESPACE1, NAMESPACE2}; 262 observer.execute(new VersionedPackage( 263 CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH); 264 verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, expectedResetNamespaces); 265 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS, 266 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 267 268 observer.execute(new VersionedPackage( 269 CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING); 270 verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_CHANGES, expectedResetNamespaces); 271 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES, 272 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 273 274 observer.execute(new VersionedPackage( 275 CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING); 276 verifySettingsResets(Settings.RESET_MODE_TRUSTED_DEFAULTS, /*resetNamespaces=*/null); 277 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS, 278 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 279 280 observer.execute(new VersionedPackage( 281 CALLING_PACKAGE1, 1), PackageWatchdog.FAILURE_REASON_APP_CRASH); 282 verify(() -> RecoverySystem.rebootPromptAndWipeUserData(mMockContext, RescueParty.TAG)); 283 assertTrue(RescueParty.isAttemptingFactoryReset()); 284 } 285 286 @Test testIsAttemptingFactoryReset()287 public void testIsAttemptingFactoryReset() { 288 for (int i = 0; i < LEVEL_FACTORY_RESET; i++) { 289 noteBoot(); 290 } 291 verify(() -> RecoverySystem.rebootPromptAndWipeUserData(mMockContext, RescueParty.TAG)); 292 assertTrue(RescueParty.isAttemptingFactoryReset()); 293 } 294 295 @Test testOnSettingsProviderPublishedExecutesRescueLevels()296 public void testOnSettingsProviderPublishedExecutesRescueLevels() { 297 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString(1)); 298 299 RescueParty.onSettingsProviderPublished(mMockContext); 300 301 verifySettingsResets(Settings.RESET_MODE_UNTRUSTED_DEFAULTS, /*resetNamespaces=*/ null); 302 assertEquals(RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS, 303 SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE)); 304 } 305 306 @Test testNativeRescuePartyResets()307 public void testNativeRescuePartyResets() { 308 doReturn(true).when(() -> SettingsToPropertiesMapper.isNativeFlagsResetPerformed()); 309 doReturn(FAKE_RESET_NATIVE_NAMESPACES).when( 310 () -> SettingsToPropertiesMapper.getResetNativeCategories()); 311 312 RescueParty.onSettingsProviderPublished(mMockContext); 313 314 verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS, 315 FAKE_NATIVE_NAMESPACE1)); 316 verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS, 317 FAKE_NATIVE_NAMESPACE2)); 318 } 319 320 @Test testExplicitlyEnablingAndDisablingRescue()321 public void testExplicitlyEnablingAndDisablingRescue() { 322 SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false)); 323 SystemProperties.set(PROP_DISABLE_RESCUE, Boolean.toString(true)); 324 assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage, 325 PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), false); 326 327 SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true)); 328 assertTrue(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage, 329 PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING)); 330 } 331 332 @Test testDisablingRescueByDeviceConfigFlag()333 public void testDisablingRescueByDeviceConfigFlag() { 334 SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false)); 335 SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(true)); 336 337 assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage, 338 PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), false); 339 340 // Restore the property value initalized in SetUp() 341 SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true)); 342 SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(false)); 343 } 344 345 @Test testHealthCheckLevels()346 public void testHealthCheckLevels() { 347 RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); 348 349 // Ensure that no action is taken for cases where the failure reason is unknown 350 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 351 LEVEL_FACTORY_RESET)); 352 assertEquals(observer.onHealthCheckFailed(null, PackageWatchdog.FAILURE_REASON_UNKNOWN), 353 PackageHealthObserverImpact.USER_IMPACT_NONE); 354 355 /* 356 For the following cases, ensure that the returned user impact corresponds with the user 357 impact of the next available rescue level, not the current one. 358 */ 359 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 360 RescueParty.LEVEL_NONE)); 361 assertEquals(observer.onHealthCheckFailed(null, 362 PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), 363 PackageHealthObserverImpact.USER_IMPACT_LOW); 364 365 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 366 RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS)); 367 assertEquals(observer.onHealthCheckFailed(null, 368 PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), 369 PackageHealthObserverImpact.USER_IMPACT_LOW); 370 371 372 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 373 RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES)); 374 assertEquals(observer.onHealthCheckFailed(null, 375 PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), 376 PackageHealthObserverImpact.USER_IMPACT_HIGH); 377 378 379 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 380 RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS)); 381 assertEquals(observer.onHealthCheckFailed(null, 382 PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), 383 PackageHealthObserverImpact.USER_IMPACT_HIGH); 384 385 386 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 387 LEVEL_FACTORY_RESET)); 388 assertEquals(observer.onHealthCheckFailed(null, 389 PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), 390 PackageHealthObserverImpact.USER_IMPACT_HIGH); 391 } 392 393 @Test testBootLoopLevels()394 public void testBootLoopLevels() { 395 RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); 396 397 /* 398 Ensure that the returned user impact corresponds with the user impact of the next available 399 rescue level, not the current one. 400 */ 401 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 402 RescueParty.LEVEL_NONE)); 403 assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_LOW); 404 405 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 406 RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS)); 407 assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_LOW); 408 409 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 410 RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES)); 411 assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_HIGH); 412 413 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 414 RescueParty.LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS)); 415 assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_HIGH); 416 417 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 418 LEVEL_FACTORY_RESET)); 419 assertEquals(observer.onBootLoop(), PackageHealthObserverImpact.USER_IMPACT_HIGH); 420 } 421 422 @Test testRescueLevelIncrementsWhenExecuted()423 public void testRescueLevelIncrementsWhenExecuted() { 424 RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext); 425 SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL, Integer.toString( 426 RescueParty.LEVEL_NONE)); 427 observer.execute(sFailingPackage, 428 PackageWatchdog.FAILURE_REASON_APP_CRASH); 429 assertEquals(SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, -1), 430 RescueParty.LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS); 431 } 432 verifySettingsResets(int resetMode, String[] resetNamespaces)433 private void verifySettingsResets(int resetMode, String[] resetNamespaces) { 434 verify(() -> Settings.Global.resetToDefaultsAsUser(mMockContentResolver, null, 435 resetMode, UserHandle.USER_SYSTEM)); 436 verify(() -> Settings.Secure.resetToDefaultsAsUser(eq(mMockContentResolver), isNull(), 437 eq(resetMode), anyInt())); 438 // Verify DeviceConfig resets 439 if (resetNamespaces == null) { 440 verify(() -> DeviceConfig.resetToDefaults(resetMode, /*namespace=*/ null)); 441 } else { 442 for (String namespace : resetNamespaces) { 443 verify(() -> DeviceConfig.resetToDefaults(resetMode, namespace)); 444 } 445 } 446 } 447 noteBoot()448 private void noteBoot() { 449 RescuePartyObserver.getInstance(mMockContext).executeBootLoopMitigation(); 450 } 451 notePersistentAppCrash()452 private void notePersistentAppCrash() { 453 RescuePartyObserver.getInstance(mMockContext).execute(new VersionedPackage( 454 "com.package.name", 1), PackageWatchdog.FAILURE_REASON_APP_CRASH); 455 } 456 getConfigAccessBundle(String callingPackage, String namespace)457 private Bundle getConfigAccessBundle(String callingPackage, String namespace) { 458 Bundle result = new Bundle(); 459 result.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE, Settings.EXTRA_ACCESS_CALLBACK); 460 result.putString(Settings.EXTRA_CALLING_PACKAGE, callingPackage); 461 result.putString(Settings.EXTRA_NAMESPACE, namespace); 462 return result; 463 } 464 getConfigNamespaceUpdateBundle(String updatedNamespace)465 private Bundle getConfigNamespaceUpdateBundle(String updatedNamespace) { 466 Bundle result = new Bundle(); 467 result.putString(Settings.EXTRA_MONITOR_CALLBACK_TYPE, 468 Settings.EXTRA_NAMESPACE_UPDATED_CALLBACK); 469 result.putString(Settings.EXTRA_NAMESPACE, updatedNamespace); 470 return result; 471 } 472 } 473