Add synchronous transaction to wait for setInputWindow to complete (3/n)

Added callback for InputDispatcher to report back to SF.

Pass in an interface callback to setInputWindows so InputDispatcher can send
a response when setInputWindows has completed. The callback can be null
so InputDispatcher knows not to send a response on every setInputWindows
call.

Bug: 123041491
Test: Builds, runs
Change-Id: I18b28141a0bb5f2e1ffb406d601dc7822ca89ecd
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h
index ff443c6..cd12fcd 100644
--- a/include/input/IInputFlinger.h
+++ b/include/input/IInputFlinger.h
@@ -24,6 +24,7 @@
 
 #include <utils/Vector.h>
 #include <input/InputWindow.h>
+#include <input/ISetInputWindowsListener.h>
 
 namespace android {
 
@@ -35,7 +36,8 @@
 public:
     DECLARE_META_INTERFACE(InputFlinger)
 
-    virtual void setInputWindows(const Vector<InputWindowInfo>& inputHandles) = 0;
+    virtual void setInputWindows(const Vector<InputWindowInfo>& inputHandles,
+            const sp<ISetInputWindowsListener>& setInputWindowsListener) = 0;
     virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;
     virtual void registerInputChannel(const sp<InputChannel>& channel) = 0;
     virtual void unregisterInputChannel(const sp<InputChannel>& channel) = 0;
diff --git a/include/input/ISetInputWindowsListener.h b/include/input/ISetInputWindowsListener.h
new file mode 100644
index 0000000..15d31b2
--- /dev/null
+++ b/include/input/ISetInputWindowsListener.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+class ISetInputWindowsListener : public IInterface {
+public:
+    DECLARE_META_INTERFACE(SetInputWindowsListener)
+    virtual void onSetInputWindowsFinished() = 0;
+};
+
+class BnSetInputWindowsListener: public BnInterface<ISetInputWindowsListener> {
+public:
+    enum SetInputWindowsTag : uint32_t {
+        ON_SET_INPUT_WINDOWS_FINISHED
+    };
+
+    virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                                uint32_t flags = 0) override;
+};
+
+}; // namespace android
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 9197262..f77eeb2 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -806,12 +806,6 @@
         }
         return error;
     }
-
-    virtual void setInputWindowsFinished() {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::SET_INPUT_WINDOWS_FINISHED, data, &reply);
-    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -1323,11 +1317,6 @@
             }
             return removeRegionSamplingListener(listener);
         }
-        case SET_INPUT_WINDOWS_FINISHED: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            setInputWindowsFinished();
-            return NO_ERROR;
-        }
         default: {
             return BBinder::onTransact(code, data, reply, flags);
         }
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index c2d7d28..e6700e7 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -359,8 +359,6 @@
      * Removes a listener that was streaming median luma updates from SurfaceFlinger.
      */
     virtual status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) = 0;
-
-    virtual void setInputWindowsFinished() = 0;
 };
 
 // ----------------------------------------------------------------------------
@@ -408,7 +406,6 @@
         GET_PHYSICAL_DISPLAY_IDS,
         ADD_REGION_SAMPLING_LISTENER,
         REMOVE_REGION_SAMPLING_LISTENER,
-        SET_INPUT_WINDOWS_FINISHED,
 
         // Always append new enum to the end.
     };
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 8430874..32d7391 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -254,7 +254,7 @@
     };
 
     std::vector<TransferTouchFocusCommand> transferTouchFocusCommands;
-    bool syncInputWindows;
+    bool syncInputWindows{false};
 
     void merge(const InputWindowCommands& other);
     void clear();
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 8225647..f127853 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -679,8 +679,6 @@
         return NO_ERROR;
     }
 
-    void setInputWindowsFinished() override {}
-
 protected:
     IBinder* onAsBinder() override { return nullptr; }
 
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 6aedb00..2d78811 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -47,6 +47,7 @@
                 "InputApplication.cpp",
                 "InputTransport.cpp",
                 "InputWindow.cpp",
+                "ISetInputWindowsListener.cpp",
                 "VelocityControl.cpp",
                 "VelocityTracker.cpp",
             ],
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
index acf40bc..4ce5a10 100644
--- a/libs/input/IInputFlinger.cpp
+++ b/libs/input/IInputFlinger.cpp
@@ -30,7 +30,8 @@
     explicit BpInputFlinger(const sp<IBinder>& impl) :
             BpInterface<IInputFlinger>(impl) { }
 
