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

Commit 4c1adfc5 authored by Bubble Fang's avatar Bubble Fang Committed by Gerrit Code Review
Browse files

Merge "Revert "[CrashRecovery] Refactor SystemProperties as api"" into main

parents ddaefbc0 ef811dd8
Loading
Loading
Loading
Loading
+22 −15
Original line number Diff line number Diff line
@@ -33,12 +33,12 @@ import android.os.Looper;
import android.os.Process;
import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.sysprop.CrashRecoveryProperties;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.LongArrayQueue;
import android.util.MathUtils;
import android.util.Slog;
import android.util.Xml;

@@ -130,6 +130,16 @@ public class PackageWatchdog {
    static final int DEFAULT_BOOT_LOOP_TRIGGER_COUNT = 5;
    static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10);

    // These properties track individual system server boot events, and are reset once the boot
    // threshold is met, or the boot loop trigger window is exceeded between boot events.
    private static final String PROP_RESCUE_BOOT_COUNT = "sys.rescue_boot_count";
    private static final String PROP_RESCUE_BOOT_START = "sys.rescue_boot_start";

    // These properties track multiple calls made to observers tracking boot loops. They are reset
    // when the de-escalation window is exceeded between boot events.
    private static final String PROP_BOOT_MITIGATION_WINDOW_START = "sys.boot_mitigation_start";
    private static final String PROP_BOOT_MITIGATION_COUNT = "sys.boot_mitigation_count";

    private long mNumberOfNativeCrashPollsRemaining;

    private static final int DB_VERSION = 1;
