Merge "Clean up some formatting problems in the setFrameRate ndk docs" into rvc-dev
diff --git a/cmds/cmd/cmd.cpp b/cmds/cmd/cmd.cpp
index 8dad475..be2c702 100644
--- a/cmds/cmd/cmd.cpp
+++ b/cmds/cmd/cmd.cpp
@@ -185,7 +185,7 @@
     int argc = argv.size();
 
     if (argc == 0) {
-        errorLog << "cmd: No service specified; use -l to list all services" << endl;
+        errorLog << "cmd: No service specified; use -l to list all running services. Use -w to start and wait for a service." << endl;
         return 20;
     }
 
@@ -203,14 +203,22 @@
         return 0;
     }
 
-    const auto cmd = argv[0];
+    bool waitForService = ((argc > 1) && (argv[0] == "-w"));
+    int serviceIdx = (waitForService) ? 1 : 0;
+    const auto cmd = argv[serviceIdx];
 
     Vector<String16> args;
     String16 serviceName = String16(cmd.data(), cmd.size());
-    for (int i = 1; i < argc; i++) {
+    for (int i = serviceIdx + 1; i < argc; i++) {
         args.add(String16(argv[i].data(), argv[i].size()));
     }
-    sp<IBinder> service = sm->checkService(serviceName);
+    sp<IBinder> service;
+    if(waitForService) {
+        service = sm->waitForService(serviceName);
+    } else {
+        service = sm->checkService(serviceName);
+    }
+
     if (service == nullptr) {
         if (runMode == RunMode::kStandalone) {
             ALOGW("Can't find service %.*s", static_cast<int>(cmd.size()), cmd.data());
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index a0b9cbb..1824943 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -148,14 +148,13 @@
 }
 
 binder::Status DumpstateService::cancelBugreport() {
-    // This is a no-op since the cancellation is done from java side via setting sys properties.
-    // See BugreportManagerServiceImpl.
-    // TODO(b/111441001): maybe make native and java sides use different binder interface
-    // to avoid these annoyances.
+    std::lock_guard<std::mutex> lock(lock_);
+    ds_->Cancel();
     return binder::Status::ok();
 }
 
 status_t DumpstateService::dump(int fd, const Vector<String16>&) {
+    std::lock_guard<std::mutex> lock(lock_);
     if (ds_ == nullptr) {
         dprintf(fd, "Bugreport not in progress yet");
         return NO_ERROR;
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 01b7e63..772b9fe 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -239,6 +239,9 @@
 }
 
 static bool UnlinkAndLogOnError(const std::string& file) {
+    if (file.empty()) {
+        return false;
+    }
     if (unlink(file.c_str())) {
         MYLOGE("Failed to unlink file (%s): %s\n", file.c_str(), strerror(errno));
         return false;
@@ -246,7 +249,6 @@
     return true;
 }
 
-
 int64_t GetModuleMetadataVersion() {
     auto binder = defaultServiceManager()->getService(android::String16("package_native"));
     if (binder == nullptr) {
@@ -2419,6 +2421,17 @@
     return status;
 }
 
+void Dumpstate::Cancel() {
+    CleanupTmpFiles();
+    android::os::UnlinkAndLogOnError(log_path_);
+    for (int i = 0; i < NUM_OF_DUMPS; i++) {
+        android::os::UnlinkAndLogOnError(ds.bugreport_internal_dir_ + "/" +
+                                         kDumpstateBoardFiles[i]);
+    }
+    tombstone_data_.clear();
+    anr_data_.clear();
+}
+
 /*
  * Dumps relevant information to a bugreport based on the given options.
  *
@@ -2755,7 +2768,7 @@
     return ds.options_->bugreport_fd.get() != -1 ? true : false;
 }
 
-void Dumpstate::CleanupFiles() {
+void Dumpstate::CleanupTmpFiles() {
     android::os::UnlinkAndLogOnError(tmp_path_);
     android::os::UnlinkAndLogOnError(screenshot_path_);
     android::os::UnlinkAndLogOnError(path_);
@@ -2763,7 +2776,7 @@
 
 Dumpstate::RunStatus Dumpstate::HandleUserConsentDenied() {
     MYLOGD("User denied consent; deleting files and returning\n");
-    CleanupFiles();
+    CleanupTmpFiles();
     return USER_CONSENT_DENIED;
 }
 
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 7b8d282..9ce662b 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -334,6 +334,9 @@
 
     RunStatus ParseCommandlineAndRun(int argc, char* argv[]);
 
+    /* Deletes in-progress files */
+    void Cancel();
+
     /* Sets runtime options. */
     void SetOptions(std::unique_ptr<DumpOptions> options);
 
@@ -502,7 +505,7 @@
 
     // Removes the in progress files output files (tmp file, zip/txt file, screenshot),
     // but leaves the log file alone.
-    void CleanupFiles();
+    void CleanupTmpFiles();
 
     RunStatus HandleUserConsentDenied();
 
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index abe6436..cbbea12 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -522,6 +522,11 @@
         return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
     }
 
+    if (serviceIt->second.guaranteeClient) {
+        LOG(INFO) << "Tried to unregister " << name << ", but there is about to be a client.";
+        return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
+    }
+
     int clients = handleServiceClientCallback(name, false);
 
     // clients < 0: feature not implemented or other error. Assume clients.
@@ -532,6 +537,8 @@
     if (clients < 0 || clients > 2) {
         // client callbacks are either disabled or there are other clients
         LOG(INFO) << "Tried to unregister " << name << ", but there are clients: " << clients;
+        // Set this flag to ensure the clients are acknowledged in the next callback
+        serviceIt->second.guaranteeClient = true;
         return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
     }
 
diff --git a/include/android/thermal.h b/include/android/thermal.h
index 0f4b4d9..3247fa1 100644
--- a/include/android/thermal.h
+++ b/include/android/thermal.h
@@ -109,7 +109,7 @@
  * It's passed the updated thermal status as parameter, as well as the
  * pointer provided by the client that registered a callback.
  */
-typedef int (*AThermal_StatusCallback)(void *data, AThermalStatus status);
+typedef void (*AThermal_StatusCallback)(void *data, AThermalStatus status);
 
 /**
   * Acquire an instance of the thermal manager. This must be freed using
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index 71d8130..74aece8 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -31,11 +31,16 @@
 
 class ClientCounterCallback : public ::android::os::BnClientCallback {
 public:
-    ClientCounterCallback() : mNumConnectedServices(0) {}
+    ClientCounterCallback() : mNumConnectedServices(0), mForcePersist(false) {}
 
     bool registerService(const sp<IBinder>& service, const std::string& name,
                          bool allowIsolated, int dumpFlags);
 
+    /**
+     * Set a flag to prevent services from automatically shutting down
+     */
+    void forcePersist(bool persist);
+
 protected:
     Status onClients(const sp<IBinder>& service, bool clients) override;
 
@@ -60,6 +65,8 @@
      * Map of registered names and services
      */
     std::map<std::string, Service> mRegisteredServices;
+
+    bool mForcePersist;
 };
 
 bool ClientCounterCallback::registerService(const sp<IBinder>& service, const std::string& name,
@@ -88,6 +95,14 @@
     return true;
 }
 
+void ClientCounterCallback::forcePersist(bool persist) {
+    mForcePersist = persist;
+    if(!mForcePersist) {
+        // Attempt a shutdown in case the number of clients hit 0 while the flag was on
+        tryShutdown();
+    }
+}
+
 /**
  * onClients is oneway, so no need to worry about multi-threading. Note that this means multiple
  * invocations could occur on different threads however.
@@ -103,14 +118,21 @@
           mNumConnectedServices, mRegisteredServices.size(),
           String8(service->getInterfaceDescriptor()).string(), clients);
 
-    if (mNumConnectedServices == 0) {
-        tryShutdown();
-    }
-
+    tryShutdown();
     return Status::ok();
 }
 
 void ClientCounterCallback::tryShutdown() {
+    if(mNumConnectedServices > 0) {
+        // Should only shut down if there are no clients
+        return;
+    }
+
+    if(mForcePersist) {
+        ALOGI("Shutdown prevented by forcePersist override flag.");
+        return;
+    }
+
     ALOGI("Trying to shut down the service. No clients in use for any service in process.");
 
     auto manager = interface_cast<AidlServiceManager>(asBinder(defaultServiceManager()));
@@ -165,5 +187,9 @@
     return OK;
 }
 
+void LazyServiceRegistrar::forcePersist(bool persist) {
+    mClientCC->forcePersist(persist);
+}
+
 }  // namespace hardware
 }  // namespace android
\ No newline at end of file
diff --git a/libs/binder/include/binder/LazyServiceRegistrar.h b/libs/binder/include/binder/LazyServiceRegistrar.h
index efdecc4..6d711bc 100644
--- a/libs/binder/include/binder/LazyServiceRegistrar.h
+++ b/libs/binder/include/binder/LazyServiceRegistrar.h
@@ -34,6 +34,12 @@
                               const std::string& name = "default",
                               bool allowIsolated = false,
                               int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT);
+     /**
+      * Force the service to persist, even when it has 0 clients.
+      * If setting this flag from the server side, make sure to do so before calling registerService,
+      * or there may be a race with the default dynamic shutdown.
+      */
+     void forcePersist(bool persist);
 
    private:
      std::shared_ptr<internal::ClientCounterCallback> mClientCC;
diff --git a/libs/ui/include/ui/Size.h b/libs/ui/include/ui/Size.h
index c2cda17..f1e8252 100644
--- a/libs/ui/include/ui/Size.h
+++ b/libs/ui/include/ui/Size.h
@@ -109,11 +109,11 @@
     // Takes a value of type FromType, and ensures it can be represented as a value of type ToType,
     // clamping the input value to the output range if necessary.
     template <typename ToType, typename FromType>
-    static Size::remove_cv_reference_t<ToType> clamp(
-            typename std::enable_if<
-                    std::numeric_limits<Size::remove_cv_reference_t<ToType>>::is_bounded &&
-                            std::numeric_limits<Size::remove_cv_reference_t<FromType>>::is_bounded,
-                    FromType&&>::type v) {
+    static Size::remove_cv_reference_t<ToType>
+    clamp(typename std::enable_if<
+            std::numeric_limits<Size::remove_cv_reference_t<ToType>>::is_specialized &&
+                    std::numeric_limits<Size::remove_cv_reference_t<FromType>>::is_specialized,
+            FromType>::type v) {
         using BareToType = remove_cv_reference_t<ToType>;
         using BareFromType = remove_cv_reference_t<FromType>;
         static constexpr auto toHighest = std::numeric_limits<BareToType>::max();
@@ -121,21 +121,58 @@
         static constexpr auto fromHighest = std::numeric_limits<BareFromType>::max();
         static constexpr auto fromLowest = std::numeric_limits<BareFromType>::lowest();
 
-        // A clamp is needed if the range of FromType is not a subset of the range of ToType
-        static constexpr bool isClampNeeded = (toLowest > fromLowest) || (toHighest < fromHighest);
+        // Get the closest representation of [toLowest, toHighest] in type
+        // FromType to use to clamp the input value before conversion.
+
+        // std::common_type<...> is used to get a value-preserving type for the
+        // top end of the range.
+        using CommonHighestType = std::common_type_t<BareToType, BareFromType>;
+
+        // std::make_signed<std::common_type<...>> is used to get a
+        // value-preserving type for the bottom end of the range, except this is
+        // a bit trickier for non-integer types like float.
+        using CommonLowestType =
+                std::conditional_t<std::numeric_limits<CommonHighestType>::is_integer,
+                                   std::make_signed_t<std::conditional_t<
+                                           std::numeric_limits<CommonHighestType>::is_integer,
+                                           CommonHighestType, int /* not used */>>,
+                                   CommonHighestType>;
+
+        // We can then compute the clamp range in a way that can be later
+        // trivially converted to either the 'from' or 'to' types, and be
+        // representabile in either.
+        static constexpr auto commonClampHighest =
+                std::min(static_cast<CommonHighestType>(fromHighest),
+                         static_cast<CommonHighestType>(toHighest));
+        static constexpr auto commonClampLowest =
+                std::max(static_cast<CommonLowestType>(fromLowest),
+                         static_cast<CommonLowestType>(toLowest));
+
+        static constexpr auto fromClampHighest = static_cast<BareFromType>(commonClampHighest);
+        static constexpr auto fromClampLowest = static_cast<BareFromType>(commonClampLowest);
+
+        // A clamp is needed only if the range we are clamping to is not the
+        // same as the range of the input.
+        static constexpr bool isClampNeeded =
+                (fromLowest != fromClampLowest) || (fromHighest != fromClampHighest);
 
         // If a clamp is not needed, the conversion is just a trivial cast.
         if (!isClampNeeded) {
-            return static_cast<ToType>(v);
+            return static_cast<BareToType>(v);
         }
 
-        // Otherwise we need to carefully compare the limits of ToType (casted
-        // for the comparisons to be warning free to FromType) while still
-        // ensuring we return a value clamped to the range of ToType.
-        return v < static_cast<const BareFromType>(toLowest)
-                ? toLowest
-                : (v > static_cast<const BareFromType>(toHighest) ? toHighest
-                                                                  : static_cast<ToType>(v));
+        // Note: Clang complains about the value of INT32_MAX not being
+        // convertible back to int32_t from float if this is made "constexpr",
+        // when clamping a float value to an int32_t value. This is however
+        // covered by a test case to ensure the run-time cast works correctly.
+        const auto toClampHighest = static_cast<BareToType>(commonClampHighest);
+        const auto toClampLowest = static_cast<BareToType>(commonClampLowest);
+
+        // Otherwise clamping is done by using the already computed endpoints
+        // for each type.
+        return (v <= fromClampLowest)
+                ? toClampLowest
+                : ((v >= fromClampHighest) ? toClampHighest : static_cast<BareToType>(v));
     }
 };
 
diff --git a/libs/ui/tests/Size_test.cpp b/libs/ui/tests/Size_test.cpp
index 40dc702..38f37ad 100644
--- a/libs/ui/tests/Size_test.cpp
+++ b/libs/ui/tests/Size_test.cpp
@@ -186,9 +186,34 @@
 
 TEST(SizeTest, FloatRangeIsClamped) {
     ClampTest(std::numeric_limits<float>::max(), std::numeric_limits<int32_t>::max());
+    ClampTest(nexttowardf(std::numeric_limits<int32_t>::max(), std::numeric_limits<float>::max()),
+              std::numeric_limits<int32_t>::max());
+    ClampTest(static_cast<float>(std::numeric_limits<int32_t>::max()),
+              std::numeric_limits<int32_t>::max());
+    ClampTest(nexttowardf(std::numeric_limits<int32_t>::max(), 0),
+              static_cast<int32_t>(nexttowardf(std::numeric_limits<int32_t>::max(), 0)));
     ClampTest(float(0), int32_t(0));
+    ClampTest(nexttowardf(std::numeric_limits<int32_t>::lowest(), 0),
+              static_cast<int32_t>(nexttowardf(std::numeric_limits<int32_t>::lowest(), 0)));
+    ClampTest(static_cast<float>(std::numeric_limits<int32_t>::lowest()),
+              std::numeric_limits<int32_t>::lowest());
+    ClampTest(nexttowardf(std::numeric_limits<int32_t>::lowest(),
+                          std::numeric_limits<float>::lowest()),
+              std::numeric_limits<int32_t>::lowest());
     ClampTest(std::numeric_limits<float>::lowest(), std::numeric_limits<int32_t>::lowest());
 }
 
+TEST(SizeTest, Uint32RangeIsClamped) {
+    ClampTest(std::numeric_limits<uint32_t>::max(), std::numeric_limits<int32_t>::max());
+    ClampTest(std::numeric_limits<uint32_t>::max() - 1, std::numeric_limits<int32_t>::max());
+    ClampTest(static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) + 1,
+              std::numeric_limits<int32_t>::max());
+    ClampTest(static_cast<uint32_t>(std::numeric_limits<int32_t>::max()),
+              std::numeric_limits<int32_t>::max());
+    ClampTest(static_cast<uint32_t>(std::numeric_limits<int32_t>::max()) - 1,
+              std::numeric_limits<int32_t>::max() - 1);
+    ClampTest(uint32_t(0), int32_t(0));
+}
+
 } // namespace ui
 } // namespace android