-    virtual void setInputWindows(const Vector<InputWindowInfo>& inputInfo) {
+    virtual void setInputWindows(const Vector<InputWindowInfo>& inputInfo,
+            const sp<ISetInputWindowsListener>& setInputWindowsListener) {
         Parcel data, reply;
         data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
 
@@ -38,6 +39,8 @@
         for (const auto& info : inputInfo) {
             info.write(data);
         }
+        data.writeStrongBinder(IInterface::asBinder(setInputWindowsListener));
+
         remote()->transact(BnInputFlinger::SET_INPUT_WINDOWS_TRANSACTION, data, &reply,
                 IBinder::FLAG_ONEWAY);
     }
@@ -83,7 +86,9 @@
         for (size_t i = 0; i < count; i++) {
             handles.add(InputWindowInfo(data));
         }
-        setInputWindows(handles);
+        const sp<ISetInputWindowsListener> setInputWindowsListener =
+                ISetInputWindowsListener::asInterface(data.readStrongBinder());
+        setInputWindows(handles, setInputWindowsListener);
         break;
     }
     case REGISTER_INPUT_CHANNEL_TRANSACTION: {
diff --git a/libs/input/ISetInputWindowsListener.cpp b/libs/input/ISetInputWindowsListener.cpp
new file mode 100644
index 0000000..a0330da
--- /dev/null
+++ b/libs/input/ISetInputWindowsListener.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <input/ISetInputWindowsListener.h>
+
+namespace android {
+
+class BpSetInputWindowsListener : public BpInterface<ISetInputWindowsListener> {
+public:
+    explicit BpSetInputWindowsListener(const sp<IBinder>& impl)
+        : BpInterface<ISetInputWindowsListener>(impl) {
+    }
+
+    virtual ~BpSetInputWindowsListener() = default;
+
+    virtual void onSetInputWindowsFinished() {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISetInputWindowsListener::getInterfaceDescriptor());
+        remote()->transact(BnSetInputWindowsListener::ON_SET_INPUT_WINDOWS_FINISHED, data, &reply,
+                IBinder::FLAG_ONEWAY);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SetInputWindowsListener, "android.input.ISetInputWindowsListener");
+
+status_t BnSetInputWindowsListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+        uint32_t flags) {
+    switch(code) {
+        case ON_SET_INPUT_WINDOWS_FINISHED: {
+            CHECK_INTERFACE(ISetInputWindowsListener, data, reply);
+            onSetInputWindowsFinished();
+            return NO_ERROR;
+        }
+        default: {
+            return BBinder::onTransact(code, data, reply, flags);
+        }
+    }
+}
+
+} // namespace android
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 2ffd0a8..d288736 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -3072,7 +3072,7 @@
  * For removed handle, check if need to send a cancel event if already in touch.
  */
 void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& inputWindowHandles,
