Merge "BLASTBufferQueue: Initialize transform hint on creation." into rvc-dev
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index fc771a2..e68946d 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -111,8 +111,10 @@
         handlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
         handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info));
     }
-    for (auto const& i : handlesPerDisplay) {
-        mDispatcher->setInputWindows(i.second, i.first, setInputWindowsListener);
+    mDispatcher->setInputWindows(handlesPerDisplay);
+
+    if (setInputWindowsListener) {
+        setInputWindowsListener->onSetInputWindowsFinished();
     }
 }
 
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index 3b18813..7c5c9c5 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({window}, ADISPLAY_ID_DEFAULT);
+    dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     NotifyMotionArgs motionArgs = generateMotionArgs();
 
@@ -288,7 +288,7 @@
     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
     sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
 
-    dispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     for (auto _ : state) {
         MotionEvent event = generateMotionEvent();
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 308d19b..4ec61b0 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3621,6 +3621,18 @@
     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,...
@@ -3628,9 +3640,8 @@
  * 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::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
-                                      int32_t displayId,
-                                      const sp<ISetInputWindowsListener>& setInputWindowsListener) {
+void InputDispatcher::setInputWindowsLocked(
+        const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
     if (DEBUG_FOCUS) {
         std::string windowList;
         for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
@@ -3638,109 +3649,97 @@
         }
         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;
+    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);
             }
-            if (windowHandle == mLastHoverWindowHandle) {
-                foundHoveredWindow = true;
+            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*/);
             }
+            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 (!foundHoveredWindow) {
-            mLastHoverWindowHandle = nullptr;
+        if (mFocusedDisplayId == displayId) {
+            onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
         }
+    }
 
-        sp<InputWindowHandle> oldFocusedWindowHandle =
-                getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
-
-        if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
-            if (oldFocusedWindowHandle != 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)) {
                 if (DEBUG_FOCUS) {
-                    ALOGD("Focus left window: %s in display %" PRId32,
-                          oldFocusedWindowHandle->getName().c_str(), displayId);
+                    ALOGD("Touched window was removed: %s in display %" PRId32,
+                          touchedWindow.windowHandle->getName().c_str(), displayId);
                 }
-                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*/);
+                sp<InputChannel> touchedInputChannel =
+                        getInputChannelLocked(touchedWindow.windowHandle->getToken());
+                if (touchedInputChannel != nullptr) {
+                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+                                               "touched window was removed");
+                    synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
                 }
-                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);
+                state.windows.erase(state.windows.begin() + i);
+            } else {
+                ++i;
             }
         }
+    }
 
-        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 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 4aa47f8..cbba7e1 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::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId,
-            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) override;
+            const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
+                    handlesPerDisplay) override;
     virtual void setFocusedApplication(
             int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) override;
     virtual void setFocusedDisplay(int32_t displayId) override;
@@ -278,6 +278,8 @@
 
     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 6e98676..09dc92c 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -19,6 +19,7 @@
 
 #include <InputListener.h>
 #include <input/ISetInputWindowsListener.h>
+#include <unordered_map>
 
 namespace android {
 
@@ -99,13 +100,13 @@
      */
     virtual std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) = 0;
 