diff --git a/opengl/TEST_MAPPING b/opengl/TEST_MAPPING
new file mode 100644
index 0000000..d391dce
--- /dev/null
+++ b/opengl/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsGpuToolsHostTestCases"
+    }
+  ]
+}
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index e68946d..fc771a2 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -111,10 +111,8 @@
         handlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
         handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info));
     }
-    mDispatcher->setInputWindows(handlesPerDisplay);
-
-    if (setInputWindowsListener) {
-        setInputWindowsListener->onSetInputWindowsFinished();
+    for (auto const& i : handlesPerDisplay) {
+        mDispatcher->setInputWindows(i.second, i.first, setInputWindowsListener);
     }
 }
 
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index 7c5c9c5..3b18813 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -252,7 +252,7 @@
     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
     sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
 
-    dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    dispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     NotifyMotionArgs motionArgs = generateMotionArgs();
 
@@ -288,7 +288,7 @@
     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
     sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
 
-    dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    dispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     for (auto _ : state) {
         MotionEvent event = generateMotionEvent();
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 4ec61b0..308d19b 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3621,18 +3621,6 @@
     mWindowHandlesByDisplay[displayId] = newHandles;
 }
 
-void InputDispatcher::setInputWindows(
-        const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
-    { // acquire lock
-        std::scoped_lock _l(mLock);
-        for (auto const& i : handlesPerDisplay) {
-            setInputWindowsLocked(i.second, i.first);
-        }
-    }
-    // Wake up poll loop since it may need to make new input dispatching choices.
-    mLooper->wake();
-}
-
 /**
  * Called from InputManagerService, update window handle list by displayId that can receive input.
  * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
@@ -3640,8 +3628,9 @@
  * For focused handle, check if need to change and send a cancel event to previous one.
  * For removed handle, check if need to send a cancel event if already in touch.
  */
