Unregister input channel by token

An input channel is uniquely identified by its token. Once the input
channel exists, you can unregister it simply using its token.

There's no need to pass back the entire input channel, including its id,
to input dispatcher. We will look for the server-side input channel
using the token anyways.

Bug: 167947395
Test: atest libinput_tests
Change-Id: I009da372bd6cc897b019a66e9c3bbed78cc91223
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 287a6f4..29446d8 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -156,7 +156,7 @@
         EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
     }
 
-    ~InputSurface() { mInputFlinger->unregisterInputChannel(*mServerChannel); }
+    ~InputSurface() { mInputFlinger->unregisterInputChannel(mServerChannel->getConnectionToken()); }
 
     void doTransaction(std::function<void(SurfaceComposerClient::Transaction&,
                     const sp<SurfaceControl>&)> transactionBody) {
diff --git a/libs/input/android/os/IInputFlinger.aidl b/libs/input/android/os/IInputFlinger.aidl
index 5eefad3..0cdf0bb 100644
--- a/libs/input/android/os/IInputFlinger.aidl
+++ b/libs/input/android/os/IInputFlinger.aidl
@@ -31,7 +31,7 @@
     oneway void setInputWindows(in InputWindowInfo[] inputHandles,
             in @nullable ISetInputWindowsListener setInputWindowsListener);
     void registerInputChannel(in InputChannel channel);
-    void unregisterInputChannel(in InputChannel channel);
+    void unregisterInputChannel(in IBinder connectionToken);
     /**
      * Sets focus to the window identified by the token. This must be called
      * after updating any input window handles.
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index e49667e..8af9bcb 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -132,8 +132,8 @@
     return binder::Status::ok();
 }
 
-binder::Status InputManager::unregisterInputChannel(const InputChannel& channel) {
-    mDispatcher->unregisterInputChannel(channel);
+binder::Status InputManager::unregisterInputChannel(const sp<IBinder>& connectionToken) {
+    mDispatcher->unregisterInputChannel(connectionToken);
     return binder::Status::ok();
 }
 
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index bf86a98..35d2d58 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -109,7 +109,7 @@
             const sp<ISetInputWindowsListener>& setInputWindowsListener) override;
 
     binder::Status registerInputChannel(const InputChannel& channel) override;
-    binder::Status unregisterInputChannel(const InputChannel& channel) override;
+    binder::Status unregisterInputChannel(const sp<IBinder>& connectionToken) override;
     binder::Status setFocusedWindow(const FocusRequest&) override;
 
 private:
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index b428c4e..4a1a74e 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -379,7 +379,7 @@
 
     while (!mConnectionsByFd.empty()) {
         sp<Connection> connection = mConnectionsByFd.begin()->second;
-        unregisterInputChannel(*connection->inputChannel);
+        unregisterInputChannel(connection->inputChannel->getConnectionToken());
     }
 }
 
@@ -2793,7 +2793,7 @@
         }
 
         // Unregister the channel.
-        d->unregisterInputChannelLocked(*connection->inputChannel, notify);
+        d->unregisterInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
         return 0; // remove the callback
     }             // release lock
 }
@@ -3313,7 +3313,6 @@
           "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
           event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
 #endif
-
     nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
 
     policyFlags |= POLICY_FLAG_INJECTED;
@@ -4429,15 +4428,11 @@
     return OK;
 }
 
-status_t InputDispatcher::unregisterInputChannel(const InputChannel& inputChannel) {
-#if DEBUG_REGISTRATION
-    ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel.getName().c_str());
-#endif
-
+status_t InputDispatcher::unregisterInputChannel(const sp<IBinder>& connectionToken) {
     { // acquire lock
         std::scoped_lock _l(mLock);
 
-        status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
+        status_t status = unregisterInputChannelLocked(connectionToken, false /*notify*/);
         if (status) {
             return status;
         }
@@ -4449,23 +4444,22 @@
     return OK;
 }
 
