summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author bpetrivs <bpetrivs@google.com> 2019-02-28 12:08:12 +0000
committer bpetrivs <bpetrivs@google.com> 2019-03-05 11:06:47 +0000
commit93075f45e0c684bea71ef458730b9d68fc2b155f (patch)
treeffafff886321e893a4aac10b9e3031d59a12a4e1
parentbebec75d6e2140f2c0b908a395a75f6ce1d10976 (diff)
Add handling of NativeRescueParty resets to RescueParty.
Test: unit tests. Change-Id: I60d1393d483fccae405ca69a6aaedea84e1a090e
-rw-r--r--services/core/java/com/android/server/RescueParty.java10
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java3
-rw-r--r--services/core/java/com/android/server/utils/FlagNamespaceUtils.java30
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java44
4 files changed, 78 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 18c272202990..d26663520850 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -38,9 +38,11 @@ import android.util.StatsLog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
+import com.android.server.am.SettingsToPropertiesMapper;
import com.android.server.utils.FlagNamespaceUtils;
import java.io.File;
+import java.util.Arrays;
/**
* Utilities to help rescue the system from crash loops. Callers are expected to
@@ -158,6 +160,7 @@ public class RescueParty {
* opportunity to reset any settings depending on our rescue level.
*/
public static void onSettingsProviderPublished(Context context) {
+ handleNativeRescuePartyResets();
executeRescueLevel(context);
}
@@ -176,6 +179,13 @@ public class RescueParty {
return SystemClock.elapsedRealtime();
}
+ private static void handleNativeRescuePartyResets() {
+ if (SettingsToPropertiesMapper.isNativeFlagsResetPerformed()) {
+ FlagNamespaceUtils.resetDeviceConfig(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+ Arrays.asList(SettingsToPropertiesMapper.getResetNativeCategories()));
+ }
+ }
+
/**
* Escalate to the next rescue level. After incrementing the level you'll
* probably want to call {@link #executeRescueLevel(Context)}.
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 894a704c5bba..1d0fdaa08a14 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import android.annotation.NonNull;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.Uri;
@@ -167,7 +168,7 @@ public class SettingsToPropertiesMapper {
* booting.
* @return
*/
- public static String[] getResetNativeCategories() {
+ public static @NonNull String[] getResetNativeCategories() {
if (!isNativeFlagsResetPerformed()) {
return new String[0];
}
diff --git a/services/core/java/com/android/server/utils/FlagNamespaceUtils.java b/services/core/java/com/android/server/utils/FlagNamespaceUtils.java
index f26121eac939..f8c7447fc55d 100644
--- a/services/core/java/com/android/server/utils/FlagNamespaceUtils.java
+++ b/services/core/java/com/android/server/utils/FlagNamespaceUtils.java
@@ -19,6 +19,7 @@ package com.android.server.utils;
import android.annotation.Nullable;
import android.provider.DeviceConfig;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.RescueParty;
import java.util.ArrayList;
@@ -41,20 +42,23 @@ public final class FlagNamespaceUtils {
/**
* Name of the special namespace in DeviceConfig table used for communicating resets.
*/
- private static final String NAMESPACE_RESCUE_PARTY = "rescue_party_namespace";
+ @VisibleForTesting
+ public static final String NAMESPACE_RESCUE_PARTY = "rescue_party_namespace";
/**
* Flag in the {@link DeviceConfig} in {@link #NAMESPACE_RESCUE_PARTY}, holding all known {@link
* DeviceConfig} namespaces, as a {@link #DELIMITER} separated String. It's updated after the
* first time flags are written to the new namespace in the {@link DeviceConfig}.
*/
- private static final String ALL_KNOWN_NAMESPACES_FLAG = "all_known_namespaces";
+ @VisibleForTesting
+ public static final String ALL_KNOWN_NAMESPACES_FLAG = "all_known_namespaces";
/**
* Flag in the {@link DeviceConfig} in {@link #NAMESPACE_RESCUE_PARTY} with integer counter
* suffix added to it, holding {@link DeviceConfig} namespace value whose flags were recently
* reset by the {@link RescueParty}. It's updated by {@link RescueParty} every time given
* namespace flags are reset.
*/
- private static final String RESET_PLATFORM_PACKAGE_FLAG = "reset_platform_package";
+ @VisibleForTesting
+ public static final String RESET_PLATFORM_PACKAGE_FLAG = "reset_platform_package";
private static final String DELIMITER = ":";
/**
* Maximum value of the counter used in combination with {@link #RESET_PLATFORM_PACKAGE_FLAG}
@@ -97,11 +101,25 @@ public final class FlagNamespaceUtils {
* Reset all namespaces in DeviceConfig with consumed resetMode.
*/
public static void resetDeviceConfig(int resetMode) {
- List<String> allKnownNamespaces = getAllKnownDeviceConfigNamespacesList();
- for (String namespace : allKnownNamespaces) {
+ resetDeviceConfig(resetMode, getAllKnownDeviceConfigNamespacesList());
+ }
+
+ /**
+ * Reset all consumed namespaces in DeviceConfig with consumed resetMode.
+ */
+ public static void resetDeviceConfig(int resetMode, List<String> namespacesList) {
+ for (String namespace : namespacesList) {
DeviceConfig.resetToDefaults(resetMode, namespace);
}
- addToKnownResetNamespaces(allKnownNamespaces);
+ addToKnownResetNamespaces(namespacesList);
+ }
+
+ /**
+ * Resets known reset namespaces flag counter for tests only.
+ */
+ @VisibleForTesting
+ public static void resetKnownResetNamespacesFlagCounterForTest() {
+ sKnownResetNamespacesFlagCounter = -1;
}
/**
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index b13735cbf3b7..36825af527b1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -35,9 +35,12 @@ import android.content.Context;
import android.os.RecoverySystem;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.server.am.SettingsToPropertiesMapper;
+import com.android.server.utils.FlagNamespaceUtils;
import org.junit.After;
import org.junit.Before;
@@ -56,6 +59,10 @@ import java.util.HashMap;
public class RescuePartyTest {
private static final int PERSISTENT_APP_UID = 12;
private static final long CURRENT_NETWORK_TIME_MILLIS = 0L;
+ private static final String FAKE_NATIVE_NAMESPACE1 = "native1";
+ private static final String FAKE_NATIVE_NAMESPACE2 = "native2";
+ private static final String[] FAKE_RESET_NATIVE_NAMESPACES =
+ {FAKE_NATIVE_NAMESPACE1, FAKE_NATIVE_NAMESPACE2};
private MockitoSession mSession;
@@ -73,9 +80,11 @@ public class RescuePartyTest {
ExtendedMockito.mockitoSession().initMocks(
this)
.strictness(Strictness.LENIENT)
+ .spyStatic(DeviceConfig.class)
.spyStatic(SystemProperties.class)
.spyStatic(Settings.Global.class)
.spyStatic(Settings.Secure.class)
+ .spyStatic(SettingsToPropertiesMapper.class)
.spyStatic(RecoverySystem.class)
.spyStatic(RescueParty.class)
.startMocking();
@@ -121,8 +130,17 @@ public class RescuePartyTest {
}
).when(() -> SystemProperties.getLong(anyString(), anyLong()));
+ // Mock DeviceConfig
+ doAnswer((Answer<Boolean>) invocationOnMock -> true)
+ .when(() -> DeviceConfig.setProperty(anyString(), anyString(), anyString(),
+ anyBoolean()));
+ doAnswer((Answer<Void>) invocationOnMock -> null)
+ .when(() -> DeviceConfig.resetToDefaults(anyInt(), anyString()));
+
+
doReturn(CURRENT_NETWORK_TIME_MILLIS).when(() -> RescueParty.getElapsedRealtime());
RescueParty.resetAllThresholds();
+ FlagNamespaceUtils.resetKnownResetNamespacesFlagCounterForTest();
SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL,
Integer.toString(RescueParty.LEVEL_NONE));
@@ -278,10 +296,32 @@ public class RescuePartyTest {
SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
}
+ @Test
+ public void testNativeRescuePartyResets() {
+ doReturn(true).when(() -> SettingsToPropertiesMapper.isNativeFlagsResetPerformed());
+ doReturn(FAKE_RESET_NATIVE_NAMESPACES).when(
+ () -> SettingsToPropertiesMapper.getResetNativeCategories());
+
+ RescueParty.onSettingsProviderPublished(mMockContext);
+
+ verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+ FAKE_NATIVE_NAMESPACE1));
+ verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+ FAKE_NATIVE_NAMESPACE2));
+
+ ExtendedMockito.verify(
+ () -> DeviceConfig.setProperty(FlagNamespaceUtils.NAMESPACE_RESCUE_PARTY,
+ FlagNamespaceUtils.RESET_PLATFORM_PACKAGE_FLAG + 0,
+ FAKE_NATIVE_NAMESPACE1, /*makeDefault=*/true));
+ ExtendedMockito.verify(
+ () -> DeviceConfig.setProperty(FlagNamespaceUtils.NAMESPACE_RESCUE_PARTY,
+ FlagNamespaceUtils.RESET_PLATFORM_PACKAGE_FLAG + 1,
+ FAKE_NATIVE_NAMESPACE2, /*makeDefault=*/true));
+ }
+
private void verifySettingsResets(int resetMode) {
verify(() -> Settings.Global.resetToDefaultsAsUser(mMockContentResolver, null,
- resetMode,
- UserHandle.USER_SYSTEM));
+ resetMode, UserHandle.USER_SYSTEM));
verify(() -> Settings.Secure.resetToDefaultsAsUser(eq(mMockContentResolver), isNull(),
eq(resetMode), anyInt()));
}