-void InputDispatcher::setInputWindowsLocked(
-        const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
+void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
+                                      int32_t displayId,
+                                      const sp<ISetInputWindowsListener>& setInputWindowsListener) {
     if (DEBUG_FOCUS) {
         std::string windowList;
         for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
@@ -3649,97 +3638,109 @@
         }
         ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
     }
+    { // acquire lock
+        std::scoped_lock _l(mLock);
 
-    // Copy old handles for release if they are no longer present.
-    const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
+        // Copy old handles for release if they are no longer present.
+        const std::vector<sp<InputWindowHandle>> oldWindowHandles =
+                getWindowHandlesLocked(displayId);
 
-    updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
+        updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
 
-    sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
-    bool foundHoveredWindow = false;
-    for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
-        // Set newFocusedWindowHandle to the top most focused window instead of the last one
-        if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
-            windowHandle->getInfo()->visible) {
-            newFocusedWindowHandle = windowHandle;
-        }
-        if (windowHandle == mLastHoverWindowHandle) {
-            foundHoveredWindow = true;
-        }
-    }
-
-    if (!foundHoveredWindow) {
-        mLastHoverWindowHandle = nullptr;
-    }
-
-    sp<InputWindowHandle> oldFocusedWindowHandle =
-            getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
-
-    if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
-        if (oldFocusedWindowHandle != nullptr) {
-            if (DEBUG_FOCUS) {
-                ALOGD("Focus left window: %s in display %" PRId32,
-                      oldFocusedWindowHandle->getName().c_str(), displayId);
+        sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
+        bool foundHoveredWindow = false;
+        for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
+            // Set newFocusedWindowHandle to the top most focused window instead of the last one
+            if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
+                windowHandle->getInfo()->visible) {
+                newFocusedWindowHandle = windowHandle;
             }
-            sp<InputChannel> focusedInputChannel =
-                    getInputChannelLocked(oldFocusedWindowHandle->getToken());
-            if (focusedInputChannel != nullptr) {
-                CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
-                                           "focus left window");
-                synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
-                enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
+            if (windowHandle == mLastHoverWindowHandle) {
+                foundHoveredWindow = true;
             }
-            mFocusedWindowHandlesByDisplay.erase(displayId);
-        }
-        if (newFocusedWindowHandle != nullptr) {
-            if (DEBUG_FOCUS) {
-                ALOGD("Focus entered window: %s in display %" PRId32,
-                      newFocusedWindowHandle->getName().c_str(), displayId);
-            }
-            mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
-            enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
         }
 
