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

Commit 05044fd8 authored by Alexei Nicoara's avatar Alexei Nicoara Committed by Automerger Merge Worker
Browse files

Merge "Deprecating flags and settings resets in RescueParty" into main am: 25a67958

parents d8f1e31b 25a67958
Loading
Loading
Loading
Loading
+275 −159
Original line number Diff line number Diff line
@@ -241,6 +241,7 @@ public class RescueParty {
     * opportunity to reset any settings depending on our rescue level.
     */
    public static void onSettingsProviderPublished(Context context) {
        if (!Flags.deprecateFlagsAndSettingsResets()) {
            handleNativeRescuePartyResets();
            ContentResolver contentResolver = context.getContentResolver();
            DeviceConfig.setMonitorCallback(
@@ -248,6 +249,7 @@ public class RescueParty {
                    Executors.newSingleThreadExecutor(),
                    new RescuePartyMonitorCallback(context));
        }
    }


    /**
@@ -256,6 +258,7 @@ public class RescueParty {
     * on modules of newer versions.
     */
    public static void resetDeviceConfigForPackages(List<String> packageNames) {
        if (!Flags.deprecateFlagsAndSettingsResets()) {
            if (packageNames == null) {
                return;
            }
@@ -299,9 +302,11 @@ public class RescueParty {
                }
            }
        }
    }

    private static Set<String> getPresetNamespacesForPackages(List<String> packageNames) {
        Set<String> resultSet = new ArraySet<String>();
        if (!Flags.deprecateFlagsAndSettingsResets()) {
            try {
                String flagVal = DeviceConfig.getString(NAMESPACE_CONFIGURATION,
                        NAMESPACE_TO_PACKAGE_MAPPING_FLAG, "");
@@ -310,12 +315,12 @@ public class RescueParty {
                    if (TextUtils.isEmpty(mappingEntries[i])) {
                        continue;
                    }
                String[] splittedEntry = mappingEntries[i].split(":");
                if (splittedEntry.length != 2) {
                    String[] splitEntry = mappingEntries[i].split(":");
                    if (splitEntry.length != 2) {
                        throw new RuntimeException("Invalid mapping entry: " + mappingEntries[i]);
                    }
                String namespace = splittedEntry[0];
                String packageName = splittedEntry[1];
                    String namespace = splitEntry[0];
                    String packageName = splitEntry[1];

                    if (packageNames.contains(packageName)) {
                        resultSet.add(namespace);
@@ -327,6 +332,9 @@ public class RescueParty {
            } finally {
                return resultSet;
            }
        } else {
            return resultSet;
        }
    }

    @VisibleForTesting
@@ -342,20 +350,27 @@ public class RescueParty {
        }

        public void onNamespaceUpdate(@NonNull String updatedNamespace) {
            if (!Flags.deprecateFlagsAndSettingsResets()) {
                startObservingPackages(mContext, updatedNamespace);
            }
        }

        public void onDeviceConfigAccess(@NonNull String callingPackage,
                @NonNull String namespace) {

            if (!Flags.deprecateFlagsAndSettingsResets()) {
                RescuePartyObserver.getInstance(mContext).recordDeviceConfigAccess(
                        callingPackage,
                        namespace);
            }
        }
    }

    private static void startObservingPackages(Context context, @NonNull String updatedNamespace) {
        if (!Flags.deprecateFlagsAndSettingsResets()) {
            RescuePartyObserver rescuePartyObserver = RescuePartyObserver.getInstance(context);
        Set<String> callingPackages = rescuePartyObserver.getCallingPackagesSet(updatedNamespace);
            Set<String> callingPackages = rescuePartyObserver.getCallingPackagesSet(
                    updatedNamespace);
            if (callingPackages == null) {
                return;
            }
@@ -368,10 +383,13 @@ public class RescueParty {
                    callingPackageList,
                    DEFAULT_OBSERVING_DURATION_MS);
        }
    }

    private static void handleNativeRescuePartyResets() {
        if (!Flags.deprecateFlagsAndSettingsResets()) {
            if (SettingsToPropertiesMapper.isNativeFlagsResetPerformed()) {
            String[] resetNativeCategories = SettingsToPropertiesMapper.getResetNativeCategories();
                String[] resetNativeCategories =
                        SettingsToPropertiesMapper.getResetNativeCategories();
                for (int i = 0; i < resetNativeCategories.length; i++) {
                    // Don't let RescueParty reset the namespace for RescueParty switches.
                    if (NAMESPACE_CONFIGURATION.equals(resetNativeCategories[i])) {
@@ -382,6 +400,7 @@ public class RescueParty {
                }
            }
        }
    }

    private static int getMaxRescueLevel(boolean mayPerformReboot) {
        if (Flags.recoverabilityDetection()) {
@@ -400,6 +419,13 @@ public class RescueParty {
        }
    }

    private static int getMaxRescueLevel() {
        if (!SystemProperties.getBoolean(PROP_DISABLE_FACTORY_RESET_FLAG, false)) {
            return Level.factoryReset();
        }
        return Level.reboot();
    }

    /**
     * Get the rescue level to perform if this is the n-th attempt at mitigating failure.
     *
@@ -409,6 +435,7 @@ public class RescueParty {
     * @return the rescue level for the n-th mitigation attempt.
     */
    private static int getRescueLevel(int mitigationCount, boolean mayPerformReboot) {
        if (!Flags.deprecateFlagsAndSettingsResets()) {
            if (mitigationCount == 1) {
                return LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS;
            } else if (mitigationCount == 2) {
@@ -423,6 +450,16 @@ public class RescueParty {
                Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount);
                return LEVEL_NONE;
            }
        } else {
            if (mitigationCount == 1) {
                return Level.reboot();
            } else if (mitigationCount >= 2) {
                return Math.min(getMaxRescueLevel(), Level.factoryReset());
            } else {
                Slog.w(TAG, "Expected positive mitigation count, was " + mitigationCount);
                return LEVEL_NONE;
            }
        }
    }

    /**
@@ -465,6 +502,22 @@ public class RescueParty {
        }
    }

    /**
     * Get the rescue level to perform if this is the n-th attempt at mitigating failure.
     *
     * @param mitigationCount the mitigation attempt number (1 = first attempt etc.).
     * @return the rescue level for the n-th mitigation attempt.
     */
    private static @RescueLevels int getRescueLevel(int mitigationCount) {
        if (mitigationCount == 1) {
            return Level.reboot();
        } else if (mitigationCount >= 2) {
            return Math.min(getMaxRescueLevel(), Level.factoryReset());
        } else {
            return Level.none();
        }
    }

    private static void executeRescueLevel(Context context, @Nullable String failedPackage,
            int level) {
        Slog.w(TAG, "Attempting rescue level " + levelToString(level));
@@ -537,13 +590,22 @@ public class RescueParty {
                executeWarmReboot(context, level, failedPackage);
                break;
            case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
                resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS, level);
                if (!Flags.deprecateFlagsAndSettingsResets()) {
                    resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS,
                            level);
                }
                break;
            case RESCUE_LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
                resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES, level);
                if (!Flags.deprecateFlagsAndSettingsResets()) {
                    resetAllSettingsIfNecessary(context, Settings.RESET_MODE_UNTRUSTED_CHANGES,
                            level);
                }
                break;
            case RESCUE_LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
                resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS, level);
                if (!Flags.deprecateFlagsAndSettingsResets()) {
                    resetAllSettingsIfNecessary(context, Settings.RESET_MODE_TRUSTED_DEFAULTS,
                            level);
                }
                break;
            case RESCUE_LEVEL_FACTORY_RESET:
                // Before the completion of Reboot, if any crash happens then PackageWatchdog
@@ -560,6 +622,12 @@ public class RescueParty {

    private static void executeWarmReboot(Context context, int level,
            @Nullable String failedPackage) {
        if (Flags.deprecateFlagsAndSettingsResets()) {
            if (shouldThrottleReboot()) {
                return;
            }
        }

        // Request the reboot from a separate thread to avoid deadlock on PackageWatchdog
        // when device shutting down.
        setRebootProperty(true);
@@ -579,6 +647,11 @@ public class RescueParty {

    private static void executeFactoryReset(Context context, int level,
            @Nullable String failedPackage) {
        if (Flags.deprecateFlagsAndSettingsResets()) {
            if (shouldThrottleReboot()) {
                return;
            }
        }
        setFactoryResetProperty(true);
        long now = System.currentTimeMillis();
        setLastFactoryResetTimeMs(now);
@@ -655,6 +728,7 @@ public class RescueParty {

    private static void resetAllSettingsIfNecessary(Context context, int mode,
            int level) throws Exception {
        if (!Flags.deprecateFlagsAndSettingsResets()) {
            // No need to reset Settings again if they are already reset in the current level once.
            if (getMaxRescueLevelAttempted() >= level) {
                return;
@@ -681,6 +755,7 @@ public class RescueParty {
                throw res;
            }
        }
    }

    /**
     * Handle mitigation action for package failures. This observer will be register to Package
@@ -731,8 +806,12 @@ public class RescueParty {
            if (!isDisabled() && (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
                    || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING)) {
                if (Flags.recoverabilityDetection()) {
                    if (!Flags.deprecateFlagsAndSettingsResets()) {
                        return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
                                mayPerformReboot(failedPackage), failedPackage));
                    } else {
                        return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount));
                    }
                } else {
                    return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
                            mayPerformReboot(failedPackage)));
@@ -750,10 +829,17 @@ public class RescueParty {
            }
            if (failureReason == PackageWatchdog.FAILURE_REASON_APP_CRASH
                    || failureReason == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING) {
                final int level = Flags.recoverabilityDetection() ? getRescueLevel(mitigationCount,
                        mayPerformReboot(failedPackage), failedPackage)
                        : getRescueLevel(mitigationCount,
                                mayPerformReboot(failedPackage));
                final int level;
                if (Flags.recoverabilityDetection()) {
                    if (!Flags.deprecateFlagsAndSettingsResets()) {
                        level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage),
                                failedPackage);
                    } else {
                        level = getRescueLevel(mitigationCount);
                    }
                } else {
                    level = getRescueLevel(mitigationCount, mayPerformReboot(failedPackage));
                }
                executeRescueLevel(mContext,
                        failedPackage == null ? null : failedPackage.getPackageName(), level);
                return true;
@@ -787,8 +873,12 @@ public class RescueParty {
                return PackageHealthObserverImpact.USER_IMPACT_LEVEL_0;
            }
            if (Flags.recoverabilityDetection()) {
                if (!Flags.deprecateFlagsAndSettingsResets()) {
                    return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount,
                            true, /*failedPackage=*/ null));
                } else {
                    return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount));
                }
            } else {
                return mapRescueLevelToUserImpact(getRescueLevel(mitigationCount, true));
            }
@@ -800,9 +890,17 @@ public class RescueParty {
                return false;
            }
            boolean mayPerformReboot = !shouldThrottleReboot();
            final int level = Flags.recoverabilityDetection() ? getRescueLevel(mitigationCount,
                        mayPerformReboot, /*failedPackage=*/ null)
                        : getRescueLevel(mitigationCount, mayPerformReboot);
            final int level;
            if (Flags.recoverabilityDetection()) {
                if (!Flags.deprecateFlagsAndSettingsResets()) {
                    level = getRescueLevel(mitigationCount, mayPerformReboot,
                            /*failedPackage=*/ null);
                } else {
                    level = getRescueLevel(mitigationCount);
                }
            } else {
                level = getRescueLevel(mitigationCount, mayPerformReboot);
            }
            executeRescueLevel(mContext, /*failedPackage=*/ null, level);
            return true;
        }
@@ -828,18 +926,6 @@ public class RescueParty {
            return isPersistentSystemApp(failingPackage.getPackageName());
        }

        /**
         * Returns {@code true} if Rescue Party is allowed to attempt a reboot or factory reset.
         * Will return {@code false} if a factory reset was already offered recently.
         */
        private boolean shouldThrottleReboot() {
            Long lastResetTime = getLastFactoryResetTimeMs();
            long now = System.currentTimeMillis();
            long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG,
                    DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN);
            return now < lastResetTime + TimeUnit.MINUTES.toMillis(throttleDurationMin);
        }

        private boolean isPersistentSystemApp(@NonNull String packageName) {
            PackageManager pm = mContext.getPackageManager();
            try {
@@ -852,6 +938,7 @@ public class RescueParty {

        private synchronized void recordDeviceConfigAccess(@NonNull String callingPackage,
                @NonNull String namespace) {
            if (!Flags.deprecateFlagsAndSettingsResets()) {
                // Record it in calling packages to namespace map
                Set<String> namespaceSet = mCallingPackageNamespaceSetMap.get(callingPackage);
                if (namespaceSet == null) {
@@ -867,6 +954,7 @@ public class RescueParty {
                callingPackageSet.add(callingPackage);
                mNamespaceCallingPackageSetMap.put(namespace, callingPackageSet);
            }
        }

        private synchronized Set<String> getAffectedNamespaceSet(String failedPackage) {
            return mCallingPackageNamespaceSetMap.get(failedPackage);
@@ -881,6 +969,18 @@ public class RescueParty {
        }
    }

    /**
     * Returns {@code true} if Rescue Party is allowed to attempt a reboot or factory reset.
     * Will return {@code false} if a factory reset was already offered recently.
     */
    private static boolean shouldThrottleReboot() {
        Long lastResetTime = getLastFactoryResetTimeMs();
        long now = System.currentTimeMillis();
        long throttleDurationMin = SystemProperties.getLong(PROP_THROTTLE_DURATION_MIN_FLAG,
                DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN);
        return now < lastResetTime + TimeUnit.MINUTES.toMillis(throttleDurationMin);
    }

    private static int[] getAllUserIds() {
        int systemUserId = UserHandle.SYSTEM.getIdentifier();
        int[] userIds = { systemUserId };
@@ -919,6 +1019,22 @@ public class RescueParty {
        }
    }

    private static class Level {
        static int none() {
            return Flags.recoverabilityDetection() ? RESCUE_LEVEL_NONE : LEVEL_NONE;
        }

        static int reboot() {
            return Flags.recoverabilityDetection() ? RESCUE_LEVEL_WARM_REBOOT : LEVEL_WARM_REBOOT;
        }

        static int factoryReset() {
            return Flags.recoverabilityDetection()
                    ? RESCUE_LEVEL_FACTORY_RESET
                    : LEVEL_FACTORY_RESET;
        }
    }

    private static String levelToString(int level) {
        if (Flags.recoverabilityDetection()) {
            switch (level) {
+6 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.rollback;

import static android.crashrecovery.flags.Flags.deprecateFlagsAndSettingsResets;

import static com.android.server.rollback.RollbackManagerServiceImpl.sendFailure;

import android.Manifest;
@@ -623,8 +625,10 @@ class Rollback {
                parentSession.addChildSessionId(sessionId);
            }

            if (!deprecateFlagsAndSettingsResets()) {
                // Clear flags.
                RescueParty.resetDeviceConfigForPackages(packageNames);
            }

            Consumer<Intent> onResult = result -> {
                mHandler.post(() -> {
+105 −183

File changed.

Preview size limit exceeded, changes collapsed.