Hide Mouse and stylus pointers on mirrored displays

Hide the Mouse and Stylus pointers on mirrored displays if a privacy
sensitive window is present on the source display.

Test: atest PointerChoreographerTest
Bug: 325252005
Change-Id: Idc7a73508e360dfc6fc0bd66c4eb21f497e5bf6b
diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp
index 8a1eed6..02453ef 100644
--- a/services/inputflinger/PointerChoreographer.cpp
+++ b/services/inputflinger/PointerChoreographer.cpp
@@ -89,6 +89,19 @@
     }
 }
 
+// filters and returns a set of privacy sensitive displays that are currently visible.
+std::unordered_set<ui::LogicalDisplayId> getPrivacySensitiveDisplaysFromWindowInfos(
+        const std::vector<gui::WindowInfo>& windowInfos) {
+    std::unordered_set<ui::LogicalDisplayId> privacySensitiveDisplays;
+    for (const auto& windowInfo : windowInfos) {
+        if (!windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_VISIBLE) &&
+            windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::SENSITIVE_FOR_PRIVACY)) {
+            privacySensitiveDisplays.insert(windowInfo.displayId);
+        }
+    }
+    return privacySensitiveDisplays;
+}
+
 } // namespace
 
 // --- PointerChoreographer ---
@@ -246,10 +259,13 @@
     }
 
     // Use a mouse pointer controller for drawing tablets, or create one if it doesn't exist.
-    auto [it, _] = mDrawingTabletPointersByDevice.try_emplace(args.deviceId,
-                                                              getMouseControllerConstructor(
-                                                                      args.displayId));
-    // TODO (b/325252005): Add handing for drawing tablets mouse pointer controller
+    auto [it, controllerAdded] =
+            mDrawingTabletPointersByDevice.try_emplace(args.deviceId,
+                                                       getMouseControllerConstructor(
+                                                               args.displayId));
+    if (controllerAdded) {
+        onControllerAddedOrRemovedLocked();
+    }
 
     PointerControllerInterface& pc = *it->second;
 
@@ -290,7 +306,7 @@
     auto [it, controllerAdded] =
             mTouchPointersByDevice.try_emplace(args.deviceId, mTouchControllerConstructor);
     if (controllerAdded) {
-        onControllerAddedOrRemoved();
+        onControllerAddedOrRemovedLocked();
     }
 
     PointerControllerInterface& pc = *it->second;
@@ -326,10 +342,12 @@
     }
 
     // Get the stylus pointer controller for the device, or create one if it doesn't exist.
-    auto [it, _] =
+    auto [it, controllerAdded] =
             mStylusPointersByDevice.try_emplace(args.deviceId,
                                                 getStylusControllerConstructor(args.displayId));
-    // TODO (b/325252005): Add handing for stylus pointer controller
+    if (controllerAdded) {
+        onControllerAddedOrRemovedLocked();
+    }
 
     PointerControllerInterface& pc = *it->second;
 
@@ -369,15 +387,15 @@
     mTouchPointersByDevice.erase(args.deviceId);
     mStylusPointersByDevice.erase(args.deviceId);
     mDrawingTabletPointersByDevice.erase(args.deviceId);
-    onControllerAddedOrRemoved();
+    onControllerAddedOrRemovedLocked();
 }
 