-        if (mFocusedDisplayId == displayId) {
-            onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
+        if (!foundHoveredWindow) {
+            mLastHoverWindowHandle = nullptr;
         }
-    }
 
-    ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
-    if (stateIndex >= 0) {
-        TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
-        for (size_t i = 0; i < state.windows.size();) {
-            TouchedWindow& touchedWindow = state.windows[i];
-            if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
+        sp<InputWindowHandle> oldFocusedWindowHandle =
+                getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
+
+        if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
+            if (oldFocusedWindowHandle != nullptr) {
                 if (DEBUG_FOCUS) {
-                    ALOGD("Touched window was removed: %s in display %" PRId32,
-                          touchedWindow.windowHandle->getName().c_str(), displayId);
+                    ALOGD("Focus left window: %s in display %" PRId32,
+                          oldFocusedWindowHandle->getName().c_str(), displayId);
                 }
-                sp<InputChannel> touchedInputChannel =
-                        getInputChannelLocked(touchedWindow.windowHandle->getToken());
-                if (touchedInputChannel != nullptr) {
-                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
-                                               "touched window was removed");
-                    synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
+                sp<InputChannel> focusedInputChannel =
+                        getInputChannelLocked(oldFocusedWindowHandle->getToken());
+                if (focusedInputChannel != nullptr) {
+                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
+                                               "focus left window");
+                    synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
+                    enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
                 }
-                state.windows.erase(state.windows.begin() + i);
-            } else {
-                ++i;
+                mFocusedWindowHandlesByDisplay.erase(displayId);
             }
-        }
-    }
+            if (newFocusedWindowHandle != nullptr) {
+                if (DEBUG_FOCUS) {
+                    ALOGD("Focus entered window: %s in display %" PRId32,
+                          newFocusedWindowHandle->getName().c_str(), displayId);
+                }
+                mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
+                enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
+            }
 
