Watchdog.java revision d7fdd0228e6abdbc079f9cf08b780e4222dfe7c5
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
195b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackbornimport android.app.IActivityController;
205b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackbornimport android.os.Binder;
215b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackbornimport android.os.RemoteException;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.am.ActivityManagerService;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.BroadcastReceiver;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Debug;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
316f357d3284a833cc50a990e14b39f389b8972254Jeff Brownimport android.os.IPowerManager;
32116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelauimport android.os.Looper;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process;
346ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapuimport android.os.ServiceManager;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog;
389bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnorimport android.util.Log;
398a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnorimport java.io.File;
425df1d871feabee23b16a69ee48695fd892017517Colin Crossimport java.io.FileWriter;
435df1d871feabee23b16a69ee48695fd892017517Colin Crossimport java.io.IOException;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** This class calls its monitor every minute. Killing this process if they don't return **/
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Watchdog extends Thread {
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String TAG = "Watchdog";
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Set this to true to use debug default values.
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final boolean DB = false;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
53ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate    // Set this to true to have the watchdog record kernel thread stacks when it fires
54ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate    static final boolean RECORD_KERNEL_THREADS = true;
55ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate
56e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    static final long DEFAULT_TIMEOUT = DB ? 10*1000 : 60*1000;
57e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    static final long CHECK_INTERVAL = DEFAULT_TIMEOUT / 2;
58e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate
59e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    // These are temporally ordered: larger values as lateness increases
60e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    static final int COMPLETED = 0;
61e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    static final int WAITING = 1;
62e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    static final int WAITED_HALF = 2;
63e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    static final int OVERDUE = 3;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6544d04aa0ace68e6164c5eb7b3536c0992aaf5a3aIgor Murashkin    // Which native processes to dump into dropbox's stack traces
6644d04aa0ace68e6164c5eb7b3536c0992aaf5a3aIgor Murashkin    public static final String[] NATIVE_STACKS_OF_INTEREST = new String[] {
67f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        "/system/bin/mediaserver",
68f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        "/system/bin/sdcard",
69f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        "/system/bin/surfaceflinger"
70f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    };
71f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static Watchdog sWatchdog;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* This handler will be used to post message back onto the main thread */
75d7fdd0228e6abdbc079f9cf08b780e4222dfe7c5Wale Ogunwale    final ArrayList<HandlerChecker> mHandlerCheckers = new ArrayList<>();
768d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    final HandlerChecker mMonitorChecker;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ContentResolver mResolver;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ActivityManagerService mActivity;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mPhonePid;
815b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn    IActivityController mController;
828bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn    boolean mAllowRestart = true;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
858d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn     * Used for checking status of handle threads and scheduling monitor callbacks.
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
878d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    public final class HandlerChecker implements Runnable {
888d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private final Handler mHandler;
898d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private final String mName;
90e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        private final long mWaitMax;
918d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
928d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private boolean mCompleted;
938d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private Monitor mCurrentMonitor;
94e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        private long mStartTime;
958d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
96e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        HandlerChecker(Handler handler, String name, long waitMaxMillis) {
978d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mHandler = handler;
988d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mName = name;
99e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            mWaitMax = waitMaxMillis;
100e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            mCompleted = true;
1018d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
1028d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
1038d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        public void addMonitor(Monitor monitor) {
1048d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mMonitors.add(monitor);
1058d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
1068d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
1078d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        public void scheduleCheckLocked() {
1086c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown            if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) {
1096c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown                // If the target looper has recently been polling, then
110efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // there is no reason to enqueue our checker on it since that
111efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // is as good as it not being deadlocked.  This avoid having
112efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // to do a context switch to check the thread.  Note that we
113efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // only do this if mCheckReboot is false and we have no
114efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // monitors, since those would need to be executed at this point.
115efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                mCompleted = true;
116efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                return;
117efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn            }
118e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate
119e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            if (!mCompleted) {
120e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                // we already have a check in flight, so no need
121e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                return;
122e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            }
123e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate
1248d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mCompleted = false;
1258d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mCurrentMonitor = null;
126e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            mStartTime = SystemClock.uptimeMillis();
1278d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mHandler.postAtFrontOfQueue(this);
1288d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
1298d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
130e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        public boolean isOverdueLocked() {
131e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            return (!mCompleted) && (SystemClock.uptimeMillis() > mStartTime + mWaitMax);
132e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        }
133e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate
134e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        public int getCompletionStateLocked() {
135e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            if (mCompleted) {
136e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                return COMPLETED;
137e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            } else {
138e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                long latency = SystemClock.uptimeMillis() - mStartTime;
139e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                if (latency < mWaitMax/2) {
140e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    return WAITING;
141e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                } else if (latency < mWaitMax) {
142e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    return WAITED_HALF;
143e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                }
144e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            }
145e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            return OVERDUE;
1468d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
1478d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
148fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        public Thread getThread() {
149fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            return mHandler.getLooper().getThread();
150fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        }
151fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn
152fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        public String getName() {
153fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            return mName;
154fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        }
155fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn
1568d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        public String describeBlockedStateLocked() {
1577dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            if (mCurrentMonitor == null) {
1587dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                return "Blocked in handler on " + mName + " (" + getThread().getName() + ")";
1597dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            } else {
1607dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                return "Blocked in monitor " + mCurrentMonitor.getClass().getName()
1617dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                        + " on " + mName + " (" + getThread().getName() + ")";
1627dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            }
163116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelau        }
164116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelau
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1668d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        public void run() {
1678d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            final int size = mMonitors.size();
1688d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            for (int i = 0 ; i < size ; i++) {
1698d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                synchronized (Watchdog.this) {
1708d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                    mCurrentMonitor = mMonitors.get(i);
1718d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                }
1728d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                mCurrentMonitor.monitor();
1738d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            }
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1758d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            synchronized (Watchdog.this) {
1768d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                mCompleted = true;
1778d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                mCurrentMonitor = null;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final class RebootRequestReceiver extends BroadcastReceiver {
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onReceive(Context c, Intent intent) {
185f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn            if (intent.getIntExtra("nowait", 0) != 0) {
186f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn                rebootSystem("Received ACTION_REBOOT broadcast");
187f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn                return;
188f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn            }
189f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn            Slog.w(TAG, "Unsupported ACTION_REBOOT broadcast: " + intent);
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface Monitor {
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void monitor();
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Watchdog getInstance() {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sWatchdog == null) {
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sWatchdog = new Watchdog();
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return sWatchdog;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Watchdog() {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super("watchdog");
2078d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // Initialize handler checkers for each common thread we want to check.  Note
2088d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // that we are not currently checking the background thread, since it can
2098d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // potentially hold longer running operations with no guarantees about the timeliness
2108d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // of operations there.
2118d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
2128d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // The shared foreground thread is the main checker.  It is where we
2138d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // will also dispatch monitor checks and do other work.
214e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        mMonitorChecker = new HandlerChecker(FgThread.getHandler(),
215e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                "foreground thread", DEFAULT_TIMEOUT);
2168d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        mHandlerCheckers.add(mMonitorChecker);
2178d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // Add checker for main thread.  We only do a quick check since there
2188d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // can be UI running on the thread.
2198d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()),
220e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                "main thread", DEFAULT_TIMEOUT));
2218d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // Add checker for shared UI thread.
222e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(),
223e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                "ui thread", DEFAULT_TIMEOUT));
2248d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // And also check IO thread.
225e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(),
226e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                "i/o thread", DEFAULT_TIMEOUT));
2274ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown        // And the display thread.
2284ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown        mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(),
2294ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown                "display thread", DEFAULT_TIMEOUT));
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
232182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    public void init(Context context, ActivityManagerService activity) {
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mResolver = context.getContentResolver();
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mActivity = activity;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        context.registerReceiver(new RebootRequestReceiver(),
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                new IntentFilter(Intent.ACTION_REBOOT),
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                android.Manifest.permission.REBOOT, null);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
241c27181c7f3e11170ec82807cfa416f0a906ff574Christopher Tate    public void processStarted(String name, int pid) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ("com.android.phone".equals(name)) {
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPhonePid = pid;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2495b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn    public void setActivityController(IActivityController controller) {
2505b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn        synchronized (this) {
2515b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            mController = controller;
2525b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn        }
2535b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn    }
2545b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn
2558bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn    public void setAllowRestart(boolean allowRestart) {
2568bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn        synchronized (this) {
2578bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            mAllowRestart = allowRestart;
2588bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn        }
2598bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn    }
2608bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addMonitor(Monitor monitor) {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isAlive()) {
2648d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                throw new RuntimeException("Monitors can't be added once the Watchdog is running");
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2668d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mMonitorChecker.addMonitor(monitor);
2678d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
2688d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    }
2698d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
2706f357d3284a833cc50a990e14b39f389b8972254Jeff Brown    public void addThread(Handler thread) {
2716f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        addThread(thread, DEFAULT_TIMEOUT);
272e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    }
273e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate
2746f357d3284a833cc50a990e14b39f389b8972254Jeff Brown    public void addThread(Handler thread, long timeoutMillis) {
2758d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        synchronized (this) {
2768d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            if (isAlive()) {
2778d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                throw new RuntimeException("Threads can't be added once the Watchdog is running");
2788d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            }
2796f357d3284a833cc50a990e14b39f389b8972254Jeff Brown            final String name = thread.getLooper().getThread().getName();
280e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis));
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Perform a full reboot of the system.
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void rebootSystem(String reason) {
2888a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        Slog.i(TAG, "Rebooting system because: " + reason);
2896f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        IPowerManager pms = (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE);
2906f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        try {
2916f357d3284a833cc50a990e14b39f389b8972254Jeff Brown            pms.reboot(false, reason, false);
2926f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        } catch (RemoteException ex) {
2936f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        }
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
296e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    private int evaluateCheckerCompletionLocked() {
297e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        int state = COMPLETED;
2988d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        for (int i=0; i<mHandlerCheckers.size(); i++) {
2998d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            HandlerChecker hc = mHandlerCheckers.get(i);
300e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            state = Math.max(state, hc.getCompletionStateLocked());
3018d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
302e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        return state;
3038d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    }
3048d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
305fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn    private ArrayList<HandlerChecker> getBlockedCheckersLocked() {
306fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        ArrayList<HandlerChecker> checkers = new ArrayList<HandlerChecker>();
3078d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        for (int i=0; i<mHandlerCheckers.size(); i++) {
3088d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            HandlerChecker hc = mHandlerCheckers.get(i);
309e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            if (hc.isOverdueLocked()) {
310fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                checkers.add(hc);
3118d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            }
3128d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
313fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        return checkers;
314fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn    }
315fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn
316fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn    private String describeCheckersLocked(ArrayList<HandlerChecker> checkers) {
317fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        StringBuilder builder = new StringBuilder(128);
318fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        for (int i=0; i<checkers.size(); i++) {
319fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            if (builder.length() > 0) {
320fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                builder.append(", ");
321fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            }
322fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            builder.append(checkers.get(i).describeBlockedStateLocked());
323fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        }
3248d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        return builder.toString();
3258d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    }
3268d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void run() {
3296ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate        boolean waitedHalf = false;
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (true) {
331fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            final ArrayList<HandlerChecker> blockedCheckers;
3327dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            final String subject;
3338bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            final boolean allowRestart;
33489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn            int debuggerWasConnected = 0;
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (this) {
336e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                long timeout = CHECK_INTERVAL;
337e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                // Make sure we (re)spin the checkers that have become idle within
338e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                // this wait-and-check interval
339e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                for (int i=0; i<mHandlerCheckers.size(); i++) {
340e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    HandlerChecker hc = mHandlerCheckers.get(i);
341e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    hc.scheduleCheckLocked();
3428d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                }
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
34489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                if (debuggerWasConnected > 0) {
34589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    debuggerWasConnected--;
34689ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                }
34789ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // NOTE: We use uptimeMillis() here because we do not want to increment the time we
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // wait while asleep. If the device is asleep then the thing that we are waiting
3506ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate                // to timeout on is asleep as well and won't have a chance to run, causing a false
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // positive on when to kill things.
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                long start = SystemClock.uptimeMillis();
3538fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright                while (timeout > 0) {
35489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    if (Debug.isDebuggerConnected()) {
35589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                        debuggerWasConnected = 2;
35689ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
3588fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright                        wait(timeout);
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (InterruptedException e) {
3609bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor                        Log.wtf(TAG, e);
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
36289ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    if (Debug.isDebuggerConnected()) {
36389ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                        debuggerWasConnected = 2;
36489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    }
365e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start);
3669bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor                }
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
368e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                final int waitState = evaluateCheckerCompletionLocked();
369e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                if (waitState == COMPLETED) {
370e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    // The monitors have returned; reset
3716ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate                    waitedHalf = false;
3726ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate                    continue;
373e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                } else if (waitState == WAITING) {
374e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    // still waiting but within their configured intervals; back off and recheck
375e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    continue;
376e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                } else if (waitState == WAITED_HALF) {
377e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    if (!waitedHalf) {
378e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        // We've waited half the deadlock-detection interval.  Pull a stack
379e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        // trace and wait another half.
380e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        ArrayList<Integer> pids = new ArrayList<Integer>();
381e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        pids.add(Process.myPid());
382e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        ActivityManagerService.dumpStackTraces(true, pids, null, null,
383e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                                NATIVE_STACKS_OF_INTEREST);
384e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        waitedHalf = true;
385e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    }
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3888fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright
389e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                // something is overdue!
390fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                blockedCheckers = getBlockedCheckersLocked();
3917dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                subject = describeCheckersLocked(blockedCheckers);
3928bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn                allowRestart = mAllowRestart;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If we got here, that means that the system is most likely hung.
396784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru            // First collect stack traces from all threads of the system process.
397784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru            // Then kill this process so that the system will restart.
3987dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            EventLog.writeEvent(EventLogTags.WATCHDOG, subject);
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4006b1afebdaca6c27d49a243c4283e5e2e4924de8cDianne Hackborn            ArrayList<Integer> pids = new ArrayList<Integer>();
4019bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor            pids.add(Process.myPid());
4024bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor            if (mPhonePid > 0) pids.add(mPhonePid);
4036ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate            // Pass !waitedHalf so that just in case we somehow wind up here without having
4046ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate            // dumped the halfway stacks, we properly re-initialize the trace file.
4059765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            final File stack = ActivityManagerService.dumpStackTraces(
406f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn                    !waitedHalf, pids, null, null, NATIVE_STACKS_OF_INTEREST);
4074bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor
4084bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor            // Give some extra time to make sure the stack traces get written.
4094bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor            // The system's been hanging for a minute, another second or two won't hurt much.
4104bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor            SystemClock.sleep(2000);
4114bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor
412ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate            // Pull our own kernel thread stacks as well if we're configured for that
413ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate            if (RECORD_KERNEL_THREADS) {
414ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate                dumpKernelStackTraces();
415ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate            }
416ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate
4170620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            // Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the kernel log
4180620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            doSysRq('w');
4190620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            doSysRq('l');
4205df1d871feabee23b16a69ee48695fd892017517Colin Cross
4219765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            // Try to add the error to the dropbox, but assuming that the ActivityManager
4229765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            // itself may be deadlocked.  (which has happened, causing this statement to
4239765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            // deadlock and the watchdog as a whole to be ineffective)
4249765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            Thread dropboxThread = new Thread("watchdogWriteToDropbox") {
4259765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                    public void run() {
4269765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                        mActivity.addErrorToDropBox(
427a353d2654a98b292469d2559cb4424b13d779924Jeff Sharkey                                "watchdog", null, "system_server", null, null,
4287dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                                subject, null, stack, null);
4299765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                    }
4309765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                };
4319765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            dropboxThread.start();
4329765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            try {
4339765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                dropboxThread.join(2000);  // wait up to 2 seconds for it to return.
4349765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            } catch (InterruptedException ignored) {}
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4365b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            IActivityController controller;
4375b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            synchronized (this) {
4385b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                controller = mController;
4395b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            }
4405b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            if (controller != null) {
4415b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                Slog.i(TAG, "Reporting stuck state to activity controller");
4425b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                try {
4435b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                    Binder.setDumpDisabled("Service dumps disabled due to hung system process.");
4445b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                    // 1 = keep waiting, -1 = kill system
4457dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                    int res = controller.systemNotResponding(subject);
4465b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                    if (res >= 0) {
4475b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                        Slog.i(TAG, "Activity controller requested to coninue to wait");
4485b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                        waitedHalf = false;
4495b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                        continue;
4505b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                    }
4515b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                } catch (RemoteException e) {
4525b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                }
4535b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            }
4545b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn
455784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru            // Only kill the process if the debugger is not attached.
4568bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            if (Debug.isDebuggerConnected()) {
45789ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                debuggerWasConnected = 2;
45889ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn            }
45989ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn            if (debuggerWasConnected >= 2) {
4608bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn                Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
46189ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn            } else if (debuggerWasConnected > 0) {
46289ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                Slog.w(TAG, "Debugger was connected: Watchdog is *not* killing the system process");
4638bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            } else if (!allowRestart) {
4648bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn                Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
4658bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            } else {
4667dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + subject);
467fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                for (int i=0; i<blockedCheckers.size(); i++) {
468fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                    Slog.w(TAG, blockedCheckers.get(i).getName() + " stack trace:");
469fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                    StackTraceElement[] stackTrace
470fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                            = blockedCheckers.get(i).getThread().getStackTrace();
471fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                    for (StackTraceElement element: stackTrace) {
472fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                        Slog.w(TAG, "    at " + element);
473fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                    }
47456a6c66158b1ba26626a161ed782724fb1e3cea1Michael Wright                }
475fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                Slog.w(TAG, "*** GOODBYE!");
476784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru                Process.killProcess(Process.myPid());
477784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru                System.exit(10);
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4796ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate
4806ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate            waitedHalf = false;
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
483ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate
4840620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu    private void doSysRq(char c) {
4850620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu        try {
4860620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            FileWriter sysrq_trigger = new FileWriter("/proc/sysrq-trigger");
4870620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            sysrq_trigger.write(c);
4880620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            sysrq_trigger.close();
4890620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu        } catch (IOException e) {
4900620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            Slog.w(TAG, "Failed to write to /proc/sysrq-trigger", e);
4910620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu        }
4920620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu    }
4930620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu
494ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate    private File dumpKernelStackTraces() {
495ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
496ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        if (tracesPath == null || tracesPath.length() == 0) {
497ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate            return null;
498ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        }
499ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate
500ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        native_dumpKernelStacks(tracesPath);
501ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        return new File(tracesPath);
502ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate    }
503ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate
504ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate    private native void native_dumpKernelStacks(String tracesPath);
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
506