-status_t InputDispatcher::unregisterInputChannelLocked(const InputChannel& inputChannel,
+status_t InputDispatcher::unregisterInputChannelLocked(const sp<IBinder>& connectionToken,
                                                        bool notify) {
-    sp<Connection> connection = getConnectionLocked(inputChannel.getConnectionToken());
+    sp<Connection> connection = getConnectionLocked(connectionToken);
     if (connection == nullptr) {
-        ALOGW("Attempted to unregister already unregistered input channel '%s'",
-              inputChannel.getName().c_str());
+        ALOGW("Attempted to unregister already unregistered input channel");
         return BAD_VALUE;
     }
 
     removeConnectionLocked(connection);
-    mInputChannelsByToken.erase(inputChannel.getConnectionToken());
+    mInputChannelsByToken.erase(connectionToken);
 
     if (connection->monitor) {
-        removeMonitorChannelLocked(inputChannel);
+        removeMonitorChannelLocked(connectionToken);
     }
 
-    mLooper->removeFd(inputChannel.getFd());
+    mLooper->removeFd(connection->inputChannel->getFd());
 
     nsecs_t currentTime = now();
     abortBrokenDispatchCycleLocked(currentTime, connection, notify);
@@ -4474,19 +4468,19 @@
     return OK;
 }
 
-void InputDispatcher::removeMonitorChannelLocked(const InputChannel& inputChannel) {
-    removeMonitorChannelLocked(inputChannel, mGlobalMonitorsByDisplay);
-    removeMonitorChannelLocked(inputChannel, mGestureMonitorsByDisplay);
+void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
+    removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
+    removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
 }
 
 void InputDispatcher::removeMonitorChannelLocked(
-        const InputChannel& inputChannel,
+        const sp<IBinder>& connectionToken,
         std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
     for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
         std::vector<Monitor>& monitors = it->second;
         const size_t numMonitors = monitors.size();
         for (size_t i = 0; i < numMonitors; i++) {
-            if (*monitors[i].inputChannel == inputChannel) {
+            if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
                 monitors.erase(monitors.begin() + i);
                 break;
             }
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 93d3fde..c3d6b18 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -121,7 +121,7 @@
     virtual void setFocusedWindow(const FocusRequest&) override;
     virtual status_t registerInputMonitor(const std::shared_ptr<InputChannel>& inputChannel,
                                           int32_t displayId, bool isGestureMonitor) override;
-    virtual status_t unregisterInputChannel(const InputChannel& inputChannel) override;
+    virtual status_t unregisterInputChannel(const sp<IBinder>& connectionToken) override;
     virtual status_t pilferPointers(const sp<IBinder>& token) override;
 
     std::array<uint8_t, 32> sign(const VerifiedInputEvent& event) const;
@@ -490,11 +490,11 @@
     std::string dumpFocusedWindowsLocked() REQUIRES(mLock);
 
     // Registration.
-    void removeMonitorChannelLocked(const InputChannel& inputChannel) REQUIRES(mLock);
+    void removeMonitorChannelLocked(const sp<IBinder>& connectionToken) REQUIRES(mLock);
     void removeMonitorChannelLocked(
-            const InputChannel& inputChannel,
+            const sp<IBinder>& connectionToken,
             std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) REQUIRES(mLock);
-    status_t unregisterInputChannelLocked(const InputChannel& inputChannel, bool notify)
+    status_t unregisterInputChannelLocked(const sp<IBinder>& connectionToken, bool notify)
             REQUIRES(mLock);
 
     // Interesting events that we might like to log or tell the framework about.
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 179a263..c3d50ea 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -176,7 +176,7 @@
      *
      * This method may be called on any thread (usually by the input manager).
      */
-    virtual status_t unregisterInputChannel(const InputChannel& inputChannel) = 0;
+    virtual status_t unregisterInputChannel(const sp<IBinder>& connectionToken) = 0;
 
     /* Allows an input monitor steal the current pointer stream away from normal input windows.
      *
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index 2a2cea5..577309a 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -49,7 +49,7 @@
         return binder::Status::ok();
     }
     binder::Status registerInputChannel(const InputChannel&) { return binder::Status::ok(); }
-    binder::Status unregisterInputChannel(const InputChannel&) { return binder::Status::ok(); }
+    binder::Status unregisterInputChannel(const sp<IBinder>&) { return binder::Status::ok(); }
     binder::Status setFocusedWindow(const FocusRequest&) { return binder::Status::ok(); }
 
 private:
diff --git a/services/inputflinger/tests/InputFlingerService_test.cpp b/services/inputflinger/tests/InputFlingerService_test.cpp
index 99b96e9..3aef1e4 100644
--- a/services/inputflinger/tests/InputFlingerService_test.cpp
+++ b/services/inputflinger/tests/InputFlingerService_test.cpp
@@ -148,7 +148,7 @@
             const sp<ISetInputWindowsListener>& setInputWindowsListener) override;
 
     binder::Status registerInputChannel(const InputChannel& channel) override;
-    binder::Status unregisterInputChannel(const InputChannel& channel) override;
+    binder::Status unregisterInputChannel(const sp<IBinder>& connectionToken) override;
     binder::Status setFocusedWindow(const FocusRequest&) override;
 
 private:
@@ -220,13 +220,13 @@
     return binder::Status::ok();
 }
 
-binder::Status TestInputManager::unregisterInputChannel(const InputChannel& channel) {
+binder::Status TestInputManager::unregisterInputChannel(const sp<IBinder>& connectionToken) {
     AutoMutex _l(mLock);
-    // check Fd flags
-    checkFdFlags(channel.getFd());
 
     auto it = std::find_if(mInputChannels.begin(), mInputChannels.end(),
-                           [&](std::shared_ptr<InputChannel>& c) { return *c == channel; });
+                           [&](std::shared_ptr<InputChannel>& c) {
+                               return c->getConnectionToken() == connectionToken;
+                           });
     if (it != mInputChannels.end()) {
         mInputChannels.erase(it);
     }
@@ -380,7 +380,7 @@
     ASSERT_EQ(channels.size(), 1UL);
     EXPECT_EQ(channels[0], *serverChannel);
 
-    mService->unregisterInputChannel(*serverChannel);
+    mService->unregisterInputChannel(serverChannel->getConnectionToken());
     mQuery->getInputChannels(&channels);
     EXPECT_EQ(channels.size(), 0UL);
 }
@@ -397,15 +397,15 @@
     EXPECT_EQ(channels.size(), 0UL);
 
     mService->registerInputChannel(InputChannel());
-    mService->unregisterInputChannel(*clientChannel);
+    mService->unregisterInputChannel(clientChannel->getConnectionToken());
 
     mService->registerInputChannel(*serverChannel);
     mService->registerInputChannel(*clientChannel);
     mQuery->getInputChannels(&channels);
     EXPECT_EQ(channels.size(), 2UL);
 
-    mService->unregisterInputChannel(*clientChannel);
-    mService->unregisterInputChannel(*serverChannel);
+    mService->unregisterInputChannel(clientChannel->getConnectionToken());
+    mService->unregisterInputChannel(serverChannel->getConnectionToken());
     mQuery->getInputChannels(&channels);
     EXPECT_EQ(channels.size(), 0UL);
 }