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

Commit 8de96493 authored by utzcoz's avatar utzcoz Committed by Bruno Martins
Browse files

Fix NPE when resizing with transferring focus failed



If InputManager.transferTouchFocus failed when resizing, the
TaskPositioningController will call TaskPositioner.unregister
to unregister InputChannel. But the mClientCallback used by
unregister is initialized by TaskPositioner.startDrag called after
InputManager.transferTouchFocus, so it will cause NPE problem.

Add NPE checking before using mClientCallback to fix this problem.

Test: atest WmTests:TaskPositioningControllerTests

Change-Id: I245a6a3591975cdbfa6453e490cb88aa2c2fe672
Signed-off-by: default avatarutzcoz <utzcoz@gmail.com>
parent aaecaa08
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -351,8 +351,10 @@ class TaskPositioner implements IBinder.DeathRecipient {
        }
        mDisplayContent.resumeRotationLocked();
        mDisplayContent = null;
        if (mClientCallback != null) {
            mClientCallback.unlinkToDeath(this, 0 /* flags */);
        }
    }

    void startDrag(WindowState win, boolean resize, boolean preserveOrientation, float startX,
                   float startY) {
+29 −7
Original line number Diff line number Diff line
@@ -123,13 +123,7 @@ public class TaskPositioningControllerTests extends WindowTestsBase {
            assertNull(mTarget.getDragWindowHandleLocked());
        }

        final DisplayContent content = mock(DisplayContent.class);
        when(content.findTaskForResizePoint(anyInt(), anyInt())).thenReturn(mWindow.getTask());
        assertNotNull(mWindow.getTask().getTopVisibleAppMainWindow());

        mTarget.handleTapOutsideTask(content, 0, 0);
        // Wait until the looper processes finishTaskPositioning.
        assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS));
        triggerHandleTapOutsideTask();

        synchronized (mWm.mGlobalLock) {
            assertTrue(mTarget.isPositioningLocked());
@@ -143,4 +137,32 @@ public class TaskPositioningControllerTests extends WindowTestsBase {
        assertFalse(mTarget.isPositioningLocked());
        assertNull(mTarget.getDragWindowHandleLocked());
    }

    @Test
    public void testHandleTapOutsideTaskWithTransferTouchFocusFailed() {
        when(mWm.mInputManager.transferTouchFocus(
                any(InputChannel.class),
                any(InputChannel.class))).thenReturn(false);
        synchronized (mWm.mGlobalLock) {
            assertFalse(mTarget.isPositioningLocked());
            assertNull(mTarget.getDragWindowHandleLocked());
        }

        triggerHandleTapOutsideTask();

        synchronized (mWm.mGlobalLock) {
            assertFalse(mTarget.isPositioningLocked());
            assertNull(mTarget.getDragWindowHandleLocked());
        }
    }

    private void triggerHandleTapOutsideTask() {
        final DisplayContent content = mock(DisplayContent.class);
        when(content.findTaskForResizePoint(anyInt(), anyInt())).thenReturn(mWindow.getTask());
        assertNotNull(mWindow.getTask().getTopVisibleAppMainWindow());

        mTarget.handleTapOutsideTask(content, 0, 0);
        // Wait until the looper processes finishTaskPositioning.
        assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS));
    }
}