-void PointerChoreographer::onControllerAddedOrRemoved() {
+void PointerChoreographer::onControllerAddedOrRemovedLocked() {
     if (!HIDE_TOUCH_INDICATORS_FOR_SECURE_WINDOWS) {
         return;
     }
-    bool requireListener = !mTouchPointersByDevice.empty();
-    // TODO (b/325252005): Update for other types of pointer controllers
+    bool requireListener = !mTouchPointersByDevice.empty() || !mMousePointersByDisplay.empty() ||
+            !mDrawingTabletPointersByDevice.empty() || !mStylusPointersByDevice.empty();
 
     if (requireListener && mWindowInfoListener == nullptr) {
         mWindowInfoListener = sp<PointerChoreographerDisplayInfoListener>::make(this);
@@ -387,12 +405,47 @@
         SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener,
                                                                     &initialInfo);
 #endif
-        onWindowInfosChangedLocked(initialInfo.first);
+        mWindowInfoListener->setInitialDisplayInfos(initialInfo.first);
+        onPrivacySensitiveDisplaysChangedLocked(mWindowInfoListener->getPrivacySensitiveDisplays());
     } else if (!requireListener && mWindowInfoListener != nullptr) {
 #if defined(__ANDROID__)
         SurfaceComposerClient::getDefault()->removeWindowInfosListener(mWindowInfoListener);
 #endif
         mWindowInfoListener = nullptr;
+    } else if (requireListener && mWindowInfoListener != nullptr) {
+        // controller may have been added to an existing privacy sensitive display, we need to
+        // update all controllers again
+        onPrivacySensitiveDisplaysChangedLocked(mWindowInfoListener->getPrivacySensitiveDisplays());
+    }
+}
+
+void PointerChoreographer::onPrivacySensitiveDisplaysChangedLocked(
+        const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays) {
+    for (auto& [_, pc] : mTouchPointersByDevice) {
+        pc->clearSkipScreenshotFlags();
+        for (auto displayId : privacySensitiveDisplays) {
+            pc->setSkipScreenshotFlagForDisplay(displayId);
+        }
+    }
+
+    for (auto& [displayId, pc] : mMousePointersByDisplay) {
+        if (privacySensitiveDisplays.find(displayId) != privacySensitiveDisplays.end()) {
+            pc->setSkipScreenshotFlagForDisplay(displayId);
+        } else {
+            pc->clearSkipScreenshotFlags();
+        }
+    }
+
+    for (auto* pointerControllerByDevice :
+         {&mDrawingTabletPointersByDevice, &mStylusPointersByDevice}) {
+        for (auto& [_, pc] : *pointerControllerByDevice) {
+            auto displayId = pc->getDisplayId();
+            if (privacySensitiveDisplays.find(displayId) != privacySensitiveDisplays.end()) {
+                pc->setSkipScreenshotFlagForDisplay(displayId);
+            } else {
+                pc->clearSkipScreenshotFlags();
+            }
+        }
     }
 }
 
@@ -407,10 +460,10 @@
     mNextListener.notify(args);
 }
 
-void PointerChoreographer::onWindowInfosChanged(
-        const std::vector<android::gui::WindowInfo>& windowInfos) {
+void PointerChoreographer::onPrivacySensitiveDisplaysChanged(
+        const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays) {
     std::scoped_lock _l(mLock);
-    onWindowInfosChangedLocked(windowInfos);
+    onPrivacySensitiveDisplaysChangedLocked(privacySensitiveDisplays);
 }
 
 void PointerChoreographer::dump(std::string& dump) {
@@ -467,7 +520,7 @@
     if (it == mMousePointersByDisplay.end()) {
         it = mMousePointersByDisplay.emplace(displayId, getMouseControllerConstructor(displayId))
                      .first;
-        // TODO (b/325252005): Add handing for mouse pointer controller
+        onControllerAddedOrRemovedLocked();
     }
 
     return {displayId, *it->second};
@@ -509,7 +562,9 @@
             auto [mousePointerIt, isNewMousePointer] =
                     mMousePointersByDisplay.try_emplace(displayId,
                                                         getMouseControllerConstructor(displayId));
-            // TODO (b/325252005): Add handing for mouse pointer controller
+            if (isNewMousePointer) {
+                onControllerAddedOrRemovedLocked();
+            }
 
             mMouseDevices.emplace(info.getId());
             if ((!isKnownMouse || isNewMousePointer) && canUnfadeOnDisplay(displayId)) {
@@ -549,7 +604,7 @@
                 mInputDeviceInfos.end();
     });
 
-    onControllerAddedOrRemoved();
+    onControllerAddedOrRemovedLocked();
 
     // Check if we need to notify the policy if there's a change on the pointer display ID.
     return calculatePointerDisplayChangeToNotify();
@@ -715,31 +770,6 @@
     return false;
 }
 