@@ -1693,44 +1703,41 @@ public class PackageWatchdog {
        }

        private int getCount() {
            return CrashRecoveryProperties.rescueBootCount().orElse(0);
            return SystemProperties.getInt(PROP_RESCUE_BOOT_COUNT, 0);
        }

        private void setCount(int count) {
            CrashRecoveryProperties.rescueBootCount(count);
            SystemProperties.set(PROP_RESCUE_BOOT_COUNT, Integer.toString(count));
        }

        public long getStart() {
            return CrashRecoveryProperties.rescueBootStart().orElse(0L);
            return SystemProperties.getLong(PROP_RESCUE_BOOT_START, 0);
        }

        public int getMitigationCount() {
            return CrashRecoveryProperties.bootMitigationCount().orElse(0);
            return SystemProperties.getInt(PROP_BOOT_MITIGATION_COUNT, 0);
        }

        public void setStart(long start) {
            CrashRecoveryProperties.rescueBootStart(getStartTime(start));
            setPropertyStart(PROP_RESCUE_BOOT_START, start);
        }

        public void setMitigationStart(long start) {
            CrashRecoveryProperties.bootMitigationStart(getStartTime(start));
            setPropertyStart(PROP_BOOT_MITIGATION_WINDOW_START, start);
        }

        public long getMitigationStart() {
            return CrashRecoveryProperties.bootMitigationStart().orElse(0L);
            return SystemProperties.getLong(PROP_BOOT_MITIGATION_WINDOW_START, 0);
        }

        public void setMitigationCount(int count) {
            CrashRecoveryProperties.bootMitigationCount(count);
        }

        private static long constrain(long amount, long low, long high) {
            return amount < low ? low : (amount > high ? high : amount);
            SystemProperties.set(PROP_BOOT_MITIGATION_COUNT, Integer.toString(count));
        }

        public long getStartTime(long start) {
        public void setPropertyStart(String property, long start) {
            final long now = mSystemClock.uptimeMillis();
            return constrain(start, 0, now);
            final long newStart = MathUtils.constrain(start, 0, now);
            SystemProperties.set(property, Long.toString(newStart));
        }

        public void saveMitigationCountToMetadata() {
+17 −10
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.sysprop.CrashRecoveryProperties;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.ExceptionUtils;
@@ -75,6 +74,12 @@ import java.util.concurrent.TimeUnit;
 * @hide
 */
public class RescueParty {
    @VisibleForTesting
    static final String PROP_ENABLE_RESCUE = "persist.sys.enable_rescue";
    static final String PROP_ATTEMPTING_FACTORY_RESET = "sys.attempting_factory_reset";
    static final String PROP_ATTEMPTING_REBOOT = "sys.attempting_reboot";
    static final String PROP_MAX_RESCUE_LEVEL_ATTEMPTED = "sys.max_rescue_level_attempted";
    static final String PROP_LAST_FACTORY_RESET_TIME_MS = "persist.sys.last_factory_reset";
    @VisibleForTesting
    static final int LEVEL_NONE = 0;
    @VisibleForTesting
@@ -88,6 +93,8 @@ public class RescueParty {
    @VisibleForTesting
    static final int LEVEL_FACTORY_RESET = 5;
    @VisibleForTesting
    static final String PROP_RESCUE_BOOT_COUNT = "sys.rescue_boot_count";
    @VisibleForTesting
    static final String TAG = "RescueParty";
    @VisibleForTesting
    static final long DEFAULT_OBSERVING_DURATION_MS = TimeUnit.DAYS.toMillis(2);
@@ -124,7 +131,7 @@ public class RescueParty {

    private static boolean isDisabled() {
        // Check if we're explicitly enabled for testing
        if (CrashRecoveryProperties.enableRescueParty().orElse(false)) {
        if (SystemProperties.getBoolean(PROP_ENABLE_RESCUE, false)) {
            return false;
        }

@@ -170,11 +177,11 @@ public class RescueParty {
    }

    static boolean isFactoryResetPropertySet() {
        return CrashRecoveryProperties.attemptingFactoryReset().orElse(false);
        return SystemProperties.getBoolean(PROP_ATTEMPTING_FACTORY_RESET, false);
    }

    static boolean isRebootPropertySet() {
        return CrashRecoveryProperties.attemptingReboot().orElse(false);
        return SystemProperties.getBoolean(PROP_ATTEMPTING_REBOOT, false);
    }

    /**
@@ -432,7 +439,7 @@ public class RescueParty {
            case LEVEL_WARM_REBOOT:
                // Request the reboot from a separate thread to avoid deadlock on PackageWatchdog
                // when device shutting down.
                CrashRecoveryProperties.attemptingReboot(true);
                SystemProperties.set(PROP_ATTEMPTING_REBOOT, "true");
                runnable = () -> {
                    try {
                        PowerManager pm = context.getSystemService(PowerManager.class);
@@ -454,9 +461,9 @@ public class RescueParty {
                if (isRebootPropertySet()) {
                    break;
                }
                CrashRecoveryProperties.attemptingFactoryReset(true);
                SystemProperties.set(PROP_ATTEMPTING_FACTORY_RESET, "true");
                long now = System.currentTimeMillis();
                CrashRecoveryProperties.lastFactoryResetTimeMs(now);
                SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(now));
                runnable = new Runnable() {
                    @Override
                    public void run() {
@@ -506,10 +513,10 @@ public class RescueParty {
    private static void resetAllSettingsIfNecessary(Context context, int mode,
            int level) throws Exception {
        // No need to reset Settings again if they are already reset in the current level once.
        if (CrashRecoveryProperties.maxRescueLevelAttempted().orElse(LEVEL_NONE) >= level) {
        if (SystemProperties.getInt(PROP_MAX_RESCUE_LEVEL_ATTEMPTED, LEVEL_NONE) >= level) {
            return;
        }
        CrashRecoveryProperties.maxRescueLevelAttempted(level);
        SystemProperties.set(PROP_MAX_RESCUE_LEVEL_ATTEMPTED, Integer.toString(level));
        // Try our best to reset all settings possible, and once finished
        // rethrow any exception that we encountered
        Exception res = null;
@@ -724,7 +731,7 @@ public class RescueParty {
         * Will return {@code false} if a factory reset was already offered recently.
         */
        private boolean shouldThrottleReboot() {
            Long lastResetTime = CrashRecoveryProperties.lastFactoryResetTimeMs().orElse(0L);
            Long lastResetTime = SystemProperties.getLong(PROP_LAST_FACTORY_RESET_TIME_MS, 0);
            long now = System.currentTimeMillis();
            long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG,
                    DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN);
+2 −2
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.PowerManager;
import android.os.SystemProperties;
import android.sysprop.CrashRecoveryProperties;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
@@ -71,6 +70,7 @@ import java.util.function.Consumer;
final class RollbackPackageHealthObserver implements PackageHealthObserver {
    private static final String TAG = "RollbackPackageHealthObserver";
    private static final String NAME = "rollback-observer";
    private static final String PROP_ATTEMPTING_REBOOT = "sys.attempting_reboot";
    private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_PERSISTENT
            | ApplicationInfo.FLAG_SYSTEM;

@@ -450,7 +450,7 @@ final class RollbackPackageHealthObserver implements PackageHealthObserver {
                markStagedSessionHandled(rollback.getRollbackId());
                // Wait for all pending staged sessions to get handled before rebooting.
                if (isPendingStagedSessionsEmpty()) {
                    CrashRecoveryProperties.attemptingReboot(true);
                    SystemProperties.set(PROP_ATTEMPTING_REBOOT, "true");
                    mContext.getSystemService(PowerManager.class).reboot("Rollback staged install");
                }
            }
+0 −1
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ android_test {
        "mockito-target-extended-minus-junit4",
        "platform-compat-test-rules",
        "platform-test-annotations",
        "PlatformProperties",
        "service-blobstore",
        "service-jobscheduler",
        "service-permission.impl",
+19 −19
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.sysprop.CrashRecoveryProperties;
import android.util.ArraySet;

import com.android.dx.mockito.inline.extended.ExtendedMockito;
@@ -96,6 +95,7 @@ public class RescuePartyTest {
            "persist.device_config.configuration.disable_rescue_party";
    private static final String PROP_DISABLE_FACTORY_RESET_FLAG =
            "persist.device_config.configuration.disable_rescue_party_factory_reset";
    private static final String PROP_LAST_FACTORY_RESET_TIME_MS = "persist.sys.last_factory_reset";

    private static final int THROTTLING_DURATION_MIN = 10;

@@ -211,8 +211,8 @@ public class RescuePartyTest {

        doReturn(CURRENT_NETWORK_TIME_MILLIS).when(() -> RescueParty.getElapsedRealtime());

        CrashRecoveryProperties.rescueBootCount(0);
        CrashRecoveryProperties.enableRescueParty(true);
        SystemProperties.set(RescueParty.PROP_RESCUE_BOOT_COUNT, Integer.toString(0));
        SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true));
        SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(false));
    }

@@ -255,7 +255,7 @@ public class RescuePartyTest {
        noteBoot(4);
        assertTrue(RescueParty.isRebootPropertySet());

        CrashRecoveryProperties.attemptingReboot(false);
        SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false));
        noteBoot(5);
        assertTrue(RescueParty.isFactoryResetPropertySet());
    }
@@ -280,7 +280,7 @@ public class RescuePartyTest {
        noteAppCrash(4, true);
        assertTrue(RescueParty.isRebootPropertySet());

        CrashRecoveryProperties.attemptingReboot(false);
        SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false));
        noteAppCrash(5, true);
        assertTrue(RescueParty.isFactoryResetPropertySet());
    }
@@ -438,7 +438,7 @@ public class RescuePartyTest {
            noteBoot(i + 1);
        }
        assertFalse(RescueParty.isFactoryResetPropertySet());
        CrashRecoveryProperties.attemptingReboot(false);
        SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false));
        noteBoot(LEVEL_FACTORY_RESET + 1);
        assertTrue(RescueParty.isAttemptingFactoryReset());
        assertTrue(RescueParty.isFactoryResetPropertySet());
@@ -456,7 +456,7 @@ public class RescuePartyTest {
        noteBoot(mitigationCount++);
        assertFalse(RescueParty.isFactoryResetPropertySet());
        noteBoot(mitigationCount++);
        CrashRecoveryProperties.attemptingReboot(false);
        SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false));
        noteBoot(mitigationCount + 1);
        assertTrue(RescueParty.isAttemptingFactoryReset());
        assertTrue(RescueParty.isFactoryResetPropertySet());
