예제 #1
0
  /* 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
  }