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

Commit 96208305 authored by Zimuzo Ezeozue's avatar Zimuzo Ezeozue Committed by Android (Google) Code Review
Browse files

Merge "Start Watchdog early during boot" into qt-dev

parents 04bd9f90 b065b15a
Loading
Loading
Loading
Loading
+19 −11
Original line number Original line Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.server;


import android.app.IActivityController;
import android.app.IActivityController;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter;
@@ -122,7 +121,6 @@ public class Watchdog extends Thread {
    /* This handler will be used to post message back onto the main thread */
    /* This handler will be used to post message back onto the main thread */
    final ArrayList<HandlerChecker> mHandlerCheckers = new ArrayList<>();
    final ArrayList<HandlerChecker> mHandlerCheckers = new ArrayList<>();
    final HandlerChecker mMonitorChecker;
    final HandlerChecker mMonitorChecker;
    ContentResolver mResolver;
    ActivityManagerService mActivity;
    ActivityManagerService mActivity;


    int mPhonePid;
    int mPhonePid;
@@ -138,6 +136,7 @@ public class Watchdog extends Thread {
        private final String mName;
        private final String mName;
        private final long mWaitMax;
        private final long mWaitMax;
        private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
        private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
        private final ArrayList<Monitor> mMonitorQueue = new ArrayList<Monitor>();
        private boolean mCompleted;
        private boolean mCompleted;
        private Monitor mCurrentMonitor;
        private Monitor mCurrentMonitor;
        private long mStartTime;
        private long mStartTime;
@@ -150,10 +149,17 @@ public class Watchdog extends Thread {
        }
        }


        void addMonitorLocked(Monitor monitor) {
        void addMonitorLocked(Monitor monitor) {
            mMonitors.add(monitor);
            // We don't want to update mMonitors when the Handler is in the middle of checking
            // all monitors. We will update mMonitors on the next schedule if it is safe
            mMonitorQueue.add(monitor);
        }
        }


        public void scheduleCheckLocked() {
        public void scheduleCheckLocked() {
            if (mCompleted) {
                // Safe to update monitors in queue, Handler is not in the middle of work
                mMonitors.addAll(mMonitorQueue);
                mMonitorQueue.clear();
            }
            if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) {
            if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) {
                // If the target looper has recently been polling, then
                // If the target looper has recently been polling, then
                // there is no reason to enqueue our checker on it since that
                // there is no reason to enqueue our checker on it since that
@@ -213,6 +219,10 @@ public class Watchdog extends Thread {


        @Override
        @Override
        public void run() {
        public void run() {
            // Once we get here, we ensure that mMonitors does not change even if we call
            // #addMonitorLocked because we first add the new monitors to mMonitorQueue and
            // move them to mMonitors on the next schedule when mCompleted is true, at which
            // point we have completed execution of this method.
            final int size = mMonitors.size();
            final int size = mMonitors.size();
            for (int i = 0 ; i < size ; i++) {
            for (int i = 0 ; i < size ; i++) {
                synchronized (Watchdog.this) {
                synchronized (Watchdog.this) {
@@ -304,10 +314,13 @@ public class Watchdog extends Thread {
                DEFAULT_TIMEOUT > ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
                DEFAULT_TIMEOUT > ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
    }
    }


    /**
     * Registers a {@link BroadcastReceiver} to listen to reboot broadcasts and trigger reboot.
     * Should be called during boot after the ActivityManagerService is up and registered
     * as a system service so it can handle registration of a {@link BroadcastReceiver}.
     */
    public void init(Context context, ActivityManagerService activity) {
    public void init(Context context, ActivityManagerService activity) {
        mResolver = context.getContentResolver();
        mActivity = activity;
        mActivity = activity;

        context.registerReceiver(new RebootRequestReceiver(),
        context.registerReceiver(new RebootRequestReceiver(),
                new IntentFilter(Intent.ACTION_REBOOT),
                new IntentFilter(Intent.ACTION_REBOOT),
                android.Manifest.permission.REBOOT, null);
                android.Manifest.permission.REBOOT, null);
@@ -335,9 +348,6 @@ public class Watchdog extends Thread {


    public void addMonitor(Monitor monitor) {
    public void addMonitor(Monitor monitor) {
        synchronized (this) {
        synchronized (this) {
            if (isAlive()) {
                throw new RuntimeException("Monitors can't be added once the Watchdog is running");
            }
            mMonitorChecker.addMonitorLocked(monitor);
            mMonitorChecker.addMonitorLocked(monitor);
        }
        }
    }
    }
@@ -348,9 +358,6 @@ public class Watchdog extends Thread {


    public void addThread(Handler thread, long timeoutMillis) {
    public void addThread(Handler thread, long timeoutMillis) {
        synchronized (this) {
        synchronized (this) {
            if (isAlive()) {
                throw new RuntimeException("Threads can't be added once the Watchdog is running");
            }
            final String name = thread.getLooper().getThread().getName();
            final String name = thread.getLooper().getThread().getName();
            mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis));
            mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis));
        }
        }
@@ -468,6 +475,7 @@ public class Watchdog extends Thread {
                    }
                    }
                    try {
                    try {
                        wait(timeout);
                        wait(timeout);
                        // Note: mHandlerCheckers and mMonitorChecker may have changed after waiting
                    } catch (InterruptedException e) {
                    } catch (InterruptedException e) {
                        Log.wtf(TAG, e);
                        Log.wtf(TAG, e);
                    }
                    }
+13 −10
Original line number Original line Diff line number Diff line
@@ -620,6 +620,13 @@ public final class SystemServer {
     * initialized in one of the other functions.
     * initialized in one of the other functions.
     */
     */
    private void startBootstrapServices() {
    private void startBootstrapServices() {
        // Start the watchdog as early as possible so we can crash the system server
        // if we deadlock during early boot
        traceBeginAndSlog("StartWatchdog");
        final Watchdog watchdog = Watchdog.getInstance();
        watchdog.start();
        traceEnd();

        Slog.i(TAG, "Reading configuration...");
        Slog.i(TAG, "Reading configuration...");
        final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
        final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
        traceBeginAndSlog(TAG_SYSTEM_CONFIG);
        traceBeginAndSlog(TAG_SYSTEM_CONFIG);
@@ -764,6 +771,12 @@ public final class SystemServer {
        mActivityManagerService.setSystemProcess();
        mActivityManagerService.setSystemProcess();
        traceEnd();
        traceEnd();


        // Complete the watchdog setup with an ActivityManager instance and listen for reboots
        // Do this only after the ActivityManagerService is properly started as a system process
        traceBeginAndSlog("InitWatchdog");
        watchdog.init(mSystemContext, mActivityManagerService);
        traceEnd();

        // DisplayManagerService needs to setup android.display scheduling related policies
        // DisplayManagerService needs to setup android.display scheduling related policies
        // since setSystemProcess() would have overridden policies due to setProcessGroup
        // since setSystemProcess() would have overridden policies due to setProcessGroup
        mDisplayManagerService.setupSchedulerPolicies();
        mDisplayManagerService.setupSchedulerPolicies();
@@ -983,12 +996,6 @@ public final class SystemServer {


            traceBeginAndSlog("StartAlarmManagerService");
            traceBeginAndSlog("StartAlarmManagerService");
            mSystemServiceManager.startService(new AlarmManagerService(context));
            mSystemServiceManager.startService(new AlarmManagerService(context));

            traceEnd();

            traceBeginAndSlog("InitWatchdog");
            final Watchdog watchdog = Watchdog.getInstance();
            watchdog.init(context, mActivityManagerService);
            traceEnd();
            traceEnd();


            traceBeginAndSlog("StartInputManagerService");
            traceBeginAndSlog("StartInputManagerService");
@@ -2117,10 +2124,6 @@ public final class SystemServer {
            }
            }
            traceEnd();
            traceEnd();


            traceBeginAndSlog("StartWatchdog");
            Watchdog.getInstance().start();
            traceEnd();

            // Wait for all packages to be prepared
            // Wait for all packages to be prepared
            mPackageManagerService.waitForAppDataPrepared();
            mPackageManagerService.waitForAppDataPrepared();