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.
      */