Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c0993cf authored by Hongyi Zhang's avatar Hongyi Zhang
Browse files

RescueParty: Add a DeviceConfig killswitch

1. Add a killswitch DeviceConfig flag in case emergency rollback is
needed (e.g. PackageWatchdog doesn't behave correctly).
2. Register the namespace for native flag sync mapper so that we can
also use the flag to turn off native disaster recovery.

Test: Atest RescueParty & verified on local device
Bug: 149420506
Change-Id: I9a0b546c7229c8444947b522585dd2c5ed37a00b
parent c0cde525
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -399,6 +399,13 @@ public final class DeviceConfig {
    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 =
+10 −0
Original line number Diff line number Diff line
@@ -99,6 +99,8 @@ public class RescueParty {
    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 @@ public class RescueParty {
            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");
+1 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ public class SettingsToPropertiesMapper {
    @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,
+24 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ public class RescuePartyTest {
    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 @@ public class RescuePartyTest {

    @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,
@@ -326,6 +334,22 @@ public class RescuePartyTest {
                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING));
    }

    @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);