diff options
Diffstat (limited to 'services')
11 files changed, 75 insertions, 29 deletions
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index 795ab47..9e7a15d 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -3405,6 +3405,7 @@ void InputDispatcher::onANRLocked( & InputDispatcher::doNotifyANRLockedInterruptible); commandEntry->inputApplicationHandle = applicationHandle; commandEntry->inputWindowHandle = windowHandle; + commandEntry->reason = reason; } void InputDispatcher::doNotifyConfigurationChangedInterruptible( @@ -3434,7 +3435,8 @@ void InputDispatcher::doNotifyANRLockedInterruptible( mLock.unlock(); nsecs_t newTimeout = mPolicy->notifyANR( - commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle); + commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle, + commandEntry->reason); mLock.lock(); diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h index 0273dc4..190e7b2 100644 --- a/services/input/InputDispatcher.h +++ b/services/input/InputDispatcher.h @@ -202,7 +202,8 @@ public: /* Notifies the system that an application is not responding. * Returns a new timeout to continue waiting, or 0 to abort dispatch. */ virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, - const sp<InputWindowHandle>& inputWindowHandle) = 0; + const sp<InputWindowHandle>& inputWindowHandle, + const String8& reason) = 0; /* Notifies the system that an input channel is unrecoverably broken. */ virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0; @@ -596,6 +597,7 @@ private: KeyEntry* keyEntry; sp<InputApplicationHandle> inputApplicationHandle; sp<InputWindowHandle> inputWindowHandle; + String8 reason; int32_t userActivityEventType; uint32_t seq; bool handled; diff --git a/services/input/tests/InputDispatcher_test.cpp b/services/input/tests/InputDispatcher_test.cpp index ed2b4a5..26b4fab 100644 --- a/services/input/tests/InputDispatcher_test.cpp +++ b/services/input/tests/InputDispatcher_test.cpp @@ -50,7 +50,8 @@ private: } virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, - const sp<InputWindowHandle>& inputWindowHandle) { + const sp<InputWindowHandle>& inputWindowHandle, + const String8& reason) { return 0; } diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 02a78de..4e3faca 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -4681,6 +4681,21 @@ public class ConnectivityService extends IConnectivityManager.Stub { setProvNotificationVisible(visible, networkType, extraInfo, url); } + @Override + public void setAirplaneMode(boolean enable) { + enforceConnectivityInternalPermission(); + final ContentResolver cr = mContext.getContentResolver(); + Settings.Global.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0); + Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); + intent.putExtra("state", enable); + final long ident = Binder.clearCallingIdentity(); + try { + mContext.sendBroadcast(intent); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + private void onUserStart(int userId) { synchronized(mVpns) { Vpn userVpn = mVpns.get(userId); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 1e3fb40..13eb169 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -7970,8 +7970,8 @@ public final class ActivityManagerService extends ActivityManagerNative return KEY_DISPATCHING_TIMEOUT; } - - public long inputDispatchingTimedOut(int pid, final boolean aboveSystem) { + @Override + public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires permission " @@ -7986,7 +7986,7 @@ public final class ActivityManagerService extends ActivityManagerNative timeout = getInputDispatchingTimeoutLocked(proc); } - if (!inputDispatchingTimedOut(proc, null, null, aboveSystem)) { + if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { return -1; } @@ -7999,13 +7999,20 @@ public final class ActivityManagerService extends ActivityManagerNative */ public boolean inputDispatchingTimedOut(final ProcessRecord proc, final ActivityRecord activity, final ActivityRecord parent, - final boolean aboveSystem) { + final boolean aboveSystem, String reason) { if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires permission " + android.Manifest.permission.FILTER_EVENTS); } + final String annotation; + if (reason == null) { + annotation = "Input dispatching timed out"; + } else { + annotation = "Input dispatching timed out (" + reason + ")"; + } + if (proc != null) { synchronized (this) { if (proc.debugging) { @@ -8021,7 +8028,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (proc.instrumentationClass != null) { Bundle info = new Bundle(); info.putString("shortMsg", "keyDispatchingTimedOut"); - info.putString("longMsg", "Timed out while dispatching key event"); + info.putString("longMsg", annotation); finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); return true; } @@ -8029,7 +8036,7 @@ public final class ActivityManagerService extends ActivityManagerNative mHandler.post(new Runnable() { @Override public void run() { - appNotResponding(proc, activity, parent, aboveSystem, "keyDispatchingTimedOut"); + appNotResponding(proc, activity, parent, aboveSystem, annotation); } }); } diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index bf3713b..6e50808 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -305,9 +305,9 @@ final class ActivityRecord { } } - @Override public boolean keyDispatchingTimedOut() { + @Override public boolean keyDispatchingTimedOut(String reason) { ActivityRecord activity = weakActivity.get(); - return activity != null && activity.keyDispatchingTimedOut(); + return activity != null && activity.keyDispatchingTimedOut(reason); } @Override public long getKeyDispatchingTimeout() { @@ -960,14 +960,14 @@ final class ActivityRecord { return r; } - public boolean keyDispatchingTimedOut() { + public boolean keyDispatchingTimedOut(String reason) { ActivityRecord r; ProcessRecord anrApp; synchronized(service) { r = getWaitingHistoryRecordLocked(); anrApp = r != null ? r.app : null; } - return service.inputDispatchingTimedOut(anrApp, r, this, false); + return service.inputDispatchingTimedOut(anrApp, r, this, false, reason); } /** Returns the key dispatching timeout for this application token. */ diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 2b76e71..e994c23 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -620,7 +620,13 @@ final class ActivityStack { } void clearLaunchTime(ActivityRecord r) { - r.displayStartTime = r.fullyDrawnStartTime = 0; + // Make sure that there is no activity waiting for this to launch. + if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) { + r.displayStartTime = r.fullyDrawnStartTime = 0; + } else { + mStackSupervisor.removeTimeoutsForActivityLocked(r); + mStackSupervisor.scheduleIdleTimeoutLocked(r); + } } void awakeFromSleepingLocked() { diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java index 7b4c077..d749e6c 100644 --- a/services/java/com/android/server/input/InputManagerService.java +++ b/services/java/com/android/server/input/InputManagerService.java @@ -1292,8 +1292,9 @@ public class InputManagerService extends IInputManager.Stub // Native callback. private long notifyANR(InputApplicationHandle inputApplicationHandle, - InputWindowHandle inputWindowHandle) { - return mWindowManagerCallbacks.notifyANR(inputApplicationHandle, inputWindowHandle); + InputWindowHandle inputWindowHandle, String reason) { + return mWindowManagerCallbacks.notifyANR( + inputApplicationHandle, inputWindowHandle, reason); } // Native callback. @@ -1477,7 +1478,7 @@ public class InputManagerService extends IInputManager.Stub public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle); public long notifyANR(InputApplicationHandle inputApplicationHandle, - InputWindowHandle inputWindowHandle); + InputWindowHandle inputWindowHandle, String reason); public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn); diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java index 9620612..ea3af263 100644 --- a/services/java/com/android/server/wm/InputMonitor.java +++ b/services/java/com/android/server/wm/InputMonitor.java @@ -88,7 +88,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { */ @Override public long notifyANR(InputApplicationHandle inputApplicationHandle, - InputWindowHandle inputWindowHandle) { + InputWindowHandle inputWindowHandle, String reason) { AppWindowToken appWindowToken = null; WindowState windowState = null; boolean aboveSystem = false; @@ -105,7 +105,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { if (windowState != null) { Slog.i(WindowManagerService.TAG, "Input event dispatching timed out " - + "sending to " + windowState.mAttrs.getTitle()); + + "sending to " + windowState.mAttrs.getTitle() + + ". Reason: " + reason); // Figure out whether this window is layered above system windows. // We need to do this here to help the activity manager know how to // layer its ANR dialog. @@ -114,19 +115,21 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { aboveSystem = windowState.mBaseLayer > systemAlertLayer; } else if (appWindowToken != null) { Slog.i(WindowManagerService.TAG, "Input event dispatching timed out " - + "sending to application " + appWindowToken.stringName); + + "sending to application " + appWindowToken.stringName + + ". Reason: " + reason); } else { - Slog.i(WindowManagerService.TAG, "Input event dispatching timed out."); + Slog.i(WindowManagerService.TAG, "Input event dispatching timed out " + + ". Reason: " + reason); } - mService.saveANRStateLocked(appWindowToken, windowState); + mService.saveANRStateLocked(appWindowToken, windowState, reason); } if (appWindowToken != null && appWindowToken.appToken != null) { try { // Notify the activity manager about the timeout and let it decide whether // to abort dispatching or keep waiting. - boolean abort = appWindowToken.appToken.keyDispatchingTimedOut(); + boolean abort = appWindowToken.appToken.keyDispatchingTimedOut(reason); if (! abort) { // The activity manager declined to abort dispatching. // Wait a bit longer and timeout again later. @@ -139,7 +142,7 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { // Notify the activity manager about the timeout and let it decide whether // to abort dispatching or keep waiting. long timeout = ActivityManagerNative.getDefault().inputDispatchingTimedOut( - windowState.mSession.mPid, aboveSystem); + windowState.mSession.mPid, aboveSystem, reason); if (timeout >= 0) { // The activity manager declined to abort dispatching. // Wait a bit longer and timeout again later. diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 34d8973..b8d2050 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -10541,8 +10541,10 @@ public class WindowManagerService extends IWindowManager.Stub * * @param appWindowToken The application that ANR'd, may be null. * @param windowState The window that ANR'd, may be null. + * @param reason The reason for the ANR, may be null. */ - public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) { + public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState, + String reason) { StringWriter sw = new StringWriter(); PrintWriter pw = new FastPrintWriter(sw, false, 1024); pw.println(" ANR time: " + DateFormat.getInstance().format(new Date())); @@ -10552,6 +10554,9 @@ public class WindowManagerService extends IWindowManager.Stub if (windowState != null) { pw.println(" Window at fault: " + windowState.mAttrs.getTitle()); } + if (reason != null) { + pw.println(" Reason: " + reason); + } pw.println(); dumpWindowsNoHeaderLocked(pw, true, null); pw.close(); diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp index 09e5be4..d8b8b94 100644 --- a/services/jni/com_android_server_input_InputManagerService.cpp +++ b/services/jni/com_android_server_input_InputManagerService.cpp @@ -191,7 +191,8 @@ public: uint32_t policyFlags); virtual void notifyConfigurationChanged(nsecs_t when); virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, - const sp<InputWindowHandle>& inputWindowHandle); + const sp<InputWindowHandle>& inputWindowHandle, + const String8& reason); virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle); virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags); virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig); @@ -553,7 +554,7 @@ void NativeInputManager::notifyConfigurationChanged(nsecs_t when) { } nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, - const sp<InputWindowHandle>& inputWindowHandle) { + const sp<InputWindowHandle>& inputWindowHandle, const String8& reason) { #if DEBUG_INPUT_DISPATCHER_POLICY ALOGD("notifyANR"); #endif @@ -564,15 +565,18 @@ nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApp getInputApplicationHandleObjLocalRef(env, inputApplicationHandle); jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle); + jstring reasonObj = env->NewStringUTF(reason.string()); jlong newTimeout = env->CallLongMethod(mServiceObj, - gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj); + gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj, + reasonObj); if (checkAndClearExceptionFromCallback(env, "notifyANR")) { newTimeout = 0; // abort dispatch } else { assert(newTimeout >= 0); } + env->DeleteLocalRef(reasonObj); env->DeleteLocalRef(inputWindowHandleObj); env->DeleteLocalRef(inputApplicationHandleObj); return newTimeout; @@ -1379,7 +1383,7 @@ int register_android_server_InputManager(JNIEnv* env) { GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz, "notifyANR", - "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;)J"); + "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;Ljava/lang/String;)J"); GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz, "filterInputEvent", "(Landroid/view/InputEvent;I)Z"); |