From a13a07e395922ec215bd4d0f3ba301d605009ecb Mon Sep 17 00:00:00 2001 From: Arthur Hung Date: Thu, 1 Dec 2022 08:46:46 +0000 Subject: [PATCH] Inject back key event if focused window didn't be drawn If an user applied a back gesture and core found the focused window without any surface drawn, the input window could still be invisible and the focus request would be pending. In such situation, we should directly inject the back key so it could dispatch to the right focused window after the focus request is applied. Test: atest BackNavigationControllerTests Bug: 260265858 Change-Id: I77b1cad23d458927715333bdcef701f5cf409347 --- data/etc/services.core.protolog.json | 6 ++++++ .../server/wm/BackNavigationController.java | 6 ++++++ .../wm/BackNavigationControllerTests.java | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 4cc06e33ab622..33467404e38fe 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -4171,6 +4171,12 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, + "1945495497": { + "message": "Focused window didn't have a valid surface drawn.", + "level": "DEBUG", + "group": "WM_DEBUG_BACK_PREVIEW", + "at": "com\/android\/server\/wm\/BackNavigationController.java" + }, "1947239194": { "message": "Deferring rotation, still finishing previous rotation", "level": "VERBOSE", diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java index 798e73906761e..8680f1bd8b283 100644 --- a/services/core/java/com/android/server/wm/BackNavigationController.java +++ b/services/core/java/com/android/server/wm/BackNavigationController.java @@ -168,6 +168,12 @@ class BackNavigationController { + "recents. Overriding back callback to recents controller callback."); return null; } + + if (!window.isDrawn()) { + ProtoLog.d(WM_DEBUG_BACK_PREVIEW, + "Focused window didn't have a valid surface drawn."); + return null; + } } if (window == null) { diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java index dc3515dec2f59..b1d4fdf13e1be 100644 --- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java @@ -150,6 +150,7 @@ public class BackNavigationControllerTests extends WindowTestsBase { WindowState window = createWindow(null, WindowManager.LayoutParams.TYPE_WALLPAPER, "Wallpaper"); addToWindowMap(window, true); + makeWindowVisibleAndDrawn(window); IOnBackInvokedCallback callback = createOnBackInvokedCallback(); window.setOnBackInvokedCallbackInfo( @@ -236,6 +237,20 @@ public class BackNavigationControllerTests extends WindowTestsBase { 1, appLatch.getCount()); } + @Test + public void backInfoWindowWithoutDrawn() { + WindowState window = createWindow(null, WindowManager.LayoutParams.TYPE_APPLICATION, + "TestWindow"); + addToWindowMap(window, true); + + IOnBackInvokedCallback callback = createOnBackInvokedCallback(); + window.setOnBackInvokedCallbackInfo( + new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_DEFAULT)); + + BackNavigationInfo backNavigationInfo = startBackNavigation(); + assertThat(backNavigationInfo).isNull(); + } + private IOnBackInvokedCallback withSystemCallback(Task task) { IOnBackInvokedCallback callback = createOnBackInvokedCallback(); task.getTopMostActivity().getTopChild().setOnBackInvokedCallbackInfo( @@ -309,6 +324,7 @@ public class BackNavigationControllerTests extends WindowTestsBase { Mockito.doNothing().when(task).reparentSurfaceControl(any(), any()); mAtm.setFocusedTask(task.mTaskId, record); addToWindowMap(window, true); + makeWindowVisibleAndDrawn(window); return task; } @@ -333,6 +349,8 @@ public class BackNavigationControllerTests extends WindowTestsBase { addToWindowMap(window1, true); addToWindowMap(window2, true); + makeWindowVisibleAndDrawn(window2); + CrossActivityTestCase testCase = new CrossActivityTestCase(); testCase.task = task; testCase.recordBack = record1;