summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Arthur Hung <arthurhung@google.com> 2021-03-19 06:16:21 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-03-19 06:16:21 +0000
commitd5ecb64ef43ea1e6fb85c1abe2bd9d679bc3df9b (patch)
tree3d4bf090a51e7cf1af9b6348cc92599a97229bb8
parent718f955e7f0536e6c7f996e578bdaa164ec8157c (diff)
parentf452d0b9bbfa019422801b7ae132bb31fccd181e (diff)
Merge "Move drag event to InputDispatcher (5/n)" into sc-dev
-rw-r--r--services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp2
-rw-r--r--services/inputflinger/dispatcher/Entry.h2
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp20
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.h3
-rw-r--r--services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h3
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp44
6 files changed, 74 insertions, 0 deletions
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index b2ddb42eab..7bd0c6b1b8 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -113,6 +113,8 @@ private:
void setPointerCapture(bool enabled) override {}
+ void notifyDropWindow(const sp<IBinder>&, float x, float y) override {}
+
InputDispatcherConfiguration mConfig;
};
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index e5fb26c177..f3ef64ba8e 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -287,6 +287,8 @@ struct CommandEntry {
int32_t pid;
nsecs_t consumeTime; // time when the event was consumed by InputConsumer
int32_t displayId;
+ float x;
+ float y;
};
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index fe46d17493..397a9d78e5 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2345,6 +2345,10 @@ void InputDispatcher::addDragEventLocked(const MotionEntry& entry, TouchState& s
}
} else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
+ if (state.dragHoverWindowHandle && maskedAction == AMOTION_EVENT_ACTION_UP) {
+ vec2 local = state.dragHoverWindowHandle->getInfo()->transform.transform(x, y);
+ notifyDropWindowLocked(state.dragHoverWindowHandle->getToken(), local.x, local.y);
+ }
state.dragWindow = nullptr;
state.dragHoverWindowHandle = nullptr;
}
@@ -5302,6 +5306,15 @@ void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
postCommandLocked(std::move(commandEntry));
}
+void InputDispatcher::notifyDropWindowLocked(const sp<IBinder>& token, float x, float y) {
+ std::unique_ptr<CommandEntry> commandEntry =
+ std::make_unique<CommandEntry>(&InputDispatcher::doNotifyDropWindowLockedInterruptible);
+ commandEntry->newToken = token;
+ commandEntry->x = x;
+ commandEntry->y = y;
+ postCommandLocked(std::move(commandEntry));
+}
+
void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
if (connection == nullptr) {
LOG_ALWAYS_FATAL("Caller must check for nullness");
@@ -5411,6 +5424,13 @@ void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* comm
mLock.lock();
}
+void InputDispatcher::doNotifyDropWindowLockedInterruptible(CommandEntry* commandEntry) {
+ sp<IBinder> newToken = commandEntry->newToken;
+ mLock.unlock();
+ mPolicy->notifyDropWindow(newToken, commandEntry->x, commandEntry->y);
+ mLock.lock();
+}
+
void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
mLock.unlock();
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index b2f3625a73..593ec23e23 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -592,6 +592,7 @@ private:
void onFocusChangedLocked(const FocusResolver::FocusChanges& changes) REQUIRES(mLock);
void notifyFocusChangedLocked(const sp<IBinder>& oldFocus, const sp<IBinder>& newFocus)
REQUIRES(mLock);
+ void notifyDropWindowLocked(const sp<IBinder>& token, float x, float y) REQUIRES(mLock);
void onAnrLocked(const sp<Connection>& connection) REQUIRES(mLock);
void onAnrLocked(std::shared_ptr<InputApplicationHandle> application) REQUIRES(mLock);
void onUntrustedTouchLocked(const std::string& obscuringPackage) REQUIRES(mLock);
@@ -607,6 +608,8 @@ private:
REQUIRES(mLock);
void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
void doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
+ void doNotifyDropWindowLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
+
// ANR-related callbacks - start
void doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
void doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
index 439d85e06e..219f45a7c3 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
@@ -157,6 +157,9 @@ public:
* InputDispatcher is solely responsible for updating the Pointer Capture state.
*/
virtual void setPointerCapture(bool enabled) = 0;
+
+ /* Notifies the policy that the drag window has moved over to another window */
+ virtual void notifyDropWindow(const sp<IBinder>& token, float x, float y) = 0;
};
} // namespace android
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 32f9b69806..cedda6e91c 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -266,6 +266,11 @@ public:
mPointerCaptureEnabled.reset();
}
+ void assertDropTargetEquals(const sp<IBinder>& targetToken) {
+ std::scoped_lock lock(mLock);
+ ASSERT_EQ(targetToken, mDropTargetWindowToken);
+ }
+
private:
std::mutex mLock;
std::unique_ptr<InputEvent> mFilteredEvent GUARDED_BY(mLock);
@@ -284,6 +289,8 @@ private:
std::queue<int32_t> mResponsiveMonitorPids GUARDED_BY(mLock);
std::condition_variable mNotifyAnr;
+ sp<IBinder> mDropTargetWindowToken GUARDED_BY(mLock);
+
void notifyConfigurationChanged(nsecs_t when) override {
std::scoped_lock lock(mLock);
mConfigurationChangedTime = when;
@@ -392,6 +399,11 @@ private:
mPointerCaptureChangedCondition.notify_all();
}
+ void notifyDropWindow(const sp<IBinder>& token, float x, float y) override {
+ std::scoped_lock lock(mLock);
+ mDropTargetWindowToken = token;
+ }
+
void assertFilterInputEventWasCalled(int type, nsecs_t eventTime, int32_t action,
int32_t displayId) {
std::scoped_lock lock(mLock);
@@ -4789,4 +4801,36 @@ TEST_F(InputDispatcherDragTests, DragEnterAndDragExit) {
mSecondWindow->assertNoEvents();
}
+TEST_F(InputDispatcherDragTests, DragAndDrop) {
+ performDrag();
+
+ // Move on window.
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
+ ADISPLAY_ID_DEFAULT, {50, 50}))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT);
+ mWindow->consumeDragEvent(false, 50, 50);
+ mSecondWindow->assertNoEvents();
+
+ // Move to another window.
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
+ ADISPLAY_ID_DEFAULT, {150, 50}))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT);
+ mWindow->consumeDragEvent(true, 150, 50);
+ mSecondWindow->consumeDragEvent(false, 50, 50);
+
+ // drop to another window.
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
+ {150, 50}))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT);
+ mFakePolicy->assertDropTargetEquals(mSecondWindow->getToken());
+ mWindow->assertNoEvents();
+ mSecondWindow->assertNoEvents();
+}
+
} // namespace android::inputdispatcher