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[] {
673a64ecb7fdb67e7fe8c565fa972140d2c0f7c4e2Andy Hung        "/system/bin/audioserver",
68689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung        "/system/bin/cameraserver",
69689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung        "/system/bin/drmserver",
70689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung        "/system/bin/mediadrmserver",
71f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        "/system/bin/mediaserver",
72f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn        "/system/bin/sdcard",
7305d4e35c8e9cf67127630a2ee4376295f275b682Eric Laurent        "/system/bin/surfaceflinger",
74689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung        "media.codec",     // system/bin/mediacodec
75689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung        "media.extractor", // system/bin/mediaextractor
76cf9e79b90192d1a1ece3264b021d3256a2fffefeAndreas Gampe        "com.android.bluetooth",  // Bluetooth service
77f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn    };
78f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static Watchdog sWatchdog;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* This handler will be used to post message back onto the main thread */
82d7fdd0228e6abdbc079f9cf08b780e4222dfe7c5Wale Ogunwale    final ArrayList<HandlerChecker> mHandlerCheckers = new ArrayList<>();
838d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    final HandlerChecker mMonitorChecker;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ContentResolver mResolver;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ActivityManagerService mActivity;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mPhonePid;
885b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn    IActivityController mController;
898bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn    boolean mAllowRestart = true;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
928d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn     * Used for checking status of handle threads and scheduling monitor callbacks.
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
948d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    public final class HandlerChecker implements Runnable {
958d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private final Handler mHandler;
968d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private final String mName;
97e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        private final long mWaitMax;
988d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
998d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private boolean mCompleted;
1008d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        private Monitor mCurrentMonitor;
101e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        private long mStartTime;
1028d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
103e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        HandlerChecker(Handler handler, String name, long waitMaxMillis) {
1048d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mHandler = handler;
1058d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mName = name;
106e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            mWaitMax = waitMaxMillis;
107e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            mCompleted = true;
1088d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
1098d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
1108d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        public void addMonitor(Monitor monitor) {
1118d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mMonitors.add(monitor);
1128d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
1138d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
1148d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        public void scheduleCheckLocked() {
1156c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown            if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) {
1166c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown                // If the target looper has recently been polling, then
117efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // there is no reason to enqueue our checker on it since that
118efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // is as good as it not being deadlocked.  This avoid having
119efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // to do a context switch to check the thread.  Note that we
120efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // only do this if mCheckReboot is false and we have no
121efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                // monitors, since those would need to be executed at this point.
122efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                mCompleted = true;
123efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn                return;
124efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn            }
125e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate
126e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            if (!mCompleted) {
127e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                // we already have a check in flight, so no need
128e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                return;
129e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            }
130e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate
1318d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mCompleted = false;
1328d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mCurrentMonitor = null;
133e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            mStartTime = SystemClock.uptimeMillis();
1348d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mHandler.postAtFrontOfQueue(this);
1358d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
1368d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
137e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        public boolean isOverdueLocked() {
138e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            return (!mCompleted) && (SystemClock.uptimeMillis() > mStartTime + mWaitMax);
139e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        }
140e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate
141e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        public int getCompletionStateLocked() {
142e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            if (mCompleted) {
143e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                return COMPLETED;
144e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            } else {
145e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                long latency = SystemClock.uptimeMillis() - mStartTime;
146e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                if (latency < mWaitMax/2) {
147e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    return WAITING;
148e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                } else if (latency < mWaitMax) {
149e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    return WAITED_HALF;
150e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                }
151e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            }
152e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            return OVERDUE;
1538d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
1548d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
155fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        public Thread getThread() {
156fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            return mHandler.getLooper().getThread();
157fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        }
158fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn
159fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        public String getName() {
160fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            return mName;
161fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        }
162fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn
1638d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        public String describeBlockedStateLocked() {
1647dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            if (mCurrentMonitor == null) {
1657dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                return "Blocked in handler on " + mName + " (" + getThread().getName() + ")";
1667dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            } else {
1677dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                return "Blocked in monitor " + mCurrentMonitor.getClass().getName()
1687dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                        + " on " + mName + " (" + getThread().getName() + ")";
1697dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            }
170116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelau        }
171116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelau
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1738d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        public void run() {
1748d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            final int size = mMonitors.size();
1758d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            for (int i = 0 ; i < size ; i++) {
1768d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                synchronized (Watchdog.this) {
1778d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                    mCurrentMonitor = mMonitors.get(i);
1788d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                }
1798d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                mCurrentMonitor.monitor();
1808d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1828d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            synchronized (Watchdog.this) {
1838d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                mCompleted = true;
1848d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                mCurrentMonitor = null;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final class RebootRequestReceiver extends BroadcastReceiver {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onReceive(Context c, Intent intent) {
192f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn            if (intent.getIntExtra("nowait", 0) != 0) {
193f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn                rebootSystem("Received ACTION_REBOOT broadcast");
194f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn                return;
195f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn            }
196f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn            Slog.w(TAG, "Unsupported ACTION_REBOOT broadcast: " + intent);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
200517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale    /** Monitor for checking the availability of binder threads. The monitor will block until
201517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale     * there is a binder thread available to process in coming IPCs to make sure other processes
202517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale     * can still communicate with the service.
203517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale     */
204517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale    private static final class BinderThreadMonitor implements Watchdog.Monitor {
205517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale        @Override
206517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale        public void monitor() {
207517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale            Binder.blockUntilThreadAvailable();
208517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale        }
209517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale    }
210517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface Monitor {
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void monitor();
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static Watchdog getInstance() {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sWatchdog == null) {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sWatchdog = new Watchdog();
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return sWatchdog;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Watchdog() {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super("watchdog");
2258d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // Initialize handler checkers for each common thread we want to check.  Note
2268d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // that we are not currently checking the background thread, since it can
2278d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // potentially hold longer running operations with no guarantees about the timeliness
2288d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // of operations there.
2298d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
2308d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // The shared foreground thread is the main checker.  It is where we
2318d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // will also dispatch monitor checks and do other work.
232e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        mMonitorChecker = new HandlerChecker(FgThread.getHandler(),
233e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                "foreground thread", DEFAULT_TIMEOUT);
2348d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        mHandlerCheckers.add(mMonitorChecker);
2358d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // Add checker for main thread.  We only do a quick check since there
2368d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // can be UI running on the thread.
2378d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()),
238e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                "main thread", DEFAULT_TIMEOUT));
2398d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // Add checker for shared UI thread.
240e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(),
241e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                "ui thread", DEFAULT_TIMEOUT));
2428d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        // And also check IO thread.
243e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(),
244e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                "i/o thread", DEFAULT_TIMEOUT));
2454ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown        // And the display thread.
2464ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown        mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(),
2474ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown                "display thread", DEFAULT_TIMEOUT));
248517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale
249517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale        // Initialize monitor for Binder threads.
250517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale        addMonitor(new BinderThreadMonitor());
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
253182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski    public void init(Context context, ActivityManagerService activity) {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mResolver = context.getContentResolver();
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mActivity = activity;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        context.registerReceiver(new RebootRequestReceiver(),
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                new IntentFilter(Intent.ACTION_REBOOT),
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                android.Manifest.permission.REBOOT, null);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
262c27181c7f3e11170ec82807cfa416f0a906ff574Christopher Tate    public void processStarted(String name, int pid) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ("com.android.phone".equals(name)) {
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mPhonePid = pid;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2705b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn    public void setActivityController(IActivityController controller) {
2715b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn        synchronized (this) {
2725b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            mController = controller;
2735b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn        }
2745b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn    }
2755b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn
2768bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn    public void setAllowRestart(boolean allowRestart) {
2778bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn        synchronized (this) {
2788bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            mAllowRestart = allowRestart;
2798bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn        }
2808bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn    }
2818bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addMonitor(Monitor monitor) {
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isAlive()) {
2858d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                throw new RuntimeException("Monitors can't be added once the Watchdog is running");
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2878d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            mMonitorChecker.addMonitor(monitor);
2888d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
2898d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    }
2908d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
2916f357d3284a833cc50a990e14b39f389b8972254Jeff Brown    public void addThread(Handler thread) {
2926f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        addThread(thread, DEFAULT_TIMEOUT);
293e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    }
294e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate
2956f357d3284a833cc50a990e14b39f389b8972254Jeff Brown    public void addThread(Handler thread, long timeoutMillis) {
2968d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        synchronized (this) {
2978d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            if (isAlive()) {
2988d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                throw new RuntimeException("Threads can't be added once the Watchdog is running");
2998d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            }
3006f357d3284a833cc50a990e14b39f389b8972254Jeff Brown            final String name = thread.getLooper().getThread().getName();
301e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis));
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Perform a full reboot of the system.
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void rebootSystem(String reason) {
3098a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        Slog.i(TAG, "Rebooting system because: " + reason);
3106f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        IPowerManager pms = (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE);
3116f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        try {
3126f357d3284a833cc50a990e14b39f389b8972254Jeff Brown            pms.reboot(false, reason, false);
3136f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        } catch (RemoteException ex) {
3146f357d3284a833cc50a990e14b39f389b8972254Jeff Brown        }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
317e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate    private int evaluateCheckerCompletionLocked() {
318e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        int state = COMPLETED;
3198d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        for (int i=0; i<mHandlerCheckers.size(); i++) {
3208d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            HandlerChecker hc = mHandlerCheckers.get(i);
321e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            state = Math.max(state, hc.getCompletionStateLocked());
3228d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
323e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate        return state;
3248d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    }
3258d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
326fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn    private ArrayList<HandlerChecker> getBlockedCheckersLocked() {
327fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        ArrayList<HandlerChecker> checkers = new ArrayList<HandlerChecker>();
3288d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        for (int i=0; i<mHandlerCheckers.size(); i++) {
3298d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            HandlerChecker hc = mHandlerCheckers.get(i);
330e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate            if (hc.isOverdueLocked()) {
331fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                checkers.add(hc);
3328d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn            }
3338d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        }
334fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        return checkers;
335fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn    }
336fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn
337fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn    private String describeCheckersLocked(ArrayList<HandlerChecker> checkers) {
338fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        StringBuilder builder = new StringBuilder(128);
339fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        for (int i=0; i<checkers.size(); i++) {
340fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            if (builder.length() > 0) {
341fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                builder.append(", ");
342fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            }
343fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            builder.append(checkers.get(i).describeBlockedStateLocked());
344fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn        }
3458d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn        return builder.toString();
3468d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn    }
3478d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void run() {
3506ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate        boolean waitedHalf = false;
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (true) {
352fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn            final ArrayList<HandlerChecker> blockedCheckers;
3537dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            final String subject;
3548bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            final boolean allowRestart;
35589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn            int debuggerWasConnected = 0;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (this) {
357e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                long timeout = CHECK_INTERVAL;
358e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                // Make sure we (re)spin the checkers that have become idle within
359e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                // this wait-and-check interval
360e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                for (int i=0; i<mHandlerCheckers.size(); i++) {
361e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    HandlerChecker hc = mHandlerCheckers.get(i);
362e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    hc.scheduleCheckLocked();
3638d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn                }
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
36589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                if (debuggerWasConnected > 0) {
36689ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    debuggerWasConnected--;
36789ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                }
36889ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // NOTE: We use uptimeMillis() here because we do not want to increment the time we
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // wait while asleep. If the device is asleep then the thing that we are waiting
3716ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate                // to timeout on is asleep as well and won't have a chance to run, causing a false
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // positive on when to kill things.
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                long start = SystemClock.uptimeMillis();
3748fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright                while (timeout > 0) {
37589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    if (Debug.isDebuggerConnected()) {
37689ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                        debuggerWasConnected = 2;
37789ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
3798fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright                        wait(timeout);
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (InterruptedException e) {
3819bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor                        Log.wtf(TAG, e);
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
38389ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    if (Debug.isDebuggerConnected()) {
38489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                        debuggerWasConnected = 2;
38589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                    }
386e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start);
3879bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor                }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                final int waitState = evaluateCheckerCompletionLocked();
390e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                if (waitState == COMPLETED) {
391e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    // The monitors have returned; reset
3926ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate                    waitedHalf = false;
3936ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate                    continue;
394e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                } else if (waitState == WAITING) {
395e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    // still waiting but within their configured intervals; back off and recheck
396e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    continue;
397e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                } else if (waitState == WAITED_HALF) {
398e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    if (!waitedHalf) {
399e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        // We've waited half the deadlock-detection interval.  Pull a stack
400e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        // trace and wait another half.
401e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        ArrayList<Integer> pids = new ArrayList<Integer>();
402e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        pids.add(Process.myPid());
403e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        ActivityManagerService.dumpStackTraces(true, pids, null, null,
404e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                                NATIVE_STACKS_OF_INTEREST);
405e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                        waitedHalf = true;
406e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                    }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4098fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright
410e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate                // something is overdue!
411fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                blockedCheckers = getBlockedCheckersLocked();
4127dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                subject = describeCheckersLocked(blockedCheckers);
4138bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn                allowRestart = mAllowRestart;
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If we got here, that means that the system is most likely hung.
417784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru            // First collect stack traces from all threads of the system process.
418784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru            // Then kill this process so that the system will restart.
4197dd2d19725bac29306900a06818edf2f205ca051Jeff Brown            EventLog.writeEvent(EventLogTags.WATCHDOG, subject);
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4216b1afebdaca6c27d49a243c4283e5e2e4924de8cDianne Hackborn            ArrayList<Integer> pids = new ArrayList<Integer>();
4229bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor            pids.add(Process.myPid());
4234bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor            if (mPhonePid > 0) pids.add(mPhonePid);
4246ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate            // Pass !waitedHalf so that just in case we somehow wind up here without having
4256ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate            // dumped the halfway stacks, we properly re-initialize the trace file.
4269765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            final File stack = ActivityManagerService.dumpStackTraces(
427f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn                    !waitedHalf, pids, null, null, NATIVE_STACKS_OF_INTEREST);
4284bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor
4294bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor            // Give some extra time to make sure the stack traces get written.
4304bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor            // The system's been hanging for a minute, another second or two won't hurt much.
4314bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor            SystemClock.sleep(2000);
4324bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor
433ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate            // Pull our own kernel thread stacks as well if we're configured for that
434ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate            if (RECORD_KERNEL_THREADS) {
435ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate                dumpKernelStackTraces();
436ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate            }
437ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate
4380620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            // Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the kernel log
4390620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            doSysRq('w');
4400620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            doSysRq('l');
4415df1d871feabee23b16a69ee48695fd892017517Colin Cross
4429765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            // Try to add the error to the dropbox, but assuming that the ActivityManager
4439765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            // itself may be deadlocked.  (which has happened, causing this statement to
4449765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            // deadlock and the watchdog as a whole to be ineffective)
4459765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            Thread dropboxThread = new Thread("watchdogWriteToDropbox") {
4469765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                    public void run() {
4479765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                        mActivity.addErrorToDropBox(
448a353d2654a98b292469d2559cb4424b13d779924Jeff Sharkey                                "watchdog", null, "system_server", null, null,
4497dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                                subject, null, stack, null);
4509765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                    }
4519765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                };
4529765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            dropboxThread.start();
4539765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            try {
4549765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick                dropboxThread.join(2000);  // wait up to 2 seconds for it to return.
4559765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick            } catch (InterruptedException ignored) {}
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4575b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            IActivityController controller;
4585b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            synchronized (this) {
4595b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                controller = mController;
4605b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            }
4615b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            if (controller != null) {
4625b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                Slog.i(TAG, "Reporting stuck state to activity controller");
4635b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                try {
4645b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                    Binder.setDumpDisabled("Service dumps disabled due to hung system process.");
4655b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                    // 1 = keep waiting, -1 = kill system
4667dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                    int res = controller.systemNotResponding(subject);
4675b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                    if (res >= 0) {
4685b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                        Slog.i(TAG, "Activity controller requested to coninue to wait");
4695b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                        waitedHalf = false;
4705b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                        continue;
4715b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                    }
4725b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                } catch (RemoteException e) {
4735b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn                }
4745b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn            }
4755b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn
476784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru            // Only kill the process if the debugger is not attached.
4778bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            if (Debug.isDebuggerConnected()) {
47889ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                debuggerWasConnected = 2;
47989ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn            }
48089ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn            if (debuggerWasConnected >= 2) {
4818bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn                Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
48289ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn            } else if (debuggerWasConnected > 0) {
48389ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn                Slog.w(TAG, "Debugger was connected: Watchdog is *not* killing the system process");
4848bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            } else if (!allowRestart) {
4858bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn                Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
4868bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn            } else {
4877dd2d19725bac29306900a06818edf2f205ca051Jeff Brown                Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + subject);
488fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                for (int i=0; i<blockedCheckers.size(); i++) {
489fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                    Slog.w(TAG, blockedCheckers.get(i).getName() + " stack trace:");
490fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                    StackTraceElement[] stackTrace
491fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                            = blockedCheckers.get(i).getThread().getStackTrace();
492fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                    for (StackTraceElement element: stackTrace) {
493fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                        Slog.w(TAG, "    at " + element);
494fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                    }
49556a6c66158b1ba26626a161ed782724fb1e3cea1Michael Wright                }
496fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn                Slog.w(TAG, "*** GOODBYE!");
497784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru                Process.killProcess(Process.myPid());
498784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru                System.exit(10);
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5006ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate
5016ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate            waitedHalf = false;
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
504ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate
5050620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu    private void doSysRq(char c) {
5060620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu        try {
5070620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            FileWriter sysrq_trigger = new FileWriter("/proc/sysrq-trigger");
5080620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            sysrq_trigger.write(c);
5090620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            sysrq_trigger.close();
5100620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu        } catch (IOException e) {
5110620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu            Slog.w(TAG, "Failed to write to /proc/sysrq-trigger", e);
5120620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu        }
5130620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu    }
5140620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu
515ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate    private File dumpKernelStackTraces() {
516ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
517ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        if (tracesPath == null || tracesPath.length() == 0) {
518ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate            return null;
519ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        }
520ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate
521ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        native_dumpKernelStacks(tracesPath);
522ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate        return new File(tracesPath);
523ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate    }
524ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate
525ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate    private native void native_dumpKernelStacks(String tracesPath);
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
527