Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 964305e1 authored by HQ Liu's avatar HQ Liu
Browse files

Remove the current input focused window when ANR

When a freeform app launched and focused, but its window is not ready,
the input focus stays on the window of the previously focused freeform
app. The focus should be removed from the previously foccused app, so
ANR can be triggered correctly.

Bug: 216852742
Test: atest AnrTests#slowOnCreateWithKeyEventTriggersAnr
Change-Id: Id00c147ffab9b11fb2abdf0f3020bc017a31bea7
parent 45a07122
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -248,6 +248,7 @@ public final class SurfaceControl implements Parcelable {

    private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject,
            int transformHint);
    private static native void nativeRemoveCurrentInputFocus(long nativeObject, int displayId);
    private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken,
            String windowName, IBinder focusedToken, String focusedWindowName, int displayId);
    private static native void nativeSetFrameTimelineVsync(long transactionObj,
@@ -3652,6 +3653,17 @@ public final class SurfaceControl implements Parcelable {
            return this;
        }

        /**
         * Removes the input focus from the current window which is having the input focus. Should
         * only be called when the current focused app is not responding and the current focused
         * window is not beloged to the current focused app.
         * @hide
         */
        public Transaction removeCurrentInputFocus(int displayId) {
            nativeRemoveCurrentInputFocus(mNativeObject, displayId);
            return this;
        }

        /**
         * Adds or removes the flag SKIP_SCREENSHOT of the surface.  Setting the flag is equivalent
         * to creating the Surface with the {@link #SKIP_SCREENSHOT} flag.
+11 −0
Original line number Diff line number Diff line
@@ -1833,6 +1833,15 @@ static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) {
    return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
}

static void nativeRemoveCurrentInputFocus(JNIEnv* env, jclass clazz, jlong transactionObj,
                                          jint displayId) {
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
    FocusRequest request;
    request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
    request.displayId = displayId;
    transaction->setFocusedWindow(request);
}

static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionObj,
                                   jobject toTokenObj, jstring windowNameJstr,
                                   jobject focusedTokenObj, jstring focusedWindowNameJstr,
@@ -2167,6 +2176,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeSetFixedTransformHint},
    {"nativeSetFocusedWindow", "(JLandroid/os/IBinder;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;I)V",
            (void*)nativeSetFocusedWindow},
    {"nativeRemoveCurrentInputFocus", "(JI)V",
            (void*)nativeRemoveCurrentInputFocus},
    {"nativeSetFrameTimelineVsync", "(JJ)V",
            (void*)nativeSetFrameTimelineVsync },
    {"nativeAddJankDataListener", "(JJ)V",
+6 −0
Original line number Diff line number Diff line
@@ -3793,6 +3793,12 @@
      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
      "at": "com\/android\/server\/wm\/NonAppWindowAnimationAdapter.java"
    },
    "2001473656": {
      "message": "App %s is focused, but the window is not ready. Start a transaction to remove focus from the window of non-focused apps.",
      "level": "VERBOSE",
      "group": "WM_DEBUG_FOCUS_LIGHT",
      "at": "com\/android\/server\/wm\/InputMonitor.java"
    },
    "2018454757": {
      "message": "WS.removeImmediately: %s Already removed...",
      "level": "VERBOSE",
+11 −0
Original line number Diff line number Diff line
@@ -414,6 +414,17 @@ final class InputMonitor {
        final IBinder focusToken = focus != null ? focus.mInputChannelToken : null;
        if (focusToken == null) {
            mInputFocus = null;
            // When an app is focused, but its window is not showing yet, remove the input focus
            // from the current window.
            if (mDisplayContent.mFocusedApp != null) {
                ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "App %s is focused,"
                        + " but the window is not ready. Start a transaction to remove focus from"
                        + " the window of non-focused apps.",
                        mDisplayContent.mFocusedApp.getName());
                EventLog.writeEvent(LOGTAG_INPUT_FOCUS, "Requesting to set focus to null window",
                        "reason=UpdateInputWindows");
                mInputTransaction.removeCurrentInputFocus(mDisplayId);
            }
            return;
        }