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

Commit 8dba8afc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Suppress RescueParty when active USB connection."

parents 586b6b2c d9574c7b
Loading
Loading
Loading
Loading
+57 −16
Original line number Diff line number Diff line
@@ -20,9 +20,12 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.UserInfo;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
import android.os.BatteryProperties;
import android.os.Build;
import android.os.IBatteryPropertiesListener;
import android.os.IBatteryPropertiesRegistrar;
import android.os.RecoverySystem;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -31,11 +34,15 @@ import android.provider.Settings;
import android.text.format.DateUtils;
import android.util.ExceptionUtils;
import android.util.MathUtils;
import android.util.MutableBoolean;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.util.ArrayUtils;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Utilities to help rescue the system from crash loops. Callers are expected to
 * report boot events and persistent app crashes, and if they happen frequently
@@ -66,24 +73,26 @@ public class RescueParty {

    private static boolean isDisabled() {
        // We're disabled on all engineering devices
        if (Build.IS_ENG) return true;
        if (Build.IS_ENG) {
            Slog.v(TAG, "Disabled because of eng build");
            return true;
        }

        // We're disabled on userdebug devices connected over USB, since that's
        // a decent signal that someone is actively trying to debug the device,
        // or that it's in a lab environment.
        if (Build.IS_USERDEBUG) {
            try {
                if (LocalServices.getService(BatteryManagerInternal.class)
                        .getPlugType() == BatteryManager.BATTERY_PLUGGED_USB) {
        if (Build.IS_USERDEBUG && isUsbActive()) {
            Slog.v(TAG, "Disabled because of active USB connection");
            return true;
                } else {
                }
            } catch (Throwable ignored) {
            }
        }

        // One last-ditch check
        return SystemProperties.getBoolean(PROP_DISABLE_RESCUE, false);
        if (SystemProperties.getBoolean(PROP_DISABLE_RESCUE, false)) {
            Slog.v(TAG, "Disabled because of manual property");
            return true;
        }

        return false;
    }

    /**
@@ -185,14 +194,14 @@ public class RescueParty {
        final ContentResolver resolver = context.getContentResolver();
        try {
            Settings.Global.resetToDefaultsAsUser(resolver, null, mode, UserHandle.USER_SYSTEM);
        } catch (Exception e) {
            res = new RuntimeException("Failed to reset global settings", e);
        } catch (Throwable t) {
            res = new RuntimeException("Failed to reset global settings", t);
        }
        for (int userId : getAllUserIds(context)) {
            try {
                Settings.Secure.resetToDefaultsAsUser(resolver, null, mode, userId);
            } catch (Exception e) {
                res = new RuntimeException("Failed to reset secure settings for " + userId, e);
            } catch (Throwable t) {
                res = new RuntimeException("Failed to reset secure settings for " + userId, t);
            }
        }
        if (res != null) {
@@ -314,6 +323,38 @@ public class RescueParty {
        return userIds;
    }

    /**
     * Hacky test to check if the device has an active USB connection, which is
     * a good proxy for someone doing local development work. It uses a low
     * level call since we may not have started {@link BatteryManager} yet.
     */
    private static boolean isUsbActive() {
        final MutableBoolean res = new MutableBoolean(false);
        final CountDownLatch latch = new CountDownLatch(1);
        final IBatteryPropertiesListener listener = new IBatteryPropertiesListener.Stub() {
            @Override
            public void batteryPropertiesChanged(BatteryProperties props) {
                res.value = props.chargerUsbOnline;
                latch.countDown();
            }
        };

        try {
            final IBatteryPropertiesRegistrar bpr = IBatteryPropertiesRegistrar.Stub
                    .asInterface(ServiceManager.getService("batteryproperties"));
            bpr.registerListener(listener);
            try {
                latch.await(5, TimeUnit.SECONDS);
            } finally {
                bpr.unregisterListener(listener);
            }
            return res.value;
        } catch (Throwable t) {
            Slog.w(TAG, "Failed to determine if device was on USB", t);
            return false;
        }
    }

    private static String levelToString(int level) {
        switch (level) {
            case LEVEL_NONE: return "NONE";