-    // Release information for windows that are no longer present.
-    // This ensures that unused input channels are released promptly.
-    // Otherwise, they might stick around until the window handle is destroyed
-    // which might not happen until the next GC.
-    for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
-        if (!hasWindowHandleLocked(oldWindowHandle)) {
-            if (DEBUG_FOCUS) {
-                ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
+            if (mFocusedDisplayId == displayId) {
+                onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
             }
-            oldWindowHandle->releaseChannel();
         }
+
+        ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
+        if (stateIndex >= 0) {
+            TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
+            for (size_t i = 0; i < state.windows.size();) {
+                TouchedWindow& touchedWindow = state.windows[i];
+                if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
+                    if (DEBUG_FOCUS) {
+                        ALOGD("Touched window was removed: %s in display %" PRId32,
+                              touchedWindow.windowHandle->getName().c_str(), displayId);
+                    }
+                    sp<InputChannel> touchedInputChannel =
+                            getInputChannelLocked(touchedWindow.windowHandle->getToken());
+                    if (touchedInputChannel != nullptr) {
+                        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+                                                   "touched window was removed");
+                        synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
+                                                                         options);
+                    }
+                    state.windows.erase(state.windows.begin() + i);
+                } else {
+                    ++i;
+                }
+            }
+        }
+
+        // Release information for windows that are no longer present.
+        // This ensures that unused input channels are released promptly.
+        // Otherwise, they might stick around until the window handle is destroyed
+        // which might not happen until the next GC.
+        for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
+            if (!hasWindowHandleLocked(oldWindowHandle)) {
+                if (DEBUG_FOCUS) {
+                    ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
+                }
+                oldWindowHandle->releaseChannel();
+            }
+        }
+    } // release lock
+
+    // Wake up poll loop since it may need to make new input dispatching choices.
+    mLooper->wake();
+
+    if (setInputWindowsListener) {
+        setInputWindowsListener->onSetInputWindowsFinished();
     }
 }
 
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index cbba7e1..4aa47f8 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -109,8 +109,8 @@
     virtual std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) override;
 
     virtual void setInputWindows(
-            const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
-                    handlesPerDisplay) override;
+            const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId,
+            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) override;
     virtual void setFocusedApplication(
             int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) override;
     virtual void setFocusedDisplay(int32_t displayId) override;