-void PointerChoreographer::onWindowInfosChangedLocked(
-        const std::vector<android::gui::WindowInfo>& windowInfos) {
-    // Mark all spot controllers secure on displays containing secure windows and
-    // remove secure flag from others if required
-    std::unordered_set<ui::LogicalDisplayId> privacySensitiveDisplays;
-    std::unordered_set<ui::LogicalDisplayId> allDisplayIds;
-    for (const auto& windowInfo : windowInfos) {
-        allDisplayIds.insert(windowInfo.displayId);
-        if (!windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_VISIBLE) &&
-            windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::SENSITIVE_FOR_PRIVACY)) {
-            privacySensitiveDisplays.insert(windowInfo.displayId);
-        }
-    }
-
-    for (auto& it : mTouchPointersByDevice) {
-        auto& pc = it.second;
-        for (ui::LogicalDisplayId displayId : allDisplayIds) {
-            pc->setSkipScreenshot(displayId,
-                                  privacySensitiveDisplays.find(displayId) !=
-                                          privacySensitiveDisplays.end());
-        }
-    }
-    // TODO (b/325252005): update skip screenshot flag for other types of pointer controllers
-}
-
 void PointerChoreographer::setPointerIconVisibility(ui::LogicalDisplayId displayId, bool visible) {
     std::scoped_lock lock(mLock);
     if (visible) {
@@ -793,9 +823,27 @@
 void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfosChanged(
         const gui::WindowInfosUpdate& windowInfosUpdate) {
     std::scoped_lock _l(mListenerLock);
-    if (mPointerChoreographer != nullptr) {
-        mPointerChoreographer->onWindowInfosChanged(windowInfosUpdate.windowInfos);
+    if (mPointerChoreographer == nullptr) {
+        return;
     }
+    auto newPrivacySensitiveDisplays =
+            getPrivacySensitiveDisplaysFromWindowInfos(windowInfosUpdate.windowInfos);
+    if (newPrivacySensitiveDisplays != mPrivacySensitiveDisplays) {
+        mPrivacySensitiveDisplays = std::move(newPrivacySensitiveDisplays);
+        mPointerChoreographer->onPrivacySensitiveDisplaysChanged(mPrivacySensitiveDisplays);
+    }
+}
+
+void PointerChoreographer::PointerChoreographerDisplayInfoListener::setInitialDisplayInfos(
+        const std::vector<gui::WindowInfo>& windowInfos) {
+    std::scoped_lock _l(mListenerLock);
+    mPrivacySensitiveDisplays = getPrivacySensitiveDisplaysFromWindowInfos(windowInfos);
+}
+
+std::unordered_set<ui::LogicalDisplayId /*displayId*/>
+PointerChoreographer::PointerChoreographerDisplayInfoListener::getPrivacySensitiveDisplays() {
+    std::scoped_lock _l(mListenerLock);
+    return mPrivacySensitiveDisplays;
 }
 
 void PointerChoreographer::PointerChoreographerDisplayInfoListener::
diff --git a/services/inputflinger/PointerChoreographer.h b/services/inputflinger/PointerChoreographer.h
index 12316c0..11c5a0c 100644
--- a/services/inputflinger/PointerChoreographer.h
+++ b/services/inputflinger/PointerChoreographer.h
@@ -23,6 +23,7 @@
 #include <android-base/thread_annotations.h>
 #include <gui/WindowInfosListener.h>
 #include <type_traits>
+#include <unordered_set>
 
 namespace android {
 
@@ -108,7 +109,8 @@
     void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override;
 
     // Public because it's also used by tests to simulate the WindowInfosListener callback
-    void onWindowInfosChanged(const std::vector<android::gui::WindowInfo>& windowInfos);
+    void onPrivacySensitiveDisplaysChanged(
+            const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays);
 
     void dump(std::string& dump) override;
 
@@ -133,20 +135,32 @@
     void processTouchscreenAndStylusEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
     void processStylusHoverEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
     void processDeviceReset(const NotifyDeviceResetArgs& args);
-    void onControllerAddedOrRemoved() REQUIRES(mLock);
-    void onWindowInfosChangedLocked(const std::vector<android::gui::WindowInfo>& windowInfos)
+    void onControllerAddedOrRemovedLocked() REQUIRES(mLock);
+    void onPrivacySensitiveDisplaysChangedLocked(
+            const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays)
             REQUIRES(mLock);
 
+    /* This listener keeps tracks of visible privacy sensitive displays and updates the
+     * choreographer if there are any changes.
+     *
+     * Listener uses mListenerLock to guard all private data as choreographer and SurfaceComposer
+     * both can call into the listener. To prevent deadlocks Choreographer can call listener with
+     * its lock held, but listener must not call choreographer with its lock.
+     */
     class PointerChoreographerDisplayInfoListener : public gui::WindowInfosListener {
     public:
         explicit PointerChoreographerDisplayInfoListener(PointerChoreographer* pc)
               : mPointerChoreographer(pc){};
         void onWindowInfosChanged(const gui::WindowInfosUpdate&) override;
+        void setInitialDisplayInfos(const std::vector<gui::WindowInfo>& windowInfos);
+        std::unordered_set<ui::LogicalDisplayId /*displayId*/> getPrivacySensitiveDisplays();
         void onPointerChoreographerDestroyed();
 
     private:
         std::mutex mListenerLock;
         PointerChoreographer* mPointerChoreographer GUARDED_BY(mListenerLock);
+        std::unordered_set<ui::LogicalDisplayId /*displayId*/> mPrivacySensitiveDisplays
+                GUARDED_BY(mListenerLock);
     };
     sp<PointerChoreographerDisplayInfoListener> mWindowInfoListener GUARDED_BY(mLock);
 
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index cee44fc..e34ed0f 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -142,10 +142,13 @@
     /* Sets the custom pointer icon for mice or styluses. */
     virtual void setCustomPointerIcon(const SpriteIcon& icon) = 0;
 
-    /* Sets the flag to skip screenshot of the pointer indicators on the display matching the
-     * provided displayId.
+    /* Sets the flag to skip screenshot of the pointer indicators on the display for the specified
+     * displayId. This flag can only be reset with resetSkipScreenshotFlags()
      */
-    virtual void setSkipScreenshot(ui::LogicalDisplayId displayId, bool skip) = 0;
+    virtual void setSkipScreenshotFlagForDisplay(ui::LogicalDisplayId displayId) = 0;
+
+    /* Resets the flag to skip screenshot of the pointer indicators for all displays. */
+    virtual void clearSkipScreenshotFlags() = 0;
 };
 
 } // namespace android
diff --git a/services/inputflinger/tests/FakePointerController.cpp b/services/inputflinger/tests/FakePointerController.cpp
index 2bb57b3..456013e 100644
--- a/services/inputflinger/tests/FakePointerController.cpp
+++ b/services/inputflinger/tests/FakePointerController.cpp
@@ -76,13 +76,13 @@
     mCustomIconStyle = icon.style;
 }
 
-void FakePointerController::setSkipScreenshot(ui::LogicalDisplayId displayId, bool skip) {
-    if (skip) {
-        mDisplaysToSkipScreenshot.insert(displayId);
-    } else {
-        mDisplaysToSkipScreenshot.erase(displayId);
-    }
-};
+void FakePointerController::setSkipScreenshotFlagForDisplay(ui::LogicalDisplayId displayId) {
+    mDisplaysToSkipScreenshot.insert(displayId);
+}
+
+void FakePointerController::clearSkipScreenshotFlags() {
+    mDisplaysToSkipScreenshot.clear();
+}
 
 void FakePointerController::assertViewportSet(ui::LogicalDisplayId displayId) {
     ASSERT_TRUE(mDisplayId);
diff --git a/services/inputflinger/tests/FakePointerController.h b/services/inputflinger/tests/FakePointerController.h
index 5bc713f..8d95f65 100644
--- a/services/inputflinger/tests/FakePointerController.h
+++ b/services/inputflinger/tests/FakePointerController.h
@@ -45,7 +45,8 @@
     void setDisplayViewport(const DisplayViewport& viewport) override;
     void updatePointerIcon(PointerIconStyle iconId) override;
     void setCustomPointerIcon(const SpriteIcon& icon) override;
-    void setSkipScreenshot(ui::LogicalDisplayId displayId, bool skip) override;
+    void setSkipScreenshotFlagForDisplay(ui::LogicalDisplayId displayId) override;
+    void clearSkipScreenshotFlags() override;
     void fade(Transition) override;
 
     void assertViewportSet(ui::LogicalDisplayId displayId);
diff --git a/services/inputflinger/tests/PointerChoreographer_test.cpp b/services/inputflinger/tests/PointerChoreographer_test.cpp
index 1689b33..69a7382 100644
--- a/services/inputflinger/tests/PointerChoreographer_test.cpp
+++ b/services/inputflinger/tests/PointerChoreographer_test.cpp
@@ -1636,72 +1636,69 @@
     firstMousePc->assertPointerIconNotSet();
 }
 
-TEST_F_WITH_FLAGS(PointerChoreographerTest, HidesTouchSpotsOnMirroredDisplaysForSecureWindow,
-                  REQUIRES_FLAGS_ENABLED(
-                          ACONFIG_FLAG(input_flags, hide_pointer_indicators_for_secure_windows))) {
-    // Add a touch device and enable show touches.
+using HidePointerForPrivacySensitiveDisplaysFixtureParam =
+        std::tuple<std::string_view /*name*/, uint32_t /*source*/, ControllerType, PointerBuilder,
+                   std::function<void(PointerChoreographer&)>, int32_t /*action*/>;
+
+class HidePointerForPrivacySensitiveDisplaysTestFixture
+      : public PointerChoreographerTest,
+        public ::testing::WithParamInterface<HidePointerForPrivacySensitiveDisplaysFixtureParam> {};
+
+INSTANTIATE_TEST_SUITE_P(
+        PointerChoreographerTest, HidePointerForPrivacySensitiveDisplaysTestFixture,
+        ::testing::Values(
+                std::make_tuple(
+                        "TouchSpots", AINPUT_SOURCE_TOUCHSCREEN, ControllerType::TOUCH,
+                        FIRST_TOUCH_POINTER,
+                        [](PointerChoreographer& pc) { pc.setShowTouchesEnabled(true); },
+                        AMOTION_EVENT_ACTION_DOWN),
+                std::make_tuple(
+                        "Mouse", AINPUT_SOURCE_MOUSE, ControllerType::MOUSE, MOUSE_POINTER,
+                        [](PointerChoreographer& pc) {}, AMOTION_EVENT_ACTION_DOWN),
+                std::make_tuple(
+                        "Stylus", AINPUT_SOURCE_STYLUS, ControllerType::STYLUS, STYLUS_POINTER,
+                        [](PointerChoreographer& pc) { pc.setStylusPointerIconEnabled(true); },
+                        AMOTION_EVENT_ACTION_HOVER_ENTER),
+                std::make_tuple(
+                        "DrawingTablet", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS,
+                        ControllerType::MOUSE, STYLUS_POINTER, [](PointerChoreographer& pc) {},
+                        AMOTION_EVENT_ACTION_HOVER_ENTER)),
+        [](const testing::TestParamInfo<HidePointerForPrivacySensitiveDisplaysFixtureParam>& p) {
+            return std::string{std::get<0>(p.param)};
+        });
+
+TEST_P(HidePointerForPrivacySensitiveDisplaysTestFixture,
+       HidesPointerOnMirroredDisplaysForPrivacySensitiveDisplay) {
+    const auto& [name, source, controllerType, pointerBuilder, onControllerInit, action] =
+            GetParam();
+    input_flags::hide_pointer_indicators_for_secure_windows(true);
+    mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID}));
+
+    // Add appropriate pointer device
     mChoreographer.notifyInputDevicesChanged(
-            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID)}});
-    mChoreographer.setShowTouchesEnabled(true);
+            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, source, DISPLAY_ID)}});
+    onControllerInit(mChoreographer);
 
