diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2023-01-31 00:12:44 -0800 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2023-01-31 00:12:44 -0800 |
commit | f287b7f7690091a56f5baae564e18d610d5f256a (patch) | |
tree | 9433bad45fe81c7404871b66531e736a40aae58f | |
parent | 7a5850eb57b58ed34d9992a0bdd62e584f3385c0 (diff) | |
parent | f01087e659f54f3caeab98fab28fc03b327e7ae5 (diff) |
Merge f01087e659f54f3caeab98fab28fc03b327e7ae5 on remote branch
Change-Id: I49706308dbf30f53750a69d926fc395ec961e59d
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 29 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 95 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 13 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 1 |
4 files changed, 113 insertions, 25 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index d8120fcb5e..5c47be9be0 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -2276,6 +2276,20 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds); } } + + // Update the pointerIds for non-splittable when it received pointer down. + if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) { + // If no split, we suppose all touched windows should receive pointer down. + const int32_t pointerIndex = getMotionEventActionPointerIndex(action); + for (size_t i = 0; i < tempTouchState.windows.size(); i++) { + TouchedWindow& touchedWindow = tempTouchState.windows[i]; + // Ignore drag window for it should just track one pointer. + if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) { + continue; + } + touchedWindow.pointerIds.markBit(entry.pointerProperties[pointerIndex].id); + } + } } // Update dispatching for hover enter and exit. @@ -2384,13 +2398,15 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( if (info->displayId == displayId && windowHandle->getInfo()->inputConfig.test( WindowInfo::InputConfig::IS_WALLPAPER)) { + BitSet32 pointerIds; + pointerIds.markBit(entry.pointerProperties[0].id); tempTouchState .addOrUpdateWindow(windowHandle, InputTarget::FLAG_WINDOW_IS_OBSCURED | InputTarget:: FLAG_WINDOW_IS_PARTIALLY_OBSCURED | InputTarget::FLAG_DISPATCH_AS_IS, - BitSet32(0)); + pointerIds); } } } @@ -2460,17 +2476,6 @@ Failed: } i += 1; } - } else if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) { - // If no split, we suppose all touched windows should receive pointer down. - const int32_t pointerIndex = getMotionEventActionPointerIndex(action); - for (size_t i = 0; i < tempTouchState.windows.size(); i++) { - TouchedWindow& touchedWindow = tempTouchState.windows[i]; - // Ignore drag window for it should just track one pointer. - if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) { - continue; - } - touchedWindow.pointerIds.markBit(entry.pointerProperties[pointerIndex].id); - } } // Save changes unless the action was scroll in which case the temporary touch diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index b74005eb3b..49caefa5bb 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -1890,6 +1890,64 @@ TEST_F(InputDispatcherTest, TwoWindows_SplitWallpaperTouch) { wallpaperWindow->assertNoEvents(); } +TEST_F(InputDispatcherTest, WallpaperWindowReceivesMultiTouch) { + std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); + sp<FakeWindowHandle> window = + sp<FakeWindowHandle>::make(application, mDispatcher, "Top", ADISPLAY_ID_DEFAULT); + window->setDupTouchToWallpaper(true); + + sp<FakeWindowHandle> wallpaperWindow = + sp<FakeWindowHandle>::make(application, mDispatcher, "Wallpaper", ADISPLAY_ID_DEFAULT); + wallpaperWindow->setIsWallpaper(true); + constexpr int expectedWallpaperFlags = + AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED; + wallpaperWindow->setPreventSplitting(true); + + mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window, wallpaperWindow}}}); + + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, + {50, 50})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + window->consumeMotionDown(ADISPLAY_ID_DEFAULT); + wallpaperWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT, expectedWallpaperFlags); + + const MotionEvent secondFingerDownEvent = + MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .displayId(ADISPLAY_ID_DEFAULT) + .eventTime(systemTime(SYSTEM_TIME_MONOTONIC)) + .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50)) + .pointer(PointerBuilder(/* id */ 1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(10).y(10)) + .build(); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT, + InputEventInjectionSync::WAIT_FOR_RESULT)) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + + window->consumeMotionPointerDown(1); + wallpaperWindow->consumeMotionPointerDown(1, ADISPLAY_ID_DEFAULT, expectedWallpaperFlags); + + const MotionEvent secondFingerUpEvent = + MotionEventBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN) + .displayId(ADISPLAY_ID_DEFAULT) + .eventTime(systemTime(SYSTEM_TIME_MONOTONIC)) + .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50)) + .pointer(PointerBuilder(/* id */ 1, AMOTION_EVENT_TOOL_TYPE_FINGER).x(10).y(10)) + .build(); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, secondFingerUpEvent, INJECT_EVENT_TIMEOUT, + InputEventInjectionSync::WAIT_FOR_RESULT)) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + window->consumeMotionPointerUp(1); + wallpaperWindow->consumeMotionPointerUp(1, ADISPLAY_ID_DEFAULT, expectedWallpaperFlags); + + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, {50, 50})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + window->consumeMotionUp(ADISPLAY_ID_DEFAULT); + wallpaperWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT, expectedWallpaperFlags); +} + /** * On the display, have a single window, and also an area where there's no window. * First pointer touches the "no window" area of the screen. Second pointer touches the window. @@ -2325,6 +2383,43 @@ TEST_F(InputDispatcherTest, OnWindowInfosChanged_RemoveAllWindowsOnDisplay) { window->assertNoEvents(); } +TEST_F(InputDispatcherTest, NonSplitTouchableWindowReceivesMultiTouch) { + std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>(); + sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, + "Fake Window", ADISPLAY_ID_DEFAULT); + // Ensure window is non-split and have some transform. + window->setPreventSplitting(true); + window->setWindowOffset(20, 40); + mDispatcher->onWindowInfosChanged({*window->getInfo()}, {}); + + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, + {50, 50})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + window->consumeMotionDown(ADISPLAY_ID_DEFAULT); + + const MotionEvent secondFingerDownEvent = + MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN) + .displayId(ADISPLAY_ID_DEFAULT) + .eventTime(systemTime(SYSTEM_TIME_MONOTONIC)) + .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50)) + .pointer(PointerBuilder(/* id */ 1, AMOTION_EVENT_TOOL_TYPE_FINGER) + .x(-30) + .y(-50)) + .build(); + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT, + InputEventInjectionSync::WAIT_FOR_RESULT)) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + + const MotionEvent* event = window->consumeMotion(); + EXPECT_EQ(POINTER_1_DOWN, event->getAction()); + EXPECT_EQ(70, event->getX(0)); // 50 + 20 + EXPECT_EQ(90, event->getY(0)); // 50 + 40 + EXPECT_EQ(-10, event->getX(1)); // -30 + 20 + EXPECT_EQ(-10, event->getY(1)); // -50 + 40 +} + /** * Ensure the correct coordinate spaces are used by InputDispatcher. * diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 0699ae0108..bc19446747 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2441,21 +2441,10 @@ nsecs_t SurfaceFlinger::getVsyncPeriodFromHWC() const { return 0; } -sp<DisplayDevice> SurfaceFlinger::getCurrentVsyncSource() { - std::lock_guard<std::recursive_mutex> lockVsync(mVsyncLock); - - if (mNextVsyncSource) { - return mNextVsyncSource; - } else if (mActiveVsyncSource) { - return mActiveVsyncSource; - } - - return getDefaultDisplayDeviceLocked(); -} - nsecs_t SurfaceFlinger::getVsyncPeriodFromHWCcb() { std::lock_guard<std::recursive_mutex> lockVsync(mVsyncLock); + Mutex::Autolock lock(mStateLock); auto display = getDefaultDisplayDeviceLocked(); if (mNextVsyncSource) { display = mNextVsyncSource; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index add68af3c1..c41d7ab816 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1122,7 +1122,6 @@ private: */ nsecs_t getVsyncPeriodFromHWC() const REQUIRES(mStateLock); nsecs_t getVsyncPeriodFromHWCcb(); - sp<DisplayDevice> getCurrentVsyncSource(); void setHWCVsyncEnabled(PhysicalDisplayId id, hal::Vsync enabled) { mLastHWCVsyncState = enabled; |