Merge "RescueParty: Add a DeviceConfig killswitch" into rvc-dev
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index aa511cc..fb81d67 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -399,6 +399,13 @@
public static final String NAMESPACE_CONNECTIVITY_THERMAL_POWER_MANAGER =
"connectivity_thermal_power_manager";
+ /**
+ * Namespace for configuration related features.
+ *
+ * @hide
+ */
+ public static final String NAMESPACE_CONFIGURATION = "configuration";
+
private static final Object sLock = new Object();
@GuardedBy("sLock")
private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners =
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 80036bb..808d322 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -99,6 +99,8 @@
private static final String PROP_DISABLE_RESCUE = "persist.sys.disable_rescue";
private static final String PROP_VIRTUAL_DEVICE = "ro.hardware.virtual_device";
+ private static final String DEVICE_CONFIG_DISABLE_FLAG = "disable_rescue_party";
+
private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_PERSISTENT
| ApplicationInfo.FLAG_SYSTEM;
@@ -114,6 +116,14 @@
return false;
}
+ // We're disabled if the DeviceConfig disable flag is set to true.
+ // This is in case that an emergency rollback of the feature is needed.
+ if (DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_CONFIGURATION, DEVICE_CONFIG_DISABLE_FLAG, false)) {
+ Slog.v(TAG, "Disabled because of DeviceConfig flag");
+ return true;
+ }
+
// We're disabled on all engineering devices
if (Build.IS_ENG) {
Slog.v(TAG, "Disabled because of eng build");
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 0a8e70c..bac7565 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -80,6 +80,7 @@
@VisibleForTesting
static final String[] sDeviceConfigScopes = new String[] {
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT,
+ DeviceConfig.NAMESPACE_CONFIGURATION,
DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
DeviceConfig.NAMESPACE_INTELLIGENCE_CONTENT_SUGGESTIONS,
DeviceConfig.NAMESPACE_MEDIA_NATIVE,
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index c94bb87..5c82200 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -79,6 +79,7 @@
private static final String CALLING_PACKAGE2 = "com.package.name2";
private static final String NAMESPACE1 = "namespace1";
private static final String NAMESPACE2 = "namespace2";
+ private static final String DISABLE_RESCUE_PARTY_FLAG = "disable_rescue_party";
private MockitoSession mSession;
private HashMap<String, String> mSystemSettingsMap;
@@ -316,6 +317,13 @@
@Test
public void testExplicitlyEnablingAndDisablingRescue() {
+ // mock the DeviceConfig get call to avoid hitting
+ // android.permission.READ_DEVICE_CONFIG when calling real DeviceConfig.
+ doReturn(true)
+ .when(() -> DeviceConfig.getBoolean(
+ eq(DeviceConfig.NAMESPACE_CONFIGURATION),
+ eq(DISABLE_RESCUE_PARTY_FLAG),
+ eq(false)));
SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false));
SystemProperties.set(PROP_DISABLE_RESCUE, Boolean.toString(true));
assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
@@ -327,6 +335,22 @@
}
@Test
+ public void testDisablingRescueByDeviceConfigFlag() {
+ doReturn(true)
+ .when(() -> DeviceConfig.getBoolean(
+ eq(DeviceConfig.NAMESPACE_CONFIGURATION),
+ eq(DISABLE_RESCUE_PARTY_FLAG),
+ eq(false)));
+ SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false));
+
+ assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
+ PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING), false);
+
+ // Restore the property value initalized in SetUp()
+ SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true));
+ }
+
+ @Test
public void testHealthCheckLevels() {
RescuePartyObserver observer = RescuePartyObserver.getInstance(mMockContext);