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

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

Merge "Records checkpoints for shutdown/reboot calls"

parents cf1a5e3a 07bf1ddd
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -3208,6 +3208,7 @@ public final class PowerManagerService extends SystemService
                // If we're stuck in a really low-level reboot loop, and a
                // rescue party is trying to prompt the user for a factory data
                // reset, we must GET TO DA CHOPPA!
                // No check point from ShutdownCheckPoints will be dumped at this state.
                PowerManagerService.lowLevelReboot(reason);
            } else {
                throw new IllegalStateException("Too early to call shutdown() or reboot()");
@@ -5114,6 +5115,7 @@ public final class PowerManagerService extends SystemService
                mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
            }

            ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
            final long ident = Binder.clearCallingIdentity();
            try {
                shutdownOrRebootInternal(HALT_MODE_REBOOT, confirm, reason, wait);
@@ -5132,10 +5134,11 @@ public final class PowerManagerService extends SystemService
        public void rebootSafeMode(boolean confirm, boolean wait) {
            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);

            String reason = PowerManager.REBOOT_SAFE_MODE;
            ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
            final long ident = Binder.clearCallingIdentity();
            try {
                shutdownOrRebootInternal(HALT_MODE_REBOOT_SAFE_MODE, confirm,
                        PowerManager.REBOOT_SAFE_MODE, wait);
                shutdownOrRebootInternal(HALT_MODE_REBOOT_SAFE_MODE, confirm, reason, wait);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
@@ -5151,6 +5154,7 @@ public final class PowerManagerService extends SystemService
        public void shutdown(boolean confirm, String reason, boolean wait) {
            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);

            ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
            final long ident = Binder.clearCallingIdentity();
            try {
                shutdownOrRebootInternal(HALT_MODE_SHUTDOWN, confirm, reason, wait);
+29 −21
Original line number Diff line number Diff line
@@ -90,18 +90,19 @@ public final class ShutdownCheckPoints {
    }

    /** Records the stack trace of this {@link Thread} as a shutdown check point. */
    public static void recordCheckPoint() {
        INSTANCE.recordCheckPointInternal();
    public static void recordCheckPoint(@Nullable String reason) {
        INSTANCE.recordCheckPointInternal(reason);
    }

    /** Records the pid of the caller process as a shutdown check point. */
    public static void recordCheckPoint(int callerProcessId) {
        INSTANCE.recordCheckPointInternal(callerProcessId);
    public static void recordCheckPoint(int callerProcessId, @Nullable String reason) {
        INSTANCE.recordCheckPointInternal(callerProcessId, reason);
    }

    /** Records the {@link android.content.Intent} name and package as a shutdown check point. */
    public static void recordCheckPoint(String intentName, String packageName) {
        INSTANCE.recordCheckPointInternal(intentName, packageName);
    public static void recordCheckPoint(
            String intentName, String packageName, @Nullable String reason) {
        INSTANCE.recordCheckPointInternal(intentName, packageName, reason);
    }

    /** Serializes the recorded check points and writes them to given {@code printWriter}. */
@@ -119,24 +120,24 @@ public final class ShutdownCheckPoints {
    }

    @VisibleForTesting
    void recordCheckPointInternal() {
        recordCheckPointInternal(new SystemServerCheckPoint(mInjector));
    void recordCheckPointInternal(@Nullable String reason) {
        recordCheckPointInternal(new SystemServerCheckPoint(mInjector, reason));
        Slog.v(TAG, "System server shutdown checkpoint recorded");
    }

    @VisibleForTesting
    void recordCheckPointInternal(int callerProcessId) {
    void recordCheckPointInternal(int callerProcessId, @Nullable String reason) {
        recordCheckPointInternal(callerProcessId == Process.myPid()
                ? new SystemServerCheckPoint(mInjector)
                : new BinderCheckPoint(mInjector, callerProcessId));
                ? new SystemServerCheckPoint(mInjector, reason)
                : new BinderCheckPoint(mInjector, callerProcessId, reason));
        Slog.v(TAG, "Binder shutdown checkpoint recorded with pid=" + callerProcessId);
    }

    @VisibleForTesting
    void recordCheckPointInternal(String intentName, String packageName) {
    void recordCheckPointInternal(String intentName, String packageName, @Nullable String reason) {
        recordCheckPointInternal("android".equals(packageName)
                ? new SystemServerCheckPoint(mInjector)
                : new IntentCheckPoint(mInjector, intentName, packageName));
                ? new SystemServerCheckPoint(mInjector, reason)
                : new IntentCheckPoint(mInjector, intentName, packageName, reason));
        Slog.v(TAG, String.format("Shutdown intent checkpoint recorded intent=%s from package=%s",
                intentName, packageName));
    }
@@ -182,14 +183,20 @@ public final class ShutdownCheckPoints {
    private abstract static class CheckPoint {

        private final long mTimestamp;
        @Nullable private final String mReason;

        CheckPoint(Injector injector) {
        CheckPoint(Injector injector, @Nullable String reason) {
            mTimestamp = injector.currentTimeMillis();
            mReason = reason;
        }

        final void dump(PrintWriter printWriter) {
            printWriter.print("Shutdown request from ");
            printWriter.print(getOrigin());
            if (mReason != null) {
                printWriter.print(" for reason ");
                printWriter.print(mReason);
            }
            printWriter.print(" at ");
            printWriter.print(DATE_FORMAT.format(new Date(mTimestamp)));
            printWriter.println(" (epoch=" + mTimestamp + ")");
@@ -206,8 +213,8 @@ public final class ShutdownCheckPoints {

        private final StackTraceElement[] mStackTraceElements;

        SystemServerCheckPoint(Injector injector) {
            super(injector);
        SystemServerCheckPoint(Injector injector, @Nullable String reason) {
            super(injector, reason);
            mStackTraceElements = Thread.currentThread().getStackTrace();
        }

@@ -263,8 +270,8 @@ public final class ShutdownCheckPoints {
        private final int mCallerProcessId;
        private final IActivityManager mActivityManager;

        BinderCheckPoint(Injector injector, int callerProcessId) {
            super(injector);
        BinderCheckPoint(Injector injector, int callerProcessId, @Nullable String reason) {
            super(injector, reason);
            mCallerProcessId = callerProcessId;
            mActivityManager = injector.activityManager();
        }
@@ -307,8 +314,9 @@ public final class ShutdownCheckPoints {
        private final String mIntentName;
        private final String mPackageName;

        IntentCheckPoint(Injector injector, String intentName, String packageName) {
            super(injector);
        IntentCheckPoint(
                Injector injector, String intentName, String packageName, @Nullable String reason) {
            super(injector, reason);
            mIntentName = intentName;
            mPackageName = packageName;
        }
+5 −1
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ public final class ShutdownThread extends Thread {
    private static final int RADIOS_STATE_POLL_SLEEP_MS = 100;
    // maximum time we wait for the shutdown broadcast before going on.
    private static final int MAX_BROADCAST_TIME = 10 * 1000;
    private static final int MAX_CHECK_POINTS_DUMP_WAIT_TIME = 20 * 1000;
    private static final int MAX_CHECK_POINTS_DUMP_WAIT_TIME = 10 * 1000;
    private static final int MAX_RADIO_WAIT_TIME = 12 * 1000;
    private static final int MAX_UNCRYPT_WAIT_TIME = 15 * 60 * 1000;
    // constants for progress bar. the values are roughly estimated based on timeout.
@@ -165,6 +165,10 @@ public final class ShutdownThread extends Thread {
            }
        }

        // Add checkpoint for this shutdown attempt. The user might still cancel the dialog, but
        // this point preserves the system trace of the trigger point of the ShutdownThread.
        ShutdownCheckPoints.recordCheckPoint(/* reason= */ null);

        final int longPressBehavior = context.getResources().getInteger(
                        com.android.internal.R.integer.config_longPressOnPowerBehavior);
        final int resourceId = mRebootSafeMode
+9 −4
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ import com.android.server.UiThread;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.notification.NotificationDelegate;
import com.android.server.policy.GlobalActionsProvider;
import com.android.server.power.ShutdownCheckPoints;
import com.android.server.power.ShutdownThread;

import java.io.FileDescriptor;
@@ -1182,13 +1183,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
    @Override
    public void shutdown() {
        enforceStatusBarService();
        String reason = PowerManager.SHUTDOWN_USER_REQUESTED;
        ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.prepareForPossibleShutdown();
            // ShutdownThread displays UI, so give it a UI context.
            mHandler.post(() ->
                    ShutdownThread.shutdown(getUiContext(),
                        PowerManager.SHUTDOWN_USER_REQUESTED, false));
                    ShutdownThread.shutdown(getUiContext(), reason, false));
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
@@ -1200,6 +1202,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
    @Override
    public void reboot(boolean safeMode) {
        enforceStatusBarService();
        String reason = safeMode
                ? PowerManager.REBOOT_SAFE_MODE
                : PowerManager.SHUTDOWN_USER_REQUESTED;
        ShutdownCheckPoints.recordCheckPoint(Binder.getCallingPid(), reason);
        long identity = Binder.clearCallingIdentity();
        try {
            mNotificationDelegate.prepareForPossibleShutdown();
@@ -1208,8 +1214,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
                if (safeMode) {
                    ShutdownThread.rebootSafeMode(getUiContext(), true);
                } else {
                    ShutdownThread.reboot(getUiContext(),
                            PowerManager.SHUTDOWN_USER_REQUESTED, false);
                    ShutdownThread.reboot(getUiContext(), reason, false);
                }
            });
        } finally {
+14 −0
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
import com.android.server.am.PendingIntentRecord;
import com.android.server.pm.InstantAppResolver;
import com.android.server.power.ShutdownCheckPoints;
import com.android.server.uri.NeededUriGrants;
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
import com.android.server.wm.ActivityStackSupervisor.PendingActivityLaunch;
@@ -647,6 +648,19 @@ class ActivityStarter {
                mRequest.resolveActivity(mSupervisor);
            }

            // Add checkpoint for this shutdown or reboot attempt, so we can record the original
            // intent action and package name.
            if (mRequest.intent != null) {
                String intentAction = mRequest.intent.getAction();
                String callingPackage = mRequest.callingPackage;
                if (intentAction != null && callingPackage != null
                        && (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
                                || Intent.ACTION_SHUTDOWN.equals(intentAction)
                                || Intent.ACTION_REBOOT.equals(intentAction))) {
                    ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
                }
            }

            int res;
            synchronized (mService.mGlobalLock) {
                final boolean globalConfigWillChange = mRequest.globalConfig != null
Loading