diff options
| author | 2021-09-28 04:39:20 +0000 | |
|---|---|---|
| committer | 2021-09-28 04:40:58 +0000 | |
| commit | f16f283f43a78e92dbbcdadf9651d94b57d30dbc (patch) | |
| tree | 5c697f9dc01d7284054d6a0e19c6b1ff96be1817 | |
| parent | 967bf71311907c9d6b12ef268a8a38d7c718b17f (diff) | |
TouchEvent (4/n) Firing event when setting mInTouchMode
Roll forward ag/15925114
This reverts commit 967bf71311907c9d6b12ef268a8a38d7c718b17f.
Bug: 193718270
Change-Id: Iab2e33e23ce7e9dd59fa09bb81e388369e6496ef
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 80 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.h | 2 | ||||
| -rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 69 |
3 files changed, 124 insertions, 27 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index f094fee282..53c34f6de1 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -88,6 +88,9 @@ constexpr bool DEBUG_INJECTION = false; // Log debug messages about input focus tracking. constexpr bool DEBUG_FOCUS = false; +// Log debug messages about touch mode event +constexpr bool DEBUG_TOUCH_MODE = false; + // Log debug messages about touch occlusion // STOPSHIP(b/169067926): Set to false constexpr bool DEBUG_TOUCH_OCCLUSION = true; @@ -534,6 +537,23 @@ vec2 transformWithoutTranslation(const ui::Transform& transform, float x, float return transformedXy - transformedOrigin; } +// Returns true if the event type passed as argument represents a user activity. +bool isUserActivityEvent(const EventEntry& eventEntry) { + switch (eventEntry.type) { + case EventEntry::Type::FOCUS: + case EventEntry::Type::POINTER_CAPTURE_CHANGED: + case EventEntry::Type::DRAG: + case EventEntry::Type::TOUCH_MODE_CHANGED: + case EventEntry::Type::SENSOR: + case EventEntry::Type::CONFIGURATION_CHANGED: + return false; + case EventEntry::Type::DEVICE_RESET: + case EventEntry::Type::KEY: + case EventEntry::Type::MOTION: + return true; + } +} + } // namespace // --- InputDispatcher --- @@ -552,7 +572,7 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic // mInTouchMode will be initialized by the WindowManager to the default device config. // To avoid leaking stack in case that call never comes, and for tests, // initialize it here anyways. - mInTouchMode(true), + mInTouchMode(kDefaultInTouchMode), mMaximumObscuringOpacityForTouch(1.0f), mFocusedDisplayId(ADISPLAY_ID_DEFAULT), mWindowTokenWithPointerCapture(nullptr), @@ -1790,9 +1810,9 @@ int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) { displayId = motionEntry.displayId; break; } + case EventEntry::Type::TOUCH_MODE_CHANGED: case EventEntry::Type::POINTER_CAPTURE_CHANGED: case EventEntry::Type::FOCUS: - case EventEntry::Type::TOUCH_MODE_CHANGED: case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: case EventEntry::Type::SENSOR: @@ -2773,11 +2793,8 @@ std::string InputDispatcher::getApplicationWindowLabel( } void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) { - if (eventEntry.type == EventEntry::Type::FOCUS || - eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED || - eventEntry.type == EventEntry::Type::DRAG) { - // Focus or pointer capture changed events are passed to apps, but do not represent user - // activity. + if (!isUserActivityEvent(eventEntry)) { + // Not poking user activity if the event type does not represent a user activity return; } int32_t displayId = getTargetDisplayId(eventEntry); @@ -2813,16 +2830,7 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) { eventType = USER_ACTIVITY_EVENT_BUTTON; break; } - case EventEntry::Type::TOUCH_MODE_CHANGED: { - break; - } - - case EventEntry::Type::FOCUS: - case EventEntry::Type::CONFIGURATION_CHANGED: - case EventEntry::Type::DEVICE_RESET: - case EventEntry::Type::SENSOR: - case EventEntry::Type::POINTER_CAPTURE_CHANGED: - case EventEntry::Type::DRAG: { + default: { LOG_ALWAYS_FATAL("%s events are not user activity", ftl::enum_string(eventEntry.type).c_str()); break; @@ -3795,7 +3803,7 @@ void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChange ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime); } - bool needWake; + bool needWake = false; { // acquire lock std::scoped_lock _l(mLock); @@ -3890,7 +3898,7 @@ void InputDispatcher::notifyKey(const NotifyKeyArgs* args) { std::to_string(t.duration().count()).c_str()); } - bool needWake; + bool needWake = false; { // acquire lock mLock.lock(); @@ -3967,7 +3975,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) { std::to_string(t.duration().count()).c_str()); } - bool needWake; + bool needWake = false; { // acquire lock mLock.lock(); @@ -4032,7 +4040,7 @@ void InputDispatcher::notifySensor(const NotifySensorArgs* args) { ftl::enum_string(args->sensorType).c_str()); } - bool needWake; + bool needWake = false; { // acquire lock mLock.lock(); @@ -4082,7 +4090,7 @@ void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) { args->deviceId); } - bool needWake; + bool needWake = false; { // acquire lock std::scoped_lock _l(mLock); @@ -4102,7 +4110,7 @@ void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChan args->request.enable ? "true" : "false"); } - bool needWake; + bool needWake = false; { // acquire lock std::scoped_lock _l(mLock); auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime, @@ -4919,9 +4927,29 @@ void InputDispatcher::setInputFilterEnabled(bool enabled) { } void InputDispatcher::setInTouchMode(bool inTouchMode) { - std::scoped_lock lock(mLock); - mInTouchMode = inTouchMode; - // TODO(b/193718270): Fire TouchModeEvent here. + bool needWake = false; + { + std::scoped_lock lock(mLock); + if (mInTouchMode == inTouchMode) { + return; + } + if (DEBUG_TOUCH_MODE) { + ALOGD("Request to change touch mode from %s to %s", toString(mInTouchMode), + toString(inTouchMode)); + // TODO(b/198487159): Also print the current last interacted apps. + } + + // TODO(b/198499018): Store touch mode per display. + mInTouchMode = inTouchMode; + + // TODO(b/198487159): Enforce that only last interacted apps can change touch mode. + auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode); + needWake = enqueueInboundEventLocked(std::move(entry)); + } // release lock + + if (needWake) { + mLooper->wake(); + } } void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) { diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index 2282d917b7..e1544d8044 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -86,6 +86,8 @@ protected: ~InputDispatcher() override; public: + static constexpr bool kDefaultInTouchMode = true; + explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy); void dump(std::string& dump) override; diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 7fb2ccf94b..3207495aaf 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -817,6 +817,9 @@ public: case AINPUT_EVENT_TYPE_CAPTURE: { FAIL() << "Use 'consumeCaptureEvent' for CAPTURE events"; } + case AINPUT_EVENT_TYPE_TOUCH_MODE: { + FAIL() << "Use 'consumeTouchModeEvent' for TOUCH_MODE events"; + } case AINPUT_EVENT_TYPE_DRAG: { FAIL() << "Use 'consumeDragEvent' for DRAG events"; } @@ -874,6 +877,20 @@ public: EXPECT_EQ(y, dragEvent.getY()); } + void consumeTouchModeEvent(bool inTouchMode) { + const InputEvent* event = consume(); + ASSERT_NE(nullptr, event) << mName.c_str() + << ": consumer should have returned non-NULL event."; + ASSERT_EQ(AINPUT_EVENT_TYPE_TOUCH_MODE, event->getType()) + << "Got " << inputEventTypeToString(event->getType()) + << " event instead of TOUCH_MODE event"; + + ASSERT_EQ(ADISPLAY_ID_NONE, event->getDisplayId()) + << mName.c_str() << ": event displayId should always be NONE."; + const auto& touchModeEvent = static_cast<const TouchModeEvent&>(*event); + EXPECT_EQ(inTouchMode, touchModeEvent.isInTouchMode()); + } + void assertNoEvents() { InputEvent* event = consume(); if (event == nullptr) { @@ -895,6 +912,10 @@ public: const auto& captureEvent = static_cast<CaptureEvent&>(*event); ADD_FAILURE() << "Received capture event, pointerCaptureEnabled = " << (captureEvent.getPointerCaptureEnabled() ? "true" : "false"); + } else if (event->getType() == AINPUT_EVENT_TYPE_TOUCH_MODE) { + const auto& touchModeEvent = static_cast<TouchModeEvent&>(*event); + ADD_FAILURE() << "Received touch mode event, inTouchMode = " + << (touchModeEvent.isInTouchMode() ? "true" : "false"); } FAIL() << mName.c_str() << ": should not have received any events, so consume() should return NULL"; @@ -1087,6 +1108,12 @@ public: mInputReceiver->consumeDragEvent(isExiting, x, y); } + void consumeTouchModeEvent(bool inTouchMode) { + ASSERT_NE(mInputReceiver, nullptr) + << "Cannot consume events from a window with no receiver"; + mInputReceiver->consumeTouchModeEvent(inTouchMode); + } + std::optional<uint32_t> receiveEvent(InputEvent** outEvent = nullptr) { if (mInputReceiver == nullptr) { ADD_FAILURE() << "Invalid receive event on window with no receiver"; @@ -2725,7 +2752,6 @@ TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) { SCOPED_TRACE("Check default value of touch mode"); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); setFocusedWindow(window); - window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/); SCOPED_TRACE("Remove the window to trigger focus loss"); @@ -2735,6 +2761,7 @@ TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) { SCOPED_TRACE("Disable touch mode"); mDispatcher->setInTouchMode(false); + window->consumeTouchModeEvent(false); window->setFocusable(true); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); setFocusedWindow(window); @@ -2747,6 +2774,7 @@ TEST_F(InputDispatcherTest, TouchModeState_IsSentToApps) { SCOPED_TRACE("Enable touch mode again"); mDispatcher->setInTouchMode(true); + window->consumeTouchModeEvent(true); window->setFocusable(true); mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}}); setFocusedWindow(window); @@ -5882,4 +5910,43 @@ TEST_F(InputDispatcherDropInputFeatureTest, UnobscuredWindowGetsInput) { window->assertNoEvents(); } +class InputDispatcherTouchModeChangedTests : public InputDispatcherTest { +protected: + std::shared_ptr<FakeApplicationHandle> mApp; + sp<FakeWindowHandle> mWindow; + sp<FakeWindowHandle> mSecondWindow; + + void SetUp() override { + InputDispatcherTest::SetUp(); + + mApp = std::make_shared<FakeApplicationHandle>(); + mWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow", ADISPLAY_ID_DEFAULT); + mWindow->setFocusable(true); + mSecondWindow = new FakeWindowHandle(mApp, mDispatcher, "TestWindow2", ADISPLAY_ID_DEFAULT); + mSecondWindow->setFocusable(true); + + mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, mApp); + mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mSecondWindow}}}); + + setFocusedWindow(mWindow); + mWindow->consumeFocusEvent(true); + } + + void changeAndVerifyTouchMode(bool inTouchMode) { + mDispatcher->setInTouchMode(inTouchMode); + mWindow->consumeTouchModeEvent(inTouchMode); + mSecondWindow->consumeTouchModeEvent(inTouchMode); + } +}; + +TEST_F(InputDispatcherTouchModeChangedTests, ChangeTouchModeOnFocusedWindow) { + changeAndVerifyTouchMode(!InputDispatcher::kDefaultInTouchMode); +} + +TEST_F(InputDispatcherTouchModeChangedTests, EventIsNotGeneratedIfNotChangingTouchMode) { + mDispatcher->setInTouchMode(InputDispatcher::kDefaultInTouchMode); + mWindow->assertNoEvents(); + mSecondWindow->assertNoEvents(); +} + } // namespace android::inputdispatcher |