-        int32_t displayId) {
+        int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
 #if DEBUG_FOCUS
     ALOGD("setInputWindows displayId=%" PRId32, displayId);
 #endif
@@ -3222,6 +3222,10 @@
 
     // Wake up poll loop since it may need to make new input dispatching choices.
     mLooper->wake();
+
+    if (setInputWindowsListener) {
+        setInputWindowsListener->onSetInputWindowsFinished();
+    }
 }
 
 void InputDispatcher::setFocusedApplication(
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index ecfeb6c..9d8919b 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -21,6 +21,7 @@
 #include <input/InputApplication.h>
 #include <input/InputTransport.h>
 #include <input/InputWindow.h>
+#include <input/ISetInputWindowsListener.h>
 #include <utils/KeyedVector.h>
 #include <utils/Vector.h>
 #include <utils/threads.h>
@@ -39,7 +40,6 @@
 #include "InputListener.h"
 #include "InputReporterInterface.h"
 
-
 namespace android {
 
 /*
@@ -315,7 +315,8 @@
      * This method may be called on any thread (usually by the input manager).
      */
     virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles,
-            int32_t displayId) = 0;
+            int32_t displayId,
+            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) = 0;
 
     /* Sets the focused application on the given display.
      *
@@ -406,7 +407,8 @@
             uint32_t policyFlags);
 
     virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles,
-            int32_t displayId);
+            int32_t displayId,
+            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr);
     virtual void setFocusedApplication(int32_t displayId,
             const sp<InputApplicationHandle>& inputApplicationHandle);
     virtual void setFocusedDisplay(int32_t displayId);
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index a7fd9ba..b0157a1 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -103,7 +103,8 @@
     }
 };
 
-void InputManager::setInputWindows(const Vector<InputWindowInfo>& infos) {
+void InputManager::setInputWindows(const Vector<InputWindowInfo>& infos,
+        const sp<ISetInputWindowsListener>& setInputWindowsListener) {
     std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> handlesPerDisplay;
 
     Vector<sp<InputWindowHandle>> handles;
@@ -112,7 +113,7 @@
         handlesPerDisplay[info.displayId].add(new BinderWindowHandle(info));
     }
     for (auto const& i : handlesPerDisplay) {
-        mDispatcher->setInputWindows(i.second, i.first);
+        mDispatcher->setInputWindows(i.second, i.first, setInputWindowsListener);
     }
 }
 
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index e632da3..ff9a080 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -29,6 +29,7 @@
 
 #include <input/Input.h>
 #include <input/InputTransport.h>
+#include <input/ISetInputWindowsListener.h>
 
 #include <input/IInputFlinger.h>
 #include <utils/Errors.h>
@@ -93,7 +94,8 @@
     virtual sp<InputClassifierInterface> getClassifier();
     virtual sp<InputDispatcherInterface> getDispatcher();
 
-    virtual void setInputWindows(const Vector<InputWindowInfo>& handles);
+    virtual void setInputWindows(const Vector<InputWindowInfo>& handles,
+            const sp<ISetInputWindowsListener>& setInputWindowsListener);
     virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
 
     virtual void registerInputChannel(const sp<InputChannel>& channel);
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index 9d0be95..a00b5fb 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -24,6 +24,7 @@
 
 #include <cutils/compiler.h>
 #include <input/IInputFlinger.h>
+#include <input/ISetInputWindowsListener.h>
 #include <utils/String8.h>
 #include <utils/String16.h>
 #include <utils/StrongPointer.h>
@@ -39,7 +40,7 @@
     InputFlinger() ANDROID_API;
 
     virtual status_t dump(int fd, const Vector<String16>& args);
-    void setInputWindows(const Vector<InputWindowInfo>&) {}
+    void setInputWindows(const Vector<InputWindowInfo>&, const sp<ISetInputWindowsListener>&) {}
     void transferTouchFocus(const sp<IBinder>&, const sp<IBinder>&) {}
     void registerInputChannel(const sp<InputChannel>&) {}
     void unregisterInputChannel(const sp<InputChannel>&) {}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e1e3dfb..bf17d50 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -297,7 +297,9 @@
         mNumLayers(0),
         mVrFlingerRequestsDisplay(false),
         mMainThreadId(std::this_thread::get_id()),
-        mCompositionEngine{getFactory().createCompositionEngine()} {}
+        mCompositionEngine{getFactory().createCompositionEngine()} {
+    mSetInputWindowsListener = new SetInputWindowsListener(this);
+}
 
 SurfaceFlinger::SurfaceFlinger(surfaceflinger::Factory& factory)
       : SurfaceFlinger(factory, SkipInitialization) {
@@ -2948,7 +2950,10 @@
             inputHandles.add(layer->fillInputInfo());
         }
     });
-    mInputFlinger->setInputWindows(inputHandles);
+
+    mInputFlinger->setInputWindows(inputHandles,
+                                   mInputWindowCommands.syncInputWindows ? mSetInputWindowsListener
+                                                                         : nullptr);
 }
 
 void SurfaceFlinger::commitInputWindowCommands() {
@@ -4907,8 +4912,7 @@
         case GET_COLOR_MANAGEMENT:
         case GET_COMPOSITION_PREFERENCE:
         case GET_PROTECTED_CONTENT_SUPPORT:
-        case IS_WIDE_COLOR_DISPLAY:
-        case SET_INPUT_WINDOWS_FINISHED: {
+        case IS_WIDE_COLOR_DISPLAY: {
             return OK;
         }
         case CAPTURE_LAYERS:
@@ -5667,6 +5671,12 @@
     }
 }
 
+// ----------------------------------------------------------------------------
+
+void SetInputWindowsListener::onSetInputWindowsFinished() {
+    mFlinger->setInputWindowsFinished();
+}
+
 }; // namespace android
 
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 220e664..ee3933e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -33,6 +33,7 @@
 #include <gui/LayerState.h>
 #include <gui/OccupancyTracker.h>
 #include <hardware/hwcomposer_defs.h>
+#include <input/ISetInputWindowsListener.h>
 #include <layerproto/LayerProtoHeader.h>
 #include <math/mat4.h>
 #include <serviceutils/PriorityDumper.h>
@@ -201,6 +202,14 @@
     std::map<wp<IBinder>, std::vector<CompositionInfo>> mEndOfFrameCompositionInfo;
 };
 
+class SetInputWindowsListener : public BnSetInputWindowsListener {
+public:
+    SetInputWindowsListener(const sp<SurfaceFlinger>& flinger) : mFlinger(flinger) {}
+    void onSetInputWindowsFinished() override;
+
+private:
+    const sp<SurfaceFlinger> mFlinger;
+};
 
 class SurfaceFlinger : public BnSurfaceComposer,
                        public PriorityDumper,
@@ -348,6 +357,8 @@
         return mTransactionCompletedThread;
     }
 
+    void setInputWindowsFinished();
+
 private:
     friend class Client;
     friend class DisplayEventConnection;
@@ -477,7 +488,6 @@
     status_t addRegionSamplingListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle,
                                        const sp<IRegionSamplingListener>& listener) override;
     status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) override;
-    void setInputWindowsFinished() override;
     /* ------------------------------------------------------------------------
      * DeathRecipient interface
      */
@@ -1112,6 +1122,8 @@
     InputWindowCommands mInputWindowCommands;
 
     ui::DisplayPrimaries mInternalDisplayPrimaries;
+
+    sp<SetInputWindowsListener> mSetInputWindowsListener;
 };
 }; // namespace android