Loading services/inputflinger/PointerChoreographer.cpp +31 −17 Original line number Diff line number Diff line Loading @@ -30,10 +30,6 @@ namespace android { namespace input_flags = com::android::input::flags; static const bool HIDE_TOUCH_INDICATORS_FOR_SECURE_WINDOWS = input_flags::hide_pointer_indicators_for_secure_windows(); namespace { bool isFromMouse(const NotifyMotionArgs& args) { Loading Loading @@ -106,8 +102,31 @@ std::unordered_set<ui::LogicalDisplayId> getPrivacySensitiveDisplaysFromWindowIn // --- PointerChoreographer --- PointerChoreographer::PointerChoreographer(InputListenerInterface& listener, PointerChoreographer::PointerChoreographer(InputListenerInterface& inputListener, PointerChoreographerPolicyInterface& policy) : PointerChoreographer( inputListener, policy, [](const sp<android::gui::WindowInfosListener>& listener) { auto initialInfo = std::make_pair(std::vector<android::gui::WindowInfo>{}, std::vector<android::gui::DisplayInfo>{}); #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->addWindowInfosListener(listener, &initialInfo); #endif return initialInfo.first; }, [](const sp<android::gui::WindowInfosListener>& listener) { #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->removeWindowInfosListener(listener); #endif }) { } PointerChoreographer::PointerChoreographer( android::InputListenerInterface& listener, android::PointerChoreographerPolicyInterface& policy, const android::PointerChoreographer::WindowListenerRegisterConsumer& registerListener, const android::PointerChoreographer::WindowListenerUnregisterConsumer& unregisterListener) : mTouchControllerConstructor([this]() { return mPolicy.createPointerController( PointerControllerInterface::ControllerType::TOUCH); Loading @@ -117,7 +136,9 @@ PointerChoreographer::PointerChoreographer(InputListenerInterface& listener, mDefaultMouseDisplayId(ui::LogicalDisplayId::DEFAULT), mNotifiedPointerDisplayId(ui::LogicalDisplayId::INVALID), mShowTouchesEnabled(false), mStylusPointerIconEnabled(false) {} mStylusPointerIconEnabled(false), mRegisterListener(registerListener), mUnregisterListener(unregisterListener) {} PointerChoreographer::~PointerChoreographer() { std::scoped_lock _l(mLock); Loading @@ -125,6 +146,7 @@ PointerChoreographer::~PointerChoreographer() { return; } mWindowInfoListener->onPointerChoreographerDestroyed(); mUnregisterListener(mWindowInfoListener); } void PointerChoreographer::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) { Loading Loading @@ -391,7 +413,7 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args) } void PointerChoreographer::onControllerAddedOrRemovedLocked() { if (!HIDE_TOUCH_INDICATORS_FOR_SECURE_WINDOWS) { if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows()) { return; } bool requireListener = !mTouchPointersByDevice.empty() || !mMousePointersByDisplay.empty() || Loading @@ -399,18 +421,10 @@ void PointerChoreographer::onControllerAddedOrRemovedLocked() { if (requireListener && mWindowInfoListener == nullptr) { mWindowInfoListener = sp<PointerChoreographerDisplayInfoListener>::make(this); auto initialInfo = std::make_pair(std::vector<android::gui::WindowInfo>{}, std::vector<android::gui::DisplayInfo>{}); #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener, &initialInfo); #endif mWindowInfoListener->setInitialDisplayInfos(initialInfo.first); mWindowInfoListener->setInitialDisplayInfos(mRegisterListener(mWindowInfoListener)); onPrivacySensitiveDisplaysChangedLocked(mWindowInfoListener->getPrivacySensitiveDisplays()); } else if (!requireListener && mWindowInfoListener != nullptr) { #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->removeWindowInfosListener(mWindowInfoListener); #endif mUnregisterListener(mWindowInfoListener); mWindowInfoListener = nullptr; } else if (requireListener && mWindowInfoListener != nullptr) { // controller may have been added to an existing privacy sensitive display, we need to Loading services/inputflinger/PointerChoreographer.h +16 −4 Original line number Diff line number Diff line Loading @@ -108,10 +108,6 @@ public: void notifyDeviceReset(const NotifyDeviceResetArgs& args) override; void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override; // Public because it's also used by tests to simulate the WindowInfosListener callback void onPrivacySensitiveDisplaysChanged( const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays); void dump(std::string& dump) override; private: Loading Loading @@ -139,6 +135,8 @@ private: void onPrivacySensitiveDisplaysChangedLocked( const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays) REQUIRES(mLock); void onPrivacySensitiveDisplaysChanged( const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays); /* This listener keeps tracks of visible privacy sensitive displays and updates the * choreographer if there are any changes. Loading Loading @@ -194,6 +192,20 @@ private: bool mShowTouchesEnabled GUARDED_BY(mLock); bool mStylusPointerIconEnabled GUARDED_BY(mLock); std::set<ui::LogicalDisplayId /*displayId*/> mDisplaysWithPointersHidden; protected: using WindowListenerRegisterConsumer = std::function<std::vector<gui::WindowInfo>( const sp<android::gui::WindowInfosListener>&)>; using WindowListenerUnregisterConsumer = std::function<void(const sp<android::gui::WindowInfosListener>&)>; explicit PointerChoreographer(InputListenerInterface& listener, PointerChoreographerPolicyInterface&, const WindowListenerRegisterConsumer& registerListener, const WindowListenerUnregisterConsumer& unregisterListener); private: const WindowListenerRegisterConsumer mRegisterListener; const WindowListenerUnregisterConsumer mUnregisterListener; }; } // namespace android services/inputflinger/tests/FakePointerController.cpp +17 −7 Original line number Diff line number Diff line Loading @@ -77,10 +77,12 @@ void FakePointerController::setCustomPointerIcon(const SpriteIcon& icon) { } void FakePointerController::setSkipScreenshotFlagForDisplay(ui::LogicalDisplayId displayId) { mDisplaysToSkipScreenshotFlagChanged = true; mDisplaysToSkipScreenshot.insert(displayId); } void FakePointerController::clearSkipScreenshotFlags() { mDisplaysToSkipScreenshotFlagChanged = true; mDisplaysToSkipScreenshot.clear(); } Loading Loading @@ -125,13 +127,21 @@ void FakePointerController::assertCustomPointerIconNotSet() { ASSERT_EQ(std::nullopt, mCustomIconStyle); } void FakePointerController::assertIsHiddenOnMirroredDisplays(ui::LogicalDisplayId displayId, bool isHidden) { if (isHidden) { void FakePointerController::assertIsSkipScreenshotFlagSet(ui::LogicalDisplayId displayId) { ASSERT_TRUE(mDisplaysToSkipScreenshot.find(displayId) != mDisplaysToSkipScreenshot.end()); } else { } void FakePointerController::assertIsSkipScreenshotFlagNotSet(ui::LogicalDisplayId displayId) { ASSERT_TRUE(mDisplaysToSkipScreenshot.find(displayId) == mDisplaysToSkipScreenshot.end()); } void FakePointerController::assertSkipScreenshotFlagChanged() { ASSERT_TRUE(mDisplaysToSkipScreenshotFlagChanged); mDisplaysToSkipScreenshotFlagChanged = false; } void FakePointerController::assertSkipScreenshotFlagNotChanged() { ASSERT_FALSE(mDisplaysToSkipScreenshotFlagChanged); } bool FakePointerController::isPointerShown() { Loading services/inputflinger/tests/FakePointerController.h +5 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,10 @@ public: void assertPointerIconNotSet(); void assertCustomPointerIconSet(PointerIconStyle iconId); void assertCustomPointerIconNotSet(); void assertIsHiddenOnMirroredDisplays(ui::LogicalDisplayId displayId, bool isHidden); void assertIsSkipScreenshotFlagSet(ui::LogicalDisplayId displayId); void assertIsSkipScreenshotFlagNotSet(ui::LogicalDisplayId displayId); void assertSkipScreenshotFlagChanged(); void assertSkipScreenshotFlagNotChanged(); bool isPointerShown(); private: Loading @@ -81,6 +84,7 @@ private: std::map<ui::LogicalDisplayId, std::vector<int32_t>> mSpotsByDisplay; std::unordered_set<ui::LogicalDisplayId> mDisplaysToSkipScreenshot; bool mDisplaysToSkipScreenshotFlagChanged{false}; }; } // namespace android services/inputflinger/tests/InterfaceMocks.h +10 −0 Original line number Diff line number Diff line Loading @@ -27,7 +27,9 @@ #include <EventHub.h> #include <InputReaderBase.h> #include <InputReaderContext.h> #include <NotifyArgs.h> #include <PointerChoreographerPolicyInterface.h> #include <StylusState.h> #include <VibrationElement.h> #include <android-base/logging.h> Loading Loading @@ -174,4 +176,12 @@ public: MOCK_METHOD(void, sysfsNodeChanged, (const std::string& sysfsNodePath), (override)); }; class MockPointerChoreographerPolicyInterface : public PointerChoreographerPolicyInterface { public: MOCK_METHOD(std::shared_ptr<PointerControllerInterface>, createPointerController, (PointerControllerInterface::ControllerType), (override)); MOCK_METHOD(void, notifyPointerDisplayIdChanged, (ui::LogicalDisplayId displayId, const FloatPoint& position), (override)); }; } // namespace android Loading
services/inputflinger/PointerChoreographer.cpp +31 −17 Original line number Diff line number Diff line Loading @@ -30,10 +30,6 @@ namespace android { namespace input_flags = com::android::input::flags; static const bool HIDE_TOUCH_INDICATORS_FOR_SECURE_WINDOWS = input_flags::hide_pointer_indicators_for_secure_windows(); namespace { bool isFromMouse(const NotifyMotionArgs& args) { Loading Loading @@ -106,8 +102,31 @@ std::unordered_set<ui::LogicalDisplayId> getPrivacySensitiveDisplaysFromWindowIn // --- PointerChoreographer --- PointerChoreographer::PointerChoreographer(InputListenerInterface& listener, PointerChoreographer::PointerChoreographer(InputListenerInterface& inputListener, PointerChoreographerPolicyInterface& policy) : PointerChoreographer( inputListener, policy, [](const sp<android::gui::WindowInfosListener>& listener) { auto initialInfo = std::make_pair(std::vector<android::gui::WindowInfo>{}, std::vector<android::gui::DisplayInfo>{}); #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->addWindowInfosListener(listener, &initialInfo); #endif return initialInfo.first; }, [](const sp<android::gui::WindowInfosListener>& listener) { #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->removeWindowInfosListener(listener); #endif }) { } PointerChoreographer::PointerChoreographer( android::InputListenerInterface& listener, android::PointerChoreographerPolicyInterface& policy, const android::PointerChoreographer::WindowListenerRegisterConsumer& registerListener, const android::PointerChoreographer::WindowListenerUnregisterConsumer& unregisterListener) : mTouchControllerConstructor([this]() { return mPolicy.createPointerController( PointerControllerInterface::ControllerType::TOUCH); Loading @@ -117,7 +136,9 @@ PointerChoreographer::PointerChoreographer(InputListenerInterface& listener, mDefaultMouseDisplayId(ui::LogicalDisplayId::DEFAULT), mNotifiedPointerDisplayId(ui::LogicalDisplayId::INVALID), mShowTouchesEnabled(false), mStylusPointerIconEnabled(false) {} mStylusPointerIconEnabled(false), mRegisterListener(registerListener), mUnregisterListener(unregisterListener) {} PointerChoreographer::~PointerChoreographer() { std::scoped_lock _l(mLock); Loading @@ -125,6 +146,7 @@ PointerChoreographer::~PointerChoreographer() { return; } mWindowInfoListener->onPointerChoreographerDestroyed(); mUnregisterListener(mWindowInfoListener); } void PointerChoreographer::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) { Loading Loading @@ -391,7 +413,7 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args) } void PointerChoreographer::onControllerAddedOrRemovedLocked() { if (!HIDE_TOUCH_INDICATORS_FOR_SECURE_WINDOWS) { if (!com::android::input::flags::hide_pointer_indicators_for_secure_windows()) { return; } bool requireListener = !mTouchPointersByDevice.empty() || !mMousePointersByDisplay.empty() || Loading @@ -399,18 +421,10 @@ void PointerChoreographer::onControllerAddedOrRemovedLocked() { if (requireListener && mWindowInfoListener == nullptr) { mWindowInfoListener = sp<PointerChoreographerDisplayInfoListener>::make(this); auto initialInfo = std::make_pair(std::vector<android::gui::WindowInfo>{}, std::vector<android::gui::DisplayInfo>{}); #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener, &initialInfo); #endif mWindowInfoListener->setInitialDisplayInfos(initialInfo.first); mWindowInfoListener->setInitialDisplayInfos(mRegisterListener(mWindowInfoListener)); onPrivacySensitiveDisplaysChangedLocked(mWindowInfoListener->getPrivacySensitiveDisplays()); } else if (!requireListener && mWindowInfoListener != nullptr) { #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->removeWindowInfosListener(mWindowInfoListener); #endif mUnregisterListener(mWindowInfoListener); mWindowInfoListener = nullptr; } else if (requireListener && mWindowInfoListener != nullptr) { // controller may have been added to an existing privacy sensitive display, we need to Loading
services/inputflinger/PointerChoreographer.h +16 −4 Original line number Diff line number Diff line Loading @@ -108,10 +108,6 @@ public: void notifyDeviceReset(const NotifyDeviceResetArgs& args) override; void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) override; // Public because it's also used by tests to simulate the WindowInfosListener callback void onPrivacySensitiveDisplaysChanged( const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays); void dump(std::string& dump) override; private: Loading Loading @@ -139,6 +135,8 @@ private: void onPrivacySensitiveDisplaysChangedLocked( const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays) REQUIRES(mLock); void onPrivacySensitiveDisplaysChanged( const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays); /* This listener keeps tracks of visible privacy sensitive displays and updates the * choreographer if there are any changes. Loading Loading @@ -194,6 +192,20 @@ private: bool mShowTouchesEnabled GUARDED_BY(mLock); bool mStylusPointerIconEnabled GUARDED_BY(mLock); std::set<ui::LogicalDisplayId /*displayId*/> mDisplaysWithPointersHidden; protected: using WindowListenerRegisterConsumer = std::function<std::vector<gui::WindowInfo>( const sp<android::gui::WindowInfosListener>&)>; using WindowListenerUnregisterConsumer = std::function<void(const sp<android::gui::WindowInfosListener>&)>; explicit PointerChoreographer(InputListenerInterface& listener, PointerChoreographerPolicyInterface&, const WindowListenerRegisterConsumer& registerListener, const WindowListenerUnregisterConsumer& unregisterListener); private: const WindowListenerRegisterConsumer mRegisterListener; const WindowListenerUnregisterConsumer mUnregisterListener; }; } // namespace android
services/inputflinger/tests/FakePointerController.cpp +17 −7 Original line number Diff line number Diff line Loading @@ -77,10 +77,12 @@ void FakePointerController::setCustomPointerIcon(const SpriteIcon& icon) { } void FakePointerController::setSkipScreenshotFlagForDisplay(ui::LogicalDisplayId displayId) { mDisplaysToSkipScreenshotFlagChanged = true; mDisplaysToSkipScreenshot.insert(displayId); } void FakePointerController::clearSkipScreenshotFlags() { mDisplaysToSkipScreenshotFlagChanged = true; mDisplaysToSkipScreenshot.clear(); } Loading Loading @@ -125,13 +127,21 @@ void FakePointerController::assertCustomPointerIconNotSet() { ASSERT_EQ(std::nullopt, mCustomIconStyle); } void FakePointerController::assertIsHiddenOnMirroredDisplays(ui::LogicalDisplayId displayId, bool isHidden) { if (isHidden) { void FakePointerController::assertIsSkipScreenshotFlagSet(ui::LogicalDisplayId displayId) { ASSERT_TRUE(mDisplaysToSkipScreenshot.find(displayId) != mDisplaysToSkipScreenshot.end()); } else { } void FakePointerController::assertIsSkipScreenshotFlagNotSet(ui::LogicalDisplayId displayId) { ASSERT_TRUE(mDisplaysToSkipScreenshot.find(displayId) == mDisplaysToSkipScreenshot.end()); } void FakePointerController::assertSkipScreenshotFlagChanged() { ASSERT_TRUE(mDisplaysToSkipScreenshotFlagChanged); mDisplaysToSkipScreenshotFlagChanged = false; } void FakePointerController::assertSkipScreenshotFlagNotChanged() { ASSERT_FALSE(mDisplaysToSkipScreenshotFlagChanged); } bool FakePointerController::isPointerShown() { Loading
services/inputflinger/tests/FakePointerController.h +5 −1 Original line number Diff line number Diff line Loading @@ -57,7 +57,10 @@ public: void assertPointerIconNotSet(); void assertCustomPointerIconSet(PointerIconStyle iconId); void assertCustomPointerIconNotSet(); void assertIsHiddenOnMirroredDisplays(ui::LogicalDisplayId displayId, bool isHidden); void assertIsSkipScreenshotFlagSet(ui::LogicalDisplayId displayId); void assertIsSkipScreenshotFlagNotSet(ui::LogicalDisplayId displayId); void assertSkipScreenshotFlagChanged(); void assertSkipScreenshotFlagNotChanged(); bool isPointerShown(); private: Loading @@ -81,6 +84,7 @@ private: std::map<ui::LogicalDisplayId, std::vector<int32_t>> mSpotsByDisplay; std::unordered_set<ui::LogicalDisplayId> mDisplaysToSkipScreenshot; bool mDisplaysToSkipScreenshotFlagChanged{false}; }; } // namespace android
services/inputflinger/tests/InterfaceMocks.h +10 −0 Original line number Diff line number Diff line Loading @@ -27,7 +27,9 @@ #include <EventHub.h> #include <InputReaderBase.h> #include <InputReaderContext.h> #include <NotifyArgs.h> #include <PointerChoreographerPolicyInterface.h> #include <StylusState.h> #include <VibrationElement.h> #include <android-base/logging.h> Loading Loading @@ -174,4 +176,12 @@ public: MOCK_METHOD(void, sysfsNodeChanged, (const std::string& sysfsNodePath), (override)); }; class MockPointerChoreographerPolicyInterface : public PointerChoreographerPolicyInterface { public: MOCK_METHOD(std::shared_ptr<PointerControllerInterface>, createPointerController, (PointerControllerInterface::ControllerType), (override)); MOCK_METHOD(void, notifyPointerDisplayIdChanged, (ui::LogicalDisplayId displayId, const FloatPoint& position), (override)); }; } // namespace android