/* Notifies the window manager about an application that is not responding. * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch. * * Called by the InputManager. */ public long notifyANR( InputApplicationHandle inputApplicationHandle, InputWindowHandle inputWindowHandle) { AppWindowToken appWindowToken = null; synchronized (mService.mWindowMap) { WindowState windowState = null; if (inputWindowHandle != null) { windowState = (WindowState) inputWindowHandle.windowState; if (windowState != null) { appWindowToken = windowState.mAppToken; } } if (appWindowToken == null && inputApplicationHandle != null) { appWindowToken = (AppWindowToken) inputApplicationHandle.appWindowToken; } if (windowState != null) { Slog.i( WindowManagerService.TAG, "Input event dispatching timed out " + "sending to " + windowState.mAttrs.getTitle()); } else if (appWindowToken != null) { Slog.i( WindowManagerService.TAG, "Input event dispatching timed out " + "sending to application " + appWindowToken.stringName); } else { Slog.i(WindowManagerService.TAG, "Input event dispatching timed out."); } mService.saveANRStateLocked(appWindowToken, windowState); } 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(); if (!abort) { // The activity manager declined to abort dispatching. // Wait a bit longer and timeout again later. return appWindowToken.inputDispatchingTimeoutNanos; } } catch (RemoteException ex) { } } return 0; // abort dispatching }
/* Notifies the window manager about an application that is not responding. * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch. * * Called by the InputManager. */ @Override public long notifyANR( InputApplicationHandle inputApplicationHandle, InputWindowHandle inputWindowHandle, String reason) { AppWindowToken appWindowToken = null; WindowState windowState = null; boolean aboveSystem = false; synchronized (mService.mWindowMap) { if (inputWindowHandle != null) { windowState = (WindowState) inputWindowHandle.windowState; if (windowState != null) { appWindowToken = windowState.mAppToken; } } if (appWindowToken == null && inputApplicationHandle != null) { appWindowToken = (AppWindowToken) inputApplicationHandle.appWindowToken; } if (windowState != null) { Slog.i( TAG_WM, "Input event dispatching timed out " + "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. int systemAlertLayer = mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); aboveSystem = windowState.mBaseLayer > systemAlertLayer; } else if (appWindowToken != null) { Slog.i( TAG_WM, "Input event dispatching timed out " + "sending to application " + appWindowToken.stringName + ". Reason: " + reason); } else { Slog.i(TAG_WM, "Input event dispatching timed out " + ". Reason: " + reason); } 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(reason); if (!abort) { // The activity manager declined to abort dispatching. // Wait a bit longer and timeout again later. return appWindowToken.inputDispatchingTimeoutNanos; } } catch (RemoteException ex) { } } else if (windowState != null) { try { // 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, reason); if (timeout >= 0) { // The activity manager declined to abort dispatching. // Wait a bit longer and timeout again later. return timeout * 1000000L; // nanoseconds } } catch (RemoteException ex) { } } return 0; // abort dispatching }