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);
}