@@ -278,8 +278,6 @@
 
     std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay
             GUARDED_BY(mLock);
-    void setInputWindowsLocked(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
-                               int32_t displayId) REQUIRES(mLock);
     // Get window handles by display, return an empty vector if not found.
     std::vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const
             REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 09dc92c..6e98676 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -19,7 +19,6 @@
 
 #include <InputListener.h>
 #include <input/ISetInputWindowsListener.h>
-#include <unordered_map>
 
 namespace android {
 
@@ -100,13 +99,13 @@
      */
     virtual std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) = 0;
 
-    /* Sets the list of input windows per display.
+    /* Sets the list of input windows.
      *
      * This method may be called on any thread (usually by the input manager).
      */
     virtual void setInputWindows(
-            const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
-                    handlesPerDisplay) = 0;
+            const std::vector<sp<InputWindowHandle> >& inputWindowHandles, int32_t displayId,
+            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) = 0;
 
     /* Sets the focused application on the given display.
      *
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 29f3dac..1f283b1 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -871,7 +871,7 @@
     sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
             ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -888,7 +888,7 @@
     sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
             ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
+    mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -910,7 +910,7 @@
 
     // Display should have only one focused window
     windowSecond->setFocus(true);
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
+    mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
 
     windowSecond->consumeFocusEvent(true);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
@@ -935,7 +935,7 @@
     windowTop->setFocus(true);
     windowSecond->setFocus(true);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
+    mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
     windowTop->consumeFocusEvent(true);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -960,7 +960,7 @@
     windowSecond->setFocus(true);
     // Release channel for window is no longer valid.
     windowTop->releaseChannel();
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
+    mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
     windowSecond->consumeFocusEvent(true);
 
     // Test inject a key down, should dispatch to a valid window.
@@ -986,7 +986,7 @@
 
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
+    mDispatcher->setInputWindows({windowLeft, windowRight}, ADISPLAY_ID_DEFAULT);
 
     // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
     // left window. This event should be dispatched to the left window.
@@ -1003,7 +1003,7 @@
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
     window->setFocus(true);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
     window->consumeFocusEvent(true);
 
     NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
@@ -1025,7 +1025,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     NotifyMotionArgs motionArgs =
             generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -1053,7 +1053,7 @@
             "Second Window", ADISPLAY_ID_DEFAULT);
 
     // Add the windows to the dispatcher
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
+    mDispatcher->setInputWindows({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
 
     // Send down to the first window
     NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
@@ -1090,7 +1090,7 @@
             "Second Window", ADISPLAY_ID_DEFAULT);
 
     // Add the windows to the dispatcher
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
+    mDispatcher->setInputWindows({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
 
     // Send down to the first window
     NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
@@ -1152,7 +1152,7 @@
             | InputWindowInfo::FLAG_SPLIT_TOUCH);
 
     // Add the windows to the dispatcher
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
+    mDispatcher->setInputWindows({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
 
     PointF pointInFirst = {300, 200};
     PointF pointInSecond = {300, 600};
@@ -1204,7 +1204,7 @@
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
     window->setFocus(true);
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     window->consumeFocusEvent(true);
 
@@ -1220,7 +1220,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
     mDispatcher->notifyKey(&keyArgs);
@@ -1235,7 +1235,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     // Send key
     NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
@@ -1289,7 +1289,7 @@
     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
                                                       true /*isGestureMonitor*/);