@@ -464,10 +464,10 @@ public class RescuePartyTest {

    @Test
    public void testThrottlingOnBootFailures() {
        CrashRecoveryProperties.attemptingReboot(false);
        SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false));
        long now = System.currentTimeMillis();
        long beforeTimeout = now - TimeUnit.MINUTES.toMillis(THROTTLING_DURATION_MIN - 1);
        CrashRecoveryProperties.lastFactoryResetTimeMs(beforeTimeout);
        SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(beforeTimeout));
        for (int i = 1; i <= LEVEL_FACTORY_RESET; i++) {
            noteBoot(i);
        }
@@ -476,10 +476,10 @@ public class RescuePartyTest {

    @Test
    public void testThrottlingOnAppCrash() {
        CrashRecoveryProperties.attemptingReboot(false);
        SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false));
        long now = System.currentTimeMillis();
        long beforeTimeout = now - TimeUnit.MINUTES.toMillis(THROTTLING_DURATION_MIN - 1);
        CrashRecoveryProperties.lastFactoryResetTimeMs(beforeTimeout);
        SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(beforeTimeout));
        for (int i = 0; i <= LEVEL_FACTORY_RESET; i++) {
            noteAppCrash(i + 1, true);
        }
@@ -488,10 +488,10 @@ public class RescuePartyTest {

    @Test
    public void testNotThrottlingAfterTimeoutOnBootFailures() {
        CrashRecoveryProperties.attemptingReboot(false);
        SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false));
        long now = System.currentTimeMillis();
        long afterTimeout = now - TimeUnit.MINUTES.toMillis(THROTTLING_DURATION_MIN + 1);
        CrashRecoveryProperties.lastFactoryResetTimeMs(afterTimeout);
        SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(afterTimeout));
        for (int i = 1; i <= LEVEL_FACTORY_RESET; i++) {
            noteBoot(i);
        }