-    // Emit touch events to create PointerController
-    mChoreographer.notifyMotion(
-            MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
-                    .pointer(FIRST_TOUCH_POINTER)
-                    .deviceId(DEVICE_ID)
-                    .displayId(DISPLAY_ID)
-                    .build());
+    // Emit input events to create PointerController
+    mChoreographer.notifyMotion(MotionArgsBuilder(action, source)
+                                        .pointer(pointerBuilder)
+                                        .deviceId(DEVICE_ID)
+                                        .displayId(DISPLAY_ID)
+                                        .build());
 
-    // By default touch indicators should not be hidden
-    auto pc = assertPointerControllerCreated(ControllerType::TOUCH);
+    // By default pointer indicators should not be hidden
+    auto pc = assertPointerControllerCreated(controllerType);
     pc->assertIsHiddenOnMirroredDisplays(DISPLAY_ID, /*isHidden=*/false);
     pc->assertIsHiddenOnMirroredDisplays(ANOTHER_DISPLAY_ID, /*isHidden=*/false);
 
-    // adding secure window on display should set flag to hide pointer indicators on corresponding
-    // mirrored display
-    gui::WindowInfo windowInfo;
-    windowInfo.displayId = DISPLAY_ID;
-    windowInfo.inputConfig |= gui::WindowInfo::InputConfig::SENSITIVE_FOR_PRIVACY;
-    mChoreographer.onWindowInfosChanged({windowInfo});
+    // marking a display privacy sensitive should set flag to hide pointer indicators on the
+    // corresponding mirrored display
+    mChoreographer.onPrivacySensitiveDisplaysChanged(/*privacySensitiveDisplays=*/{DISPLAY_ID});
     pc->assertIsHiddenOnMirroredDisplays(DISPLAY_ID, /*isHidden=*/true);
     pc->assertIsHiddenOnMirroredDisplays(ANOTHER_DISPLAY_ID, /*isHidden=*/false);
 
