Loading services/inputflinger/PointerChoreographer.cpp +99 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,12 @@ #define LOG_TAG "PointerChoreographer" #include <android-base/logging.h> #include <com_android_input_flags.h> #if defined(__ANDROID__) #include <gui/SurfaceComposerClient.h> #endif #include <input/PrintTools.h> #include <unordered_set> #include "PointerChoreographer.h" Loading @@ -25,6 +30,10 @@ 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 @@ -96,6 +105,14 @@ PointerChoreographer::PointerChoreographer(InputListenerInterface& listener, mShowTouchesEnabled(false), mStylusPointerIconEnabled(false) {} PointerChoreographer::~PointerChoreographer() { std::scoped_lock _l(mLock); if (mWindowInfoListener == nullptr) { return; } mWindowInfoListener->onPointerChoreographerDestroyed(); } void PointerChoreographer::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) { PointerDisplayChange pointerDisplayChange; Loading Loading @@ -231,6 +248,7 @@ void PointerChoreographer::processDrawingTabletEventLocked(const android::Notify auto [it, _] = mDrawingTabletPointersByDevice.try_emplace(args.deviceId, getMouseControllerConstructor( args.displayId)); // TODO (b/325252005): Add handing for drawing tablets mouse pointer controller PointerControllerInterface& pc = *it->second; Loading Loading @@ -268,7 +286,11 @@ void PointerChoreographer::processTouchscreenAndStylusEventLocked(const NotifyMo } // Get the touch pointer controller for the device, or create one if it doesn't exist. auto [it, _] = mTouchPointersByDevice.try_emplace(args.deviceId, mTouchControllerConstructor); auto [it, controllerAdded] = mTouchPointersByDevice.try_emplace(args.deviceId, mTouchControllerConstructor); if (controllerAdded) { onControllerAddedOrRemoved(); } PointerControllerInterface& pc = *it->second; Loading Loading @@ -306,6 +328,7 @@ void PointerChoreographer::processStylusHoverEventLocked(const NotifyMotionArgs& auto [it, _] = mStylusPointersByDevice.try_emplace(args.deviceId, getStylusControllerConstructor(args.displayId)); // TODO (b/325252005): Add handing for stylus pointer controller PointerControllerInterface& pc = *it->second; Loading Loading @@ -345,6 +368,31 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args) mTouchPointersByDevice.erase(args.deviceId); mStylusPointersByDevice.erase(args.deviceId); mDrawingTabletPointersByDevice.erase(args.deviceId); onControllerAddedOrRemoved(); } void PointerChoreographer::onControllerAddedOrRemoved() { if (!HIDE_TOUCH_INDICATORS_FOR_SECURE_WINDOWS) { return; } bool requireListener = !mTouchPointersByDevice.empty(); // TODO (b/325252005): Update for other types of pointer controllers 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 onWindowInfosChangedLocked(initialInfo.first); } else if (!requireListener && mWindowInfoListener != nullptr) { #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->removeWindowInfosListener(mWindowInfoListener); #endif mWindowInfoListener = nullptr; } } void PointerChoreographer::notifyPointerCaptureChanged( Loading @@ -358,6 +406,12 @@ void PointerChoreographer::notifyPointerCaptureChanged( mNextListener.notify(args); } void PointerChoreographer::onWindowInfosChanged( const std::vector<android::gui::WindowInfo>& windowInfos) { std::scoped_lock _l(mLock); onWindowInfosChangedLocked(windowInfos); } void PointerChoreographer::dump(std::string& dump) { std::scoped_lock _l(mLock); Loading Loading @@ -410,6 +464,7 @@ std::pair<int32_t, PointerControllerInterface&> PointerChoreographer::ensureMous if (it == mMousePointersByDisplay.end()) { it = mMousePointersByDisplay.emplace(displayId, getMouseControllerConstructor(displayId)) .first; // TODO (b/325252005): Add handing for mouse pointer controller } return {displayId, *it->second}; Loading Loading @@ -450,6 +505,8 @@ PointerChoreographer::PointerDisplayChange PointerChoreographer::updatePointerCo auto [mousePointerIt, isNewMousePointer] = mMousePointersByDisplay.try_emplace(displayId, getMouseControllerConstructor(displayId)); // TODO (b/325252005): Add handing for mouse pointer controller mMouseDevices.emplace(info.getId()); if ((!isKnownMouse || isNewMousePointer) && canUnfadeOnDisplay(displayId)) { mousePointerIt->second->unfade(PointerControllerInterface::Transition::IMMEDIATE); Loading Loading @@ -488,6 +545,8 @@ PointerChoreographer::PointerDisplayChange PointerChoreographer::updatePointerCo mInputDeviceInfos.end(); }); onControllerAddedOrRemoved(); // Check if we need to notify the policy if there's a change on the pointer display ID. return calculatePointerDisplayChangeToNotify(); } Loading Loading @@ -652,6 +711,31 @@ bool PointerChoreographer::setPointerIcon( 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<int32_t> privacySensitiveDisplays; std::unordered_set<int32_t> 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 (int32_t 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(int32_t displayId, bool visible) { std::scoped_lock lock(mLock); if (visible) { Loading Loading @@ -702,4 +786,18 @@ PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusContr return ConstructorDelegate(std::move(ctor)); } void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfosChanged( const gui::WindowInfosUpdate& windowInfosUpdate) { std::scoped_lock _l(mListenerLock); if (mPointerChoreographer != nullptr) { mPointerChoreographer->onWindowInfosChanged(windowInfosUpdate.windowInfos); } } void PointerChoreographer::PointerChoreographerDisplayInfoListener:: onPointerChoreographerDestroyed() { std::scoped_lock _l(mListenerLock); mPointerChoreographer = nullptr; } } // namespace android services/inputflinger/PointerChoreographer.h +21 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "PointerChoreographerPolicyInterface.h" #include <android-base/thread_annotations.h> #include <gui/WindowInfosListener.h> #include <type_traits> namespace android { Loading Loading @@ -83,7 +84,7 @@ class PointerChoreographer : public PointerChoreographerInterface { public: explicit PointerChoreographer(InputListenerInterface& listener, PointerChoreographerPolicyInterface&); ~PointerChoreographer() override = default; ~PointerChoreographer() override; void setDefaultMouseDisplayId(int32_t displayId) override; void setDisplayViewports(const std::vector<DisplayViewport>& viewports) override; Loading @@ -106,6 +107,9 @@ 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 onWindowInfosChanged(const std::vector<android::gui::WindowInfo>& windowInfos); void dump(std::string& dump) override; private: Loading @@ -127,6 +131,22 @@ private: 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) REQUIRES(mLock); class PointerChoreographerDisplayInfoListener : public gui::WindowInfosListener { public: explicit PointerChoreographerDisplayInfoListener(PointerChoreographer* pc) : mPointerChoreographer(pc){}; void onWindowInfosChanged(const gui::WindowInfosUpdate&) override; void onPointerChoreographerDestroyed(); private: std::mutex mListenerLock; PointerChoreographer* mPointerChoreographer GUARDED_BY(mListenerLock); }; sp<PointerChoreographerDisplayInfoListener> mWindowInfoListener GUARDED_BY(mLock); using ControllerConstructor = ConstructorDelegate<std::function<std::shared_ptr<PointerControllerInterface>()>>; Loading services/inputflinger/include/PointerControllerInterface.h +5 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,11 @@ public: /* 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. */ virtual void setSkipScreenshot(int32_t displayId, bool skip) = 0; }; } // namespace android services/inputflinger/tests/FakePointerController.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,14 @@ void FakePointerController::setCustomPointerIcon(const SpriteIcon& icon) { mCustomIconStyle = icon.style; } void FakePointerController::setSkipScreenshot(int32_t displayId, bool skip) { if (skip) { mDisplaysToSkipScreenshot.insert(displayId); } else { mDisplaysToSkipScreenshot.erase(displayId); } }; void FakePointerController::assertViewportSet(int32_t displayId) { ASSERT_TRUE(mDisplayId); ASSERT_EQ(displayId, mDisplayId); Loading Loading @@ -117,6 +125,14 @@ void FakePointerController::assertCustomPointerIconNotSet() { ASSERT_EQ(std::nullopt, mCustomIconStyle); } void FakePointerController::assertIsHiddenOnMirroredDisplays(int32_t displayId, bool isHidden) { if (isHidden) { ASSERT_TRUE(mDisplaysToSkipScreenshot.find(displayId) != mDisplaysToSkipScreenshot.end()); } else { ASSERT_TRUE(mDisplaysToSkipScreenshot.find(displayId) == mDisplaysToSkipScreenshot.end()); } } bool FakePointerController::isPointerShown() { return mIsPointerShown; } Loading services/inputflinger/tests/FakePointerController.h +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <input/DisplayViewport.h> #include <input/Input.h> #include <utils/BitSet.h> #include <unordered_set> namespace android { Loading @@ -45,6 +46,7 @@ public: void setDisplayViewport(const DisplayViewport& viewport) override; void updatePointerIcon(PointerIconStyle iconId) override; void setCustomPointerIcon(const SpriteIcon& icon) override; void setSkipScreenshot(int32_t displayId, bool skip) override; void fade(Transition) override; void assertViewportSet(int32_t displayId); Loading @@ -55,6 +57,7 @@ public: void assertPointerIconNotSet(); void assertCustomPointerIconSet(PointerIconStyle iconId); void assertCustomPointerIconNotSet(); void assertIsHiddenOnMirroredDisplays(int32_t displayId, bool isHidden); bool isPointerShown(); private: Loading @@ -77,6 +80,7 @@ private: std::optional<PointerIconStyle> mCustomIconStyle; std::map<int32_t, std::vector<int32_t>> mSpotsByDisplay; std::unordered_set<int32_t> mDisplaysToSkipScreenshot; }; } // namespace android Loading
services/inputflinger/PointerChoreographer.cpp +99 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,12 @@ #define LOG_TAG "PointerChoreographer" #include <android-base/logging.h> #include <com_android_input_flags.h> #if defined(__ANDROID__) #include <gui/SurfaceComposerClient.h> #endif #include <input/PrintTools.h> #include <unordered_set> #include "PointerChoreographer.h" Loading @@ -25,6 +30,10 @@ 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 @@ -96,6 +105,14 @@ PointerChoreographer::PointerChoreographer(InputListenerInterface& listener, mShowTouchesEnabled(false), mStylusPointerIconEnabled(false) {} PointerChoreographer::~PointerChoreographer() { std::scoped_lock _l(mLock); if (mWindowInfoListener == nullptr) { return; } mWindowInfoListener->onPointerChoreographerDestroyed(); } void PointerChoreographer::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) { PointerDisplayChange pointerDisplayChange; Loading Loading @@ -231,6 +248,7 @@ void PointerChoreographer::processDrawingTabletEventLocked(const android::Notify auto [it, _] = mDrawingTabletPointersByDevice.try_emplace(args.deviceId, getMouseControllerConstructor( args.displayId)); // TODO (b/325252005): Add handing for drawing tablets mouse pointer controller PointerControllerInterface& pc = *it->second; Loading Loading @@ -268,7 +286,11 @@ void PointerChoreographer::processTouchscreenAndStylusEventLocked(const NotifyMo } // Get the touch pointer controller for the device, or create one if it doesn't exist. auto [it, _] = mTouchPointersByDevice.try_emplace(args.deviceId, mTouchControllerConstructor); auto [it, controllerAdded] = mTouchPointersByDevice.try_emplace(args.deviceId, mTouchControllerConstructor); if (controllerAdded) { onControllerAddedOrRemoved(); } PointerControllerInterface& pc = *it->second; Loading Loading @@ -306,6 +328,7 @@ void PointerChoreographer::processStylusHoverEventLocked(const NotifyMotionArgs& auto [it, _] = mStylusPointersByDevice.try_emplace(args.deviceId, getStylusControllerConstructor(args.displayId)); // TODO (b/325252005): Add handing for stylus pointer controller PointerControllerInterface& pc = *it->second; Loading Loading @@ -345,6 +368,31 @@ void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args) mTouchPointersByDevice.erase(args.deviceId); mStylusPointersByDevice.erase(args.deviceId); mDrawingTabletPointersByDevice.erase(args.deviceId); onControllerAddedOrRemoved(); } void PointerChoreographer::onControllerAddedOrRemoved() { if (!HIDE_TOUCH_INDICATORS_FOR_SECURE_WINDOWS) { return; } bool requireListener = !mTouchPointersByDevice.empty(); // TODO (b/325252005): Update for other types of pointer controllers 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 onWindowInfosChangedLocked(initialInfo.first); } else if (!requireListener && mWindowInfoListener != nullptr) { #if defined(__ANDROID__) SurfaceComposerClient::getDefault()->removeWindowInfosListener(mWindowInfoListener); #endif mWindowInfoListener = nullptr; } } void PointerChoreographer::notifyPointerCaptureChanged( Loading @@ -358,6 +406,12 @@ void PointerChoreographer::notifyPointerCaptureChanged( mNextListener.notify(args); } void PointerChoreographer::onWindowInfosChanged( const std::vector<android::gui::WindowInfo>& windowInfos) { std::scoped_lock _l(mLock); onWindowInfosChangedLocked(windowInfos); } void PointerChoreographer::dump(std::string& dump) { std::scoped_lock _l(mLock); Loading Loading @@ -410,6 +464,7 @@ std::pair<int32_t, PointerControllerInterface&> PointerChoreographer::ensureMous if (it == mMousePointersByDisplay.end()) { it = mMousePointersByDisplay.emplace(displayId, getMouseControllerConstructor(displayId)) .first; // TODO (b/325252005): Add handing for mouse pointer controller } return {displayId, *it->second}; Loading Loading @@ -450,6 +505,8 @@ PointerChoreographer::PointerDisplayChange PointerChoreographer::updatePointerCo auto [mousePointerIt, isNewMousePointer] = mMousePointersByDisplay.try_emplace(displayId, getMouseControllerConstructor(displayId)); // TODO (b/325252005): Add handing for mouse pointer controller mMouseDevices.emplace(info.getId()); if ((!isKnownMouse || isNewMousePointer) && canUnfadeOnDisplay(displayId)) { mousePointerIt->second->unfade(PointerControllerInterface::Transition::IMMEDIATE); Loading Loading @@ -488,6 +545,8 @@ PointerChoreographer::PointerDisplayChange PointerChoreographer::updatePointerCo mInputDeviceInfos.end(); }); onControllerAddedOrRemoved(); // Check if we need to notify the policy if there's a change on the pointer display ID. return calculatePointerDisplayChangeToNotify(); } Loading Loading @@ -652,6 +711,31 @@ bool PointerChoreographer::setPointerIcon( 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<int32_t> privacySensitiveDisplays; std::unordered_set<int32_t> 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 (int32_t 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(int32_t displayId, bool visible) { std::scoped_lock lock(mLock); if (visible) { Loading Loading @@ -702,4 +786,18 @@ PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusContr return ConstructorDelegate(std::move(ctor)); } void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfosChanged( const gui::WindowInfosUpdate& windowInfosUpdate) { std::scoped_lock _l(mListenerLock); if (mPointerChoreographer != nullptr) { mPointerChoreographer->onWindowInfosChanged(windowInfosUpdate.windowInfos); } } void PointerChoreographer::PointerChoreographerDisplayInfoListener:: onPointerChoreographerDestroyed() { std::scoped_lock _l(mListenerLock); mPointerChoreographer = nullptr; } } // namespace android
services/inputflinger/PointerChoreographer.h +21 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "PointerChoreographerPolicyInterface.h" #include <android-base/thread_annotations.h> #include <gui/WindowInfosListener.h> #include <type_traits> namespace android { Loading Loading @@ -83,7 +84,7 @@ class PointerChoreographer : public PointerChoreographerInterface { public: explicit PointerChoreographer(InputListenerInterface& listener, PointerChoreographerPolicyInterface&); ~PointerChoreographer() override = default; ~PointerChoreographer() override; void setDefaultMouseDisplayId(int32_t displayId) override; void setDisplayViewports(const std::vector<DisplayViewport>& viewports) override; Loading @@ -106,6 +107,9 @@ 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 onWindowInfosChanged(const std::vector<android::gui::WindowInfo>& windowInfos); void dump(std::string& dump) override; private: Loading @@ -127,6 +131,22 @@ private: 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) REQUIRES(mLock); class PointerChoreographerDisplayInfoListener : public gui::WindowInfosListener { public: explicit PointerChoreographerDisplayInfoListener(PointerChoreographer* pc) : mPointerChoreographer(pc){}; void onWindowInfosChanged(const gui::WindowInfosUpdate&) override; void onPointerChoreographerDestroyed(); private: std::mutex mListenerLock; PointerChoreographer* mPointerChoreographer GUARDED_BY(mListenerLock); }; sp<PointerChoreographerDisplayInfoListener> mWindowInfoListener GUARDED_BY(mLock); using ControllerConstructor = ConstructorDelegate<std::function<std::shared_ptr<PointerControllerInterface>()>>; Loading
services/inputflinger/include/PointerControllerInterface.h +5 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,11 @@ public: /* 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. */ virtual void setSkipScreenshot(int32_t displayId, bool skip) = 0; }; } // namespace android
services/inputflinger/tests/FakePointerController.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,14 @@ void FakePointerController::setCustomPointerIcon(const SpriteIcon& icon) { mCustomIconStyle = icon.style; } void FakePointerController::setSkipScreenshot(int32_t displayId, bool skip) { if (skip) { mDisplaysToSkipScreenshot.insert(displayId); } else { mDisplaysToSkipScreenshot.erase(displayId); } }; void FakePointerController::assertViewportSet(int32_t displayId) { ASSERT_TRUE(mDisplayId); ASSERT_EQ(displayId, mDisplayId); Loading Loading @@ -117,6 +125,14 @@ void FakePointerController::assertCustomPointerIconNotSet() { ASSERT_EQ(std::nullopt, mCustomIconStyle); } void FakePointerController::assertIsHiddenOnMirroredDisplays(int32_t displayId, bool isHidden) { if (isHidden) { ASSERT_TRUE(mDisplaysToSkipScreenshot.find(displayId) != mDisplaysToSkipScreenshot.end()); } else { ASSERT_TRUE(mDisplaysToSkipScreenshot.find(displayId) == mDisplaysToSkipScreenshot.end()); } } bool FakePointerController::isPointerShown() { return mIsPointerShown; } Loading
services/inputflinger/tests/FakePointerController.h +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <input/DisplayViewport.h> #include <input/Input.h> #include <utils/BitSet.h> #include <unordered_set> namespace android { Loading @@ -45,6 +46,7 @@ public: void setDisplayViewport(const DisplayViewport& viewport) override; void updatePointerIcon(PointerIconStyle iconId) override; void setCustomPointerIcon(const SpriteIcon& icon) override; void setSkipScreenshot(int32_t displayId, bool skip) override; void fade(Transition) override; void assertViewportSet(int32_t displayId); Loading @@ -55,6 +57,7 @@ public: void assertPointerIconNotSet(); void assertCustomPointerIconSet(PointerIconStyle iconId); void assertCustomPointerIconNotSet(); void assertIsHiddenOnMirroredDisplays(int32_t displayId, bool isHidden); bool isPointerShown(); private: Loading @@ -77,6 +80,7 @@ private: std::optional<PointerIconStyle> mCustomIconStyle; std::map<int32_t, std::vector<int32_t>> mSpotsByDisplay; std::unordered_set<int32_t> mDisplaysToSkipScreenshot; }; } // namespace android