-    /* Sets the list of input windows.
+    /* Sets the list of input windows per display.
      *
      * This method may be called on any thread (usually by the input manager).
      */
     virtual void setInputWindows(
-            const std::vector<sp<InputWindowHandle> >& inputWindowHandles, int32_t displayId,
-            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) = 0;
+            const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
+                    handlesPerDisplay) = 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 1f283b1..29f3dac 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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     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({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
     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({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
 
     windowSecond->consumeFocusEvent(true);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
@@ -935,7 +935,7 @@
     windowTop->setFocus(true);
     windowSecond->setFocus(true);
 
-    mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
     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({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
     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({windowLeft, windowRight}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
 
     // 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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     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({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
 
     // 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({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
 
     // 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({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
 
     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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     window->consumeFocusEvent(true);
 
@@ -1220,7 +1220,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     // 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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
 
     SCOPED_TRACE("Remove the window to trigger focus loss");
     window->setFocus(false);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
 
     SCOPED_TRACE("Disable touch mode");
     mDispatcher->setInTouchMode(false);
     window->setFocus(true);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
 
     SCOPED_TRACE("Remove the window to trigger focus loss");
     window->setFocus(false);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
 
     SCOPED_TRACE("Enable touch mode again");
     mDispatcher->setInTouchMode(true);
     window->setFocus(true);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
 
     window->assertNoEvents();
@@ -1423,7 +1423,7 @@
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
     window->setFocus(true);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     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({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     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({mWindow}, ADISPLAY_ID_DEFAULT);
+        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
 
         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({windowInPrimary}, ADISPLAY_ID_DEFAULT);
+        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
         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({windowInSecondary}, SECOND_DISPLAY_ID);
+        mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
         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({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
+        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
         mFocusedWindow->consumeFocusEvent(true);
     }
 
@@ -1916,7 +1916,7 @@
         mWindow2->setId(1);
         mWindow2->setFrame(Rect(100, 100, 200, 200));
 
-        mDispatcher->setInputWindows({mWindow1, mWindow2}, ADISPLAY_ID_DEFAULT);
+        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
     }
 
 protected:
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 9a13c00..77d8c11 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <cinttypes>
 #include <sys/socket.h>
 #include <utils/threads.h>
 
@@ -69,17 +70,17 @@
 }
 
 bool SensorService::SensorEventConnection::needsWakeLock() {
-    Mutex::Autolock _l(mConnectionLock);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
     return !mDead && mWakeLockRefCount > 0;
 }
 
 void SensorService::SensorEventConnection::resetWakeLockRefCount() {
-    Mutex::Autolock _l(mConnectionLock);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
     mWakeLockRefCount = 0;
 }
 
 void SensorService::SensorEventConnection::dump(String8& result) {
-    Mutex::Autolock _l(mConnectionLock);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
     result.appendFormat("\tOperating Mode: ");
     if (!mService->isWhiteListedPackage(getPackageName())) {
         result.append("RESTRICTED\n");
@@ -91,11 +92,11 @@
     result.appendFormat("\t %s | WakeLockRefCount %d | uid %d | cache size %d | "
             "max cache size %d\n", mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize,
             mMaxCacheSize);
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
+    for (auto& it : mSensorInfo) {
+        const FlushInfo& flushInfo = it.second.flushInfo;
         result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
-                            mService->getSensorName(mSensorInfo.keyAt(i)).string(),
-                            mSensorInfo.keyAt(i),
+                            mService->getSensorName(it.first).string(),
+                            it.first,
                             flushInfo.mFirstFlushPending ? "First flush pending" :
                                                            "active",
                             flushInfo.mPendingFlushEventsToSend);
@@ -121,7 +122,7 @@
  */
 void SensorService::SensorEventConnection::dump(util::ProtoOutputStream* proto) const {
     using namespace service::SensorEventConnectionProto;
-    Mutex::Autolock _l(mConnectionLock);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
 
     if (!mService->isWhiteListedPackage(getPackageName())) {
         proto->write(OPERATING_MODE, OP_MODE_RESTRICTED);
@@ -135,12 +136,12 @@
     proto->write(UID, int32_t(mUid));
     proto->write(CACHE_SIZE, int32_t(mCacheSize));
     proto->write(MAX_CACHE_SIZE, int32_t(mMaxCacheSize));
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
+    for (auto& it : mSensorInfo) {
+        const FlushInfo& flushInfo = it.second.flushInfo;
         const uint64_t token = proto->start(FLUSH_INFOS);
         proto->write(FlushInfoProto::SENSOR_NAME,
-                std::string(mService->getSensorName(mSensorInfo.keyAt(i))));
-        proto->write(FlushInfoProto::SENSOR_HANDLE, mSensorInfo.keyAt(i));
+                std::string(mService->getSensorName(it.first)));
+        proto->write(FlushInfoProto::SENSOR_HANDLE, it.first);
         proto->write(FlushInfoProto::FIRST_FLUSH_PENDING, flushInfo.mFirstFlushPending);
         proto->write(FlushInfoProto::PENDING_FLUSH_EVENTS_TO_SEND,
                 flushInfo.mPendingFlushEventsToSend);
@@ -157,40 +158,54 @@
 #endif
 }
 
-bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
-    Mutex::Autolock _l(mConnectionLock);
+bool SensorService::SensorEventConnection::addSensor(
+    int32_t handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags) {
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
     sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
     if (si == nullptr ||
         !canAccessSensor(si->getSensor(), "Tried adding", mOpPackageName) ||
-        mSensorInfo.indexOfKey(handle) >= 0) {
+        mSensorInfo.count(handle) > 0) {
         return false;
     }
-    mSensorInfo.add(handle, FlushInfo());
+
+    SensorRequest request = {
+      .samplingPeriodNs = samplingPeriodNs,
+      .maxBatchReportLatencyNs = maxBatchReportLatencyNs,
+      .reservedFlags = reservedFlags
+    };
+
+    mSensorInfo[handle] = request;
     return true;
 }
 
 bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
-    Mutex::Autolock _l(mConnectionLock);
-    if (mSensorInfo.removeItem(handle) >= 0) {
-        return true;
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    return mSensorInfo.erase(handle) > 0;
+}
+
+std::vector<int32_t> SensorService::SensorEventConnection::getActiveSensorHandles() const {
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    std::vector<int32_t> list;
+    for (auto& it : mSensorInfo) {
+        list.push_back(it.first);
     }
-    return false;
+    return list;
 }
 
 bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
-    Mutex::Autolock _l(mConnectionLock);
-    return mSensorInfo.indexOfKey(handle) >= 0;
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    return mSensorInfo.count(handle) + mSensorInfoBackup.count(handle) > 0;
 }
 
 bool SensorService::SensorEventConnection::hasAnySensor() const {
-    Mutex::Autolock _l(mConnectionLock);
-    return mSensorInfo.size() ? true : false;
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    return mSensorInfo.size() + mSensorInfoBackup.size() ? true : false;
 }
 
 bool SensorService::SensorEventConnection::hasOneShotSensors() const {
-    Mutex::Autolock _l(mConnectionLock);
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const int handle = mSensorInfo.keyAt(i);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    for (auto &it : mSensorInfo) {
+        const int handle = it.first;
         sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si != nullptr && si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
             return true;
@@ -205,16 +220,15 @@
 
 void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
                                 bool value) {
-    Mutex::Autolock _l(mConnectionLock);
-    ssize_t index = mSensorInfo.indexOfKey(handle);
-    if (index >= 0) {
-        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    if (mSensorInfo.count(handle) > 0) {
+        FlushInfo& flushInfo = mSensorInfo[handle].flushInfo;
         flushInfo.mFirstFlushPending = value;
     }
 }
 
 void SensorService::SensorEventConnection::updateLooperRegistration(const sp<Looper>& looper) {
-    Mutex::Autolock _l(mConnectionLock);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
     updateLooperRegistrationLocked(looper);
 }
 
@@ -233,8 +247,8 @@
     int looper_flags = 0;
     if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
     if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const int handle = mSensorInfo.keyAt(i);
+    for (auto& it : mSensorInfo) {
+        const int handle = it.first;
         sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si != nullptr && si->getSensor().isWakeUpSensor()) {
             looper_flags |= ALOOPER_EVENT_INPUT;
@@ -265,10 +279,9 @@
 }
 
 void SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
-    Mutex::Autolock _l(mConnectionLock);
-    ssize_t index = mSensorInfo.indexOfKey(handle);
-    if (index >= 0) {
-        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    if (mSensorInfo.count(handle) > 0) {
+        FlushInfo& flushInfo = mSensorInfo[handle].flushInfo;
         flushInfo.mPendingFlushEventsToSend++;
     }
 }
@@ -282,7 +295,7 @@
     std::unique_ptr<sensors_event_t[]> sanitizedBuffer;
 
     int count = 0;
-    Mutex::Autolock _l(mConnectionLock);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
     if (scratch) {
         size_t i=0;
         while (i<numEvents) {
@@ -296,15 +309,14 @@
                 sensor_handle = buffer[i].meta_data.sensor;
             }
 
-            ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
             // Check if this connection has registered for this sensor. If not continue to the
             // next sensor_event.
-            if (index < 0) {
+            if (mSensorInfo.count(sensor_handle) == 0) {
                 ++i;
                 continue;
             }
 
-            FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+            FlushInfo& flushInfo = mSensorInfo[sensor_handle].flushInfo;
             // Check if there is a pending flush_complete event for this sensor on this connection.
             if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
                     mapFlushEventsToConnections[i] == this) {
@@ -425,9 +437,55 @@
     return size < 0 ? status_t(size) : status_t(NO_ERROR);
 }
 
+void SensorService::SensorEventConnection::updateSensorSubscriptions() {
+    if (!hasSensorAccess()) {
+        stopAll();
+    } else {
+        recoverAll();
+    }
+}
+
 void SensorService::SensorEventConnection::setSensorAccess(const bool hasAccess) {
-    Mutex::Autolock _l(mConnectionLock);
-    mHasSensorAccess = hasAccess;
+    if (mHasSensorAccess != hasAccess) {
+        mHasSensorAccess = hasAccess;
+        updateSensorSubscriptions();
+    }
+}
+
+void SensorService::SensorEventConnection::stopAll() {
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    if (!mSensorInfo.empty()) {
+        mSensorInfoBackup = mSensorInfo;
+        mSensorInfo.clear();
+
+        for (auto& it : mSensorInfoBackup) {
+            int32_t handle = it.first;
+
+            status_t err =  mService->disable(this, handle);
+
+            if (err != NO_ERROR) {
+                ALOGE("Error disabling sensor %d", handle);
+            }
+        }
+    }
+}
+
+void SensorService::SensorEventConnection::recoverAll() {
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    for (auto& it : mSensorInfoBackup) {
+        int32_t handle = it.first;
+        SensorRequest &request = it.second;
+
+        status_t err =  mService->enable(
+            this, handle, request.samplingPeriodNs, request.maxBatchReportLatencyNs,
+            request.reservedFlags, mOpPackageName);
+
+        if (err != NO_ERROR) {
+            ALOGE("Error recovering sensor %d", handle);
+        }
+    }
+
+    mSensorInfoBackup.clear();
 }
 
 bool SensorService::SensorEventConnection::hasSensorAccess() {
@@ -522,14 +580,14 @@
     flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
     // Loop through all the sensors for this connection and check if there are any pending
     // flush complete events to be sent.
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const int handle = mSensorInfo.keyAt(i);
+    for (auto& it : mSensorInfo) {
+        const int handle = it.first;
         sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si == nullptr) {
             continue;
         }
 
-        FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
+        FlushInfo& flushInfo = it.second.flushInfo;
         while (flushInfo.mPendingFlushEventsToSend > 0) {
             flushCompleteEvent.meta_data.sensor = handle;
             bool wakeUpSensor = si->getSensor().isWakeUpSensor();
@@ -554,7 +612,7 @@
     // half the size of the socket buffer allocated in BitTube whichever is smaller.
     const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
             int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
-    Mutex::Autolock _l(mConnectionLock);
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
     // Send pending flush complete events (if any)
     sendPendingFlushEventsLocked();
     for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
@@ -615,14 +673,13 @@
     // separately before the next batch of events.
     for (int j = 0; j < numEventsDropped; ++j) {
         if (scratch[j].type == SENSOR_TYPE_META_DATA) {
-            ssize_t index = mSensorInfo.indexOfKey(scratch[j].meta_data.sensor);
-            if (index < 0) {
+            if (mSensorInfo.count(scratch[j].meta_data.sensor) == 0) {
                 ALOGW("%s: sensor 0x%x is not found in connection",
                       __func__, scratch[j].meta_data.sensor);
                 continue;
             }
 
-            FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+            FlushInfo& flushInfo = mSensorInfo[scratch[j].meta_data.sensor].flushInfo;
             flushInfo.mPendingFlushEventsToSend++;
             ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
                      flushInfo.mPendingFlushEventsToSend);
@@ -658,13 +715,21 @@
     } else {
         err = mService->disable(this, handle);
     }
+
     return err;
 }
 
 status_t SensorService::SensorEventConnection::setEventRate(
         int handle, nsecs_t samplingPeriodNs)
 {
-    return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
+    status_t err = mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
+
+    std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+    if (err == NO_ERROR && mSensorInfo.count(handle) > 0) {
+        mSensorInfo[handle].samplingPeriodNs = samplingPeriodNs;
+    }
+
+    return err;
 }
 
 status_t  SensorService::SensorEventConnection::flush() {
@@ -685,7 +750,7 @@
             // and remove the fd from Looper. Call checkWakeLockState to know if SensorService
             // can release the wake-lock.
             ALOGD_IF(DEBUG_CONNECTIONS, "%p Looper error %d", this, fd);
-            Mutex::Autolock _l(mConnectionLock);
+            std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
             mDead = true;
             mWakeLockRefCount = 0;
             updateLooperRegistrationLocked(mService->getLooper());
@@ -704,7 +769,7 @@
         unsigned char buf[sizeof(sensors_event_t)];
         ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
         {
-            Mutex::Autolock _l(mConnectionLock);
+            std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
             if (numBytesRead == sizeof(sensors_event_t)) {
                 if (!mDataInjectionMode) {
                     ALOGE("Data injected in normal mode, dropping event"
@@ -764,8 +829,8 @@
 int SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const {
     size_t fifoWakeUpSensors = 0;
     size_t fifoNonWakeUpSensors = 0;
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(mSensorInfo.keyAt(i));
+    for (auto& it : mSensorInfo) {
+        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(it.first);
         if (si == nullptr) {
             continue;
         }
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index caf5d7c..3ba5c07 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -23,7 +23,6 @@
 
 #include <utils/Vector.h>
 #include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
 #include <utils/threads.h>
 #include <utils/AndroidThreads.h>
 #include <utils/RefBase.h>
@@ -58,8 +57,10 @@
     bool hasSensor(int32_t handle) const;
     bool hasAnySensor() const;
     bool hasOneShotSensors() const;
-    bool addSensor(int32_t handle);
+    bool addSensor(
+        int32_t handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags);
     bool removeSensor(int32_t handle);
+    std::vector<int32_t> getActiveSensorHandles() const;
     void setFirstFlushPending(int32_t handle, bool value);
     void dump(String8& result);
     void dump(util::ProtoOutputStream* proto) const;
@@ -70,7 +71,7 @@
     uid_t getUid() const { return mUid; }
 
     void setSensorAccess(const bool hasAccess);
-
+    void updateSensorSubscriptions();
 private:
     virtual ~SensorEventConnection();
     virtual void onFirstRef();
@@ -136,13 +137,16 @@
     // privacy not being enabled.
     bool hasSensorAccess();
 
+    void stopAll();
+    void recoverAll();
+
     // Call noteOp for the sensor if the sensor requires a permission
     bool noteOpIfRequired(const sensors_event_t& event);
 
     sp<SensorService> const mService;
     sp<BitTube> mChannel;
     uid_t mUid;
-    mutable Mutex mConnectionLock;
+    mutable std::recursive_mutex mConnectionLock;
     // Number of events from wake up sensors which are still pending and haven't been delivered to
     // the corresponding application. It is incremented by one unit for each write to the socket.
     uint32_t mWakeLockRefCount;
@@ -169,8 +173,17 @@
 
         FlushInfo() : mPendingFlushEventsToSend(0), mFirstFlushPending(false) {}
     };
-    // protected by SensorService::mLock. Key for this vector is the sensor handle.
-    KeyedVector<int, FlushInfo> mSensorInfo;
+
+    struct SensorRequest {
+      nsecs_t samplingPeriodNs;
+      nsecs_t maxBatchReportLatencyNs;
+      int reservedFlags;
+      FlushInfo flushInfo;
+    };
+
+    // protected by SensorService::mLock. Key for this map is the sensor handle.
+    std::unordered_map<int32_t, SensorRequest> mSensorInfo;
+    std::unordered_map<int32_t, SensorRequest> mSensorInfoBackup;
 
     sensors_event_t *mEventCache;
     int mCacheSize, mMaxCacheSize;
@@ -185,7 +198,7 @@
 
     mutable Mutex mDestroyLock;
     bool mDestroyed;
-    bool mHasSensorAccess;
+    std::atomic_bool mHasSensorAccess;
 
     // Store a mapping of sensor handles to required AppOp for a sensor. This map only contains a
     // valid mapping for sensors that require a permission in order to reduce the lookup time.
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 22a15c6..5ae7c51 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -301,7 +301,10 @@
 
 void SensorService::setSensorAccess(uid_t uid, bool hasAccess) {
     ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
-    for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) {
+    const auto& connections = connLock.getActiveConnections();
+
+    mLock.unlock();
+    for (const sp<SensorEventConnection>& conn : connections) {
         if (conn->getUid() == uid) {
             conn->setSensorAccess(hasAccess);
         }
@@ -638,6 +641,9 @@
 
 void SensorService::disableAllSensorsLocked(ConnectionSafeAutolock* connLock) {
     SensorDevice& dev(SensorDevice::getInstance());
+    for (const sp<SensorEventConnection>& connection : connLock->getActiveConnections()) {
+        connection->updateSensorSubscriptions();
+    }
     for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) {
         connection->stopAll(true /* backupRecord */);
     }
@@ -666,6 +672,9 @@
     }
     SensorDevice& dev(SensorDevice::getInstance());
     dev.enableAllSensors();
+    for (const sp<SensorEventConnection>& connection : connLock->getActiveConnections()) {
+        connection->updateSensorSubscriptions();
+    }
     for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) {
         connection->recoverAll();
     }
@@ -1589,7 +1598,7 @@
         }
     }
 
-    if (connection->addSensor(handle)) {
+    if (connection->addSensor(handle, samplingPeriodNs, maxBatchReportLatencyNs, reservedFlags)) {
         BatteryService::enableSensor(connection->getUid(), handle);
         // the sensor was added (which means it wasn't already there)
         // so, see if this connection becomes active
@@ -1739,18 +1748,22 @@
     const int halVersion = dev.getHalDeviceVersion();
     status_t err(NO_ERROR);
     Mutex::Autolock _l(mLock);
+
+    size_t numSensors = 0;
     // Loop through all sensors for this connection and call flush on each of them.
-    for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) {
-        const int handle = connection->mSensorInfo.keyAt(i);
+    for (int handle : connection->getActiveSensorHandles()) {
         sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
         if (sensor == nullptr) {
             continue;
         }
+        numSensors++;
+
         if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
             ALOGE("flush called on a one-shot sensor");
             err = INVALID_OPERATION;
             continue;
         }
+
         if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
             // For older devices just increment pending flush count which will send a trivial
             // flush complete event.
@@ -1768,7 +1781,8 @@
             err = (err_flush != NO_ERROR) ? err_flush : err;
         }
     }
-    return err;
+
+    return (numSensors == 0) ? INVALID_OPERATION : err;
 }
 
 bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,