-    // removing the secure window should reset the state
-    windowInfo.inputConfig.clear(gui::WindowInfo::InputConfig::SENSITIVE_FOR_PRIVACY);
-    mChoreographer.onWindowInfosChanged({windowInfo});
-    pc->assertIsHiddenOnMirroredDisplays(DISPLAY_ID, /*isHidden=*/false);
-    pc->assertIsHiddenOnMirroredDisplays(ANOTHER_DISPLAY_ID, /*isHidden=*/false);
-}
-
-TEST_F_WITH_FLAGS(PointerChoreographerTest,
-                  DoesNotHidesTouchSpotsOnMirroredDisplaysForInvisibleWindow,
-                  REQUIRES_FLAGS_ENABLED(
-                          ACONFIG_FLAG(input_flags, hide_pointer_indicators_for_secure_windows))) {
-    // Add a touch device and enable show touches.
-    mChoreographer.notifyInputDevicesChanged(
-            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID)}});
-    mChoreographer.setShowTouchesEnabled(true);
-
-    // Emit touch events to create PointerController
-    mChoreographer.notifyMotion(
-            MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
-                    .pointer(FIRST_TOUCH_POINTER)
-                    .deviceId(DEVICE_ID)
-                    .displayId(DISPLAY_ID)
-                    .build());
-
-    // By default touch indicators should not be hidden
-    auto pc = assertPointerControllerCreated(ControllerType::TOUCH);
-    pc->assertIsHiddenOnMirroredDisplays(DISPLAY_ID, /*isHidden=*/false);
-    pc->assertIsHiddenOnMirroredDisplays(ANOTHER_DISPLAY_ID, /*isHidden=*/false);
-
-    // adding secure but hidden window on display should still not set flag to hide pointer
-    // indicators
-    gui::WindowInfo windowInfo;
-    windowInfo.displayId = DISPLAY_ID;
-    windowInfo.inputConfig |= gui::WindowInfo::InputConfig::SENSITIVE_FOR_PRIVACY;
-    windowInfo.inputConfig |= gui::WindowInfo::InputConfig::NOT_VISIBLE;
-    mChoreographer.onWindowInfosChanged({windowInfo});
+    // un-marking the privacy sensitive display should reset the state
+    mChoreographer.onPrivacySensitiveDisplaysChanged(/*privacySensitiveDisplays=*/{});
     pc->assertIsHiddenOnMirroredDisplays(DISPLAY_ID, /*isHidden=*/false);
     pc->assertIsHiddenOnMirroredDisplays(ANOTHER_DISPLAY_ID, /*isHidden=*/false);
 }