@@ -1309,7 +1309,7 @@
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
     window->setFocus(true);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
     window->consumeFocusEvent(true);
 
     FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
@@ -1325,7 +1325,7 @@
     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
                                                       true /*isGestureMonitor*/);
@@ -1351,7 +1351,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     NotifyMotionArgs motionArgs =
             generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -1387,29 +1387,29 @@
     window->setFocus(true);
 
     SCOPED_TRACE("Check default value of touch mode");
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
     window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
 
     SCOPED_TRACE("Remove the window to trigger focus loss");
     window->setFocus(false);
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
     window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
 
     SCOPED_TRACE("Disable touch mode");
     mDispatcher->setInTouchMode(false);
     window->setFocus(true);
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
     window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
 
     SCOPED_TRACE("Remove the window to trigger focus loss");
     window->setFocus(false);
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
     window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
 
     SCOPED_TRACE("Enable touch mode again");
     mDispatcher->setInTouchMode(true);
     window->setFocus(true);
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
     window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
 
     window->assertNoEvents();
@@ -1423,7 +1423,7 @@
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
     window->setFocus(true);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
     window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
 
     NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
@@ -1459,7 +1459,7 @@
 
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
 
     NotifyMotionArgs motionArgs =
             generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -1512,7 +1512,7 @@
         mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
         mWindow->setFocus(true);
