Add WindowInfosListener to Input

Register a WindowInfosListener in InputDispatcher to allow
it to listen for window info changes rather than SurfaceFlinger
having to talk directly to InputDispatcher.

Test: Existing tests pass
Bug: 188792659
Change-Id: If6ccfb0c8c5af0a7b3777c9002157128568cbb6e
diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h
index b0c631a..7af1f0e 100644
--- a/libs/gui/include/gui/WindowInfo.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -242,18 +242,6 @@
     }
 
     /**
-     * Requests that the state of this object be updated to reflect
-     * the most current available information about the application.
-     * As this class is created as RefBase object, no pure virtual function is allowed.
-     *
-     * This method should only be called from within the input dispatcher's
-     * critical section.
-     *
-     * Returns true on success, or false if the handle is no longer valid.
-     */
-    virtual bool updateInfo() { return false; }
-
-    /**
      * Updates from another input window handle.
      */
     void updateFrom(const sp<WindowInfoHandle> handle);
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 24d186c..73e5749 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -96,6 +96,7 @@
         "libinputflinger_base",
         "libinputreporter",
         "libinputreader",
+        "libgui",
     ],
     static_libs: [
         "libinputdispatcher",
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index e81dcfe..693b1f9 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -114,15 +114,6 @@
     return mDispatcher;
 }
 
-class BinderWindowHandle : public WindowInfoHandle {
-public:
-    BinderWindowHandle(const WindowInfo& info) { mInfo = info; }
-
-    bool updateInfo() override {
-        return true;
-    }
-};
-
 binder::Status InputManager::setInputWindows(
         const std::vector<WindowInfo>& infos,
         const sp<ISetInputWindowsListener>& setInputWindowsListener) {
@@ -131,7 +122,7 @@
     std::vector<sp<WindowInfoHandle>> handles;
     for (const auto& info : infos) {
         handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
-        handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info));
+        handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
     }
     mDispatcher->setInputWindows(handlesPerDisplay);
 
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index f77c029..5e9facf 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -185,10 +185,11 @@
                      const sp<InputDispatcher>& dispatcher, const std::string name)
           : FakeInputReceiver(dispatcher, name), mFrame(Rect(0, 0, WIDTH, HEIGHT)) {
         inputApplicationHandle->updateInfo();
+        updateInfo();
         mInfo.applicationInfo = *inputApplicationHandle->getInfo();
     }
 
-    virtual bool updateInfo() override {
+    void updateInfo() {
         mInfo.token = mClientChannel->getConnectionToken();
         mInfo.name = "FakeWindowHandle";
         mInfo.type = WindowInfo::Type::APPLICATION;
@@ -207,8 +208,6 @@
         mInfo.ownerPid = INJECTOR_PID;
         mInfo.ownerUid = INJECTOR_UID;
         mInfo.displayId = ADISPLAY_ID_DEFAULT;
-
-        return true;
     }
 
 protected:
diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp
index 7c7a16b..171f2b5 100644
--- a/services/inputflinger/dispatcher/Android.bp
+++ b/services/inputflinger/dispatcher/Android.bp
@@ -64,6 +64,7 @@
         "libstatspull",
         "libstatssocket",
         "libui",
+        "libgui",
         "libutils",
         "lib-platform-compat-native-api",
         "server_configurable_flags",
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 9f4108d..d32d6f4 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -55,6 +55,7 @@
 #include <binder/Binder.h>
 #include <binder/IServiceManager.h>
 #include <com/android/internal/compat/IPlatformCompatNative.h>
+#include <gui/SurfaceComposerClient.h>
 #include <input/InputDevice.h>
 #include <log/log.h>
 #include <log/log_event_list.h>
@@ -559,6 +560,10 @@
     }
 }
 
+void InputDispatcher::onFirstRef() {
+    SurfaceComposerClient::getDefault()->addWindowInfosListener(this);
+}
+
 status_t InputDispatcher::start() {
     if (mThread) {
         return ALREADY_EXISTS;
@@ -4436,11 +4441,6 @@
 
     std::vector<sp<WindowInfoHandle>> newHandles;
     for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
-        if (!handle->updateInfo()) {
-            // handle no longer valid
-            continue;
-        }
-
         const WindowInfo* info = handle->getInfo();
         if ((getInputChannelLocked(handle->getToken()) == nullptr &&
              info->portalToDisplayId == ADISPLAY_ID_NONE)) {
@@ -6240,4 +6240,16 @@
     mLooper->wake();
 }
 
+void InputDispatcher::onWindowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos) {
+    // The listener sends the windows as a flattened array. Separate the windows by display for
+    // more convenient parsing.
+    std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
+
+    for (const auto& info : windowInfos) {
+        handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
+        handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
+    }
+    setInputWindows(handlesPerDisplay);
+}
+
 } // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 87dd6ee..2436e73 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -58,6 +58,7 @@
 
 #include <InputListener.h>
 #include <InputReporterInterface.h>
+#include <gui/WindowInfosListener.h>
 
 namespace android::inputdispatcher {
 
@@ -80,7 +81,7 @@
  *
  *     A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
  */
-class InputDispatcher : public android::InputDispatcherInterface {
+class InputDispatcher : public android::InputDispatcherInterface, public gui::WindowInfosListener {
 protected:
     ~InputDispatcher() override;
 
@@ -142,6 +143,8 @@
 
     void displayRemoved(int32_t displayId) override;
 
+    void onWindowInfosChanged(const std::vector<gui::WindowInfo>& windowInfos) override;
+
 private:
     enum class DropReason {
         NOT_DROPPED,
@@ -659,6 +662,8 @@
 
     sp<InputReporterInterface> mReporter;
     sp<com::android::internal::compat::IPlatformCompatNative> mCompatService;
+
+    void onFirstRef() override;
 };
 
 } // namespace android::inputdispatcher
diff --git a/services/inputflinger/tests/FocusResolver_test.cpp b/services/inputflinger/tests/FocusResolver_test.cpp
index 8c0edca..662be80 100644
--- a/services/inputflinger/tests/FocusResolver_test.cpp
+++ b/services/inputflinger/tests/FocusResolver_test.cpp
@@ -41,7 +41,6 @@
         mInfo.focusable = focusable;
     }
 
-    bool updateInfo() { return true; }
     void setFocusable(bool focusable) { mInfo.focusable = focusable; }
     void setVisible(bool visible) { mInfo.visible = visible; }
 };
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index a568220..f884a4b 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -937,8 +937,6 @@
         mInfo.displayId = displayId;
     }
 
-    virtual bool updateInfo() { return true; }
-
     void setFocusable(bool focusable) { mInfo.focusable = focusable; }
 
     void setVisible(bool visible) { mInfo.visible = visible; }