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