-        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
+        mDispatcher->setInputWindows({mWindow}, ADISPLAY_ID_DEFAULT);
 
         mWindow->consumeFocusEvent(true);
     }
@@ -1602,7 +1602,7 @@
         // Set focus window for primary display, but focused display would be second one.
         mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
         windowInPrimary->setFocus(true);
-        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
+        mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT);
         windowInPrimary->consumeFocusEvent(true);
 
         application2 = new FakeApplicationHandle();
@@ -1614,7 +1614,7 @@
         // Set focus window for second display.
         mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
         windowInSecondary->setFocus(true);
-        mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
+        mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID);
         windowInSecondary->consumeFocusEvent(true);
     }
 
@@ -1664,7 +1664,7 @@
     windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
 
     // Remove all windows in secondary display.
-    mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
+    mDispatcher->setInputWindows({}, SECOND_DISPLAY_ID);
 
     // Expect old focus should receive a cancel event.
     windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
@@ -1828,7 +1828,7 @@
         mFocusedWindow->setFocus(true);
 
         // Expect one focus window exist in display.
-        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
+        mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
         mFocusedWindow->consumeFocusEvent(true);
     }
 
@@ -1916,7 +1916,7 @@
         mWindow2->setId(1);
         mWindow2->setFrame(Rect(100, 100, 200, 200));
 
-        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
+        mDispatcher->setInputWindows({mWindow1, mWindow2}, ADISPLAY_ID_DEFAULT);
     }
 
 protected:
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index aeffb0e..4c3b3e5 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -183,10 +183,7 @@
 }
 
 ui::Size FramebufferSurface::limitFramebufferSize(uint32_t width, uint32_t height) {
-    // TODO(b/149495759): Use the ui::Size constructor once it no longer is broken.
-    ui::Size framebufferSize;
-    framebufferSize.width = width;
-    framebufferSize.height = height;
+    ui::Size framebufferSize(width, height);
     bool wasLimited = true;
     if (width > mMaxWidth && mMaxWidth != 0) {
         float aspectRatio = float(width) / float(height);
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 5b3cd69..80102bd 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -194,7 +194,7 @@
 
 Increment* SurfaceInterceptor::createTraceIncrementLocked() {
     Increment* increment(mTrace.add_increment());
-    increment->set_time_stamp(systemTime());
+    increment->set_time_stamp(elapsedRealtimeNano());
     return increment;
 }
 
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 20c8d7a..a9c3332 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -129,7 +129,12 @@
 }
 
 status_t SurfaceTracing::writeToFile() {
-    mThread.join();
+    std::thread thread;
+    {
+        std::scoped_lock lock(mTraceLock);
+        thread = std::move(mThread);
+    }
+    thread.join();
     return mLastErr;
 }
 
diff --git a/services/surfaceflinger/tests/AndroidTest.xml b/services/surfaceflinger/tests/AndroidTest.xml
index 8315037..000628f 100644
--- a/services/surfaceflinger/tests/AndroidTest.xml
+++ b/services/surfaceflinger/tests/AndroidTest.xml
@@ -18,6 +18,7 @@
         <option name="cleanup" value="true" />
         <option name="push" value="SurfaceFlinger_test->/data/local/tmp/SurfaceFlinger_test" />
     </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
     <option name="test-suite-tag" value="apct" />
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
diff --git a/vulkan/TEST_MAPPING b/vulkan/TEST_MAPPING
new file mode 100644
index 0000000..d391dce
--- /dev/null
+++ b/vulkan/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsGpuToolsHostTestCases"
+    }
+  ]
+}