@@ -499,10 +499,10 @@ public class RescuePartyTest {
    }
    @Test
    public void testNotThrottlingAfterTimeoutOnAppCrash() {
        CrashRecoveryProperties.attemptingReboot(false);
        SystemProperties.set(RescueParty.PROP_ATTEMPTING_REBOOT, Boolean.toString(false));
        long now = System.currentTimeMillis();
        long afterTimeout = now - TimeUnit.MINUTES.toMillis(THROTTLING_DURATION_MIN + 1);
        CrashRecoveryProperties.lastFactoryResetTimeMs(afterTimeout);
        SystemProperties.set(PROP_LAST_FACTORY_RESET_TIME_MS, Long.toString(afterTimeout));
        for (int i = 0; i <= LEVEL_FACTORY_RESET; i++) {
            noteAppCrash(i + 1, true);
        }
@@ -525,26 +525,26 @@ public class RescuePartyTest {

    @Test
    public void testExplicitlyEnablingAndDisablingRescue() {
        CrashRecoveryProperties.enableRescueParty(false);
        SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false));
        SystemProperties.set(PROP_DISABLE_RESCUE, Boolean.toString(true));
        assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false);

        CrashRecoveryProperties.enableRescueParty(true);
        SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true));
        assertTrue(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1));
    }

    @Test
    public void testDisablingRescueByDeviceConfigFlag() {
        CrashRecoveryProperties.enableRescueParty(false);
        SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(false));
        SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(true));

        assertEquals(RescuePartyObserver.getInstance(mMockContext).execute(sFailingPackage,
                PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING, 1), false);

        // Restore the property value initialized in SetUp()
        CrashRecoveryProperties.enableRescueParty(true);
        SystemProperties.set(RescueParty.PROP_ENABLE_RESCUE, Boolean.toString(true));
        SystemProperties.set(PROP_DEVICE_CONFIG_DISABLE_FLAG, Boolean.toString(false));
    }