Add InputDispatcherInterface::transferTouch api
The new api will allow the transfer of touch from the current
window (wherever that may be) to the specified window.
Bug: 177997773
Test: atest inputflinger_tests
Change-Id: I6acd17cfb6de0fa8466c73e99e27c0b283864eae
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 9a43ed9..8ea71fe 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4741,6 +4741,40 @@
return true;
}
+// Binder call
+bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
+ sp<IBinder> fromToken;
+ { // acquire lock
+ std::scoped_lock _l(mLock);
+
+ sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
+ if (toWindowHandle == nullptr) {
+ ALOGW("Could not find window associated with token=%p", destChannelToken.get());
+ return false;
+ }
+
+ const int32_t displayId = toWindowHandle->getInfo()->displayId;
+
+ auto touchStateIt = mTouchStatesByDisplay.find(displayId);
+ if (touchStateIt == mTouchStatesByDisplay.end()) {
+ ALOGD("Could not transfer touch because the display %" PRId32 " is not being touched",
+ displayId);
+ return false;
+ }
+
+ TouchState& state = touchStateIt->second;
+ if (state.windows.size() != 1) {
+ ALOGW("Cannot transfer touch state because there are %zu windows being touched",
+ state.windows.size());
+ return false;
+ }
+ const TouchedWindow& touchedWindow = state.windows[0];
+ fromToken = touchedWindow.windowHandle->getToken();
+ } // release lock
+
+ return transferTouchFocus(fromToken, destChannelToken);
+}
+
void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
if (DEBUG_FOCUS) {
ALOGD("Resetting and dropping all events (%s).", reason);
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 7ba03e8..6edc5f1 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -81,60 +81,60 @@
*/
class InputDispatcher : public android::InputDispatcherInterface {
protected:
- virtual ~InputDispatcher();
+ ~InputDispatcher() override;
public:
explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
- virtual void dump(std::string& dump) override;
- virtual void monitor() override;
- virtual bool waitForIdle() override;
- virtual status_t start() override;
- virtual status_t stop() override;
+ void dump(std::string& dump) override;
+ void monitor() override;
+ bool waitForIdle() override;
+ status_t start() override;
+ status_t stop() override;
- virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override;
- virtual void notifyKey(const NotifyKeyArgs* args) override;
- virtual void notifyMotion(const NotifyMotionArgs* args) override;
- virtual void notifySwitch(const NotifySwitchArgs* args) override;
- virtual void notifySensor(const NotifySensorArgs* args) override;
- virtual void notifyVibratorState(const NotifyVibratorStateArgs* args) override;
- virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
- virtual void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) override;
+ void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override;
+ void notifyKey(const NotifyKeyArgs* args) override;
+ void notifyMotion(const NotifyMotionArgs* args) override;
+ void notifySwitch(const NotifySwitchArgs* args) override;
+ void notifySensor(const NotifySensorArgs* args) override;
+ void notifyVibratorState(const NotifyVibratorStateArgs* args) override;
+ void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
+ void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) override;
- virtual android::os::InputEventInjectionResult injectInputEvent(
+ android::os::InputEventInjectionResult injectInputEvent(
const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
android::os::InputEventInjectionSync syncMode, std::chrono::milliseconds timeout,
uint32_t policyFlags) override;
- virtual std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) override;
+ std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) override;
- virtual void setInputWindows(
- const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
- handlesPerDisplay) override;
- virtual void setFocusedApplication(
+ void setInputWindows(const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
+ handlesPerDisplay) override;
+ void setFocusedApplication(
int32_t displayId,
const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) override;
- virtual void setFocusedDisplay(int32_t displayId) override;
- virtual void setInputDispatchMode(bool enabled, bool frozen) override;
- virtual void setInputFilterEnabled(bool enabled) override;
- virtual void setInTouchMode(bool inTouchMode) override;
- virtual void setMaximumObscuringOpacityForTouch(float opacity) override;
- virtual void setBlockUntrustedTouchesMode(android::os::BlockUntrustedTouchesMode mode) override;
+ void setFocusedDisplay(int32_t displayId) override;
+ void setInputDispatchMode(bool enabled, bool frozen) override;
+ void setInputFilterEnabled(bool enabled) override;
+ void setInTouchMode(bool inTouchMode) override;
+ void setMaximumObscuringOpacityForTouch(float opacity) override;
+ void setBlockUntrustedTouchesMode(android::os::BlockUntrustedTouchesMode mode) override;
- virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
- bool isDragDrop = false) override;
+ bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
+ bool isDragDrop = false) override;
+ bool transferTouch(const sp<IBinder>& destChannelToken) override;
- virtual base::Result<std::unique_ptr<InputChannel>> createInputChannel(
+ base::Result<std::unique_ptr<InputChannel>> createInputChannel(
const std::string& name) override;
- virtual void setFocusedWindow(const FocusRequest&) override;
- virtual base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId,
- bool isGestureMonitor,
- const std::string& name,
- int32_t pid) override;
- virtual status_t removeInputChannel(const sp<IBinder>& connectionToken) override;
- virtual status_t pilferPointers(const sp<IBinder>& token) override;
- virtual void requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) override;
- virtual bool flushSensor(int deviceId, InputDeviceSensorType sensorType) override;
+ void setFocusedWindow(const FocusRequest&) override;
+ base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId,
+ bool isGestureMonitor,
+ const std::string& name,
+ int32_t pid) override;
+ status_t removeInputChannel(const sp<IBinder>& connectionToken) override;
+ status_t pilferPointers(const sp<IBinder>& token) override;
+ void requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) override;
+ bool flushSensor(int deviceId, InputDeviceSensorType sensorType) override;
std::array<uint8_t, 32> sign(const VerifiedInputEvent& event) const;
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index b601dfc..7f85e53 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -151,6 +151,14 @@
*/
virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
bool isDragDrop) = 0;
+
+ /**
+ * Transfer touch focus to the provided channel, no matter where the current touch is.
+ *
+ * Return true on success, false if there was no on-going touch.
+ */
+ virtual bool transferTouch(const sp<IBinder>& destChannelToken) = 0;
+
/**
* Sets focus on the specified window.
*/