diff options
-rw-r--r-- | libs/input/PointerController.cpp | 90 | ||||
-rw-r--r-- | libs/input/PointerController.h | 18 |
2 files changed, 92 insertions, 16 deletions
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp index 8f04cfb70469..f43586f8d9d0 100644 --- a/libs/input/PointerController.cpp +++ b/libs/input/PointerController.cpp @@ -17,24 +17,29 @@ #define LOG_TAG "PointerController" //#define LOG_NDEBUG 0 -// Log debug messages about pointer updates -#define DEBUG_POINTER_UPDATES 0 - #include "PointerController.h" -#include "MouseCursorController.h" #include "PointerControllerContext.h" -#include "TouchSpotController.h" - -#include <log/log.h> -#include <SkBitmap.h> #include <SkBlendMode.h> #include <SkCanvas.h> #include <SkColor.h> -#include <SkPaint.h> namespace android { +namespace { + +const ui::Transform kIdentityTransform; + +} // namespace + +// --- PointerController::DisplayInfoListener --- + +void PointerController::DisplayInfoListener::onWindowInfosChanged( + const std::vector<android::gui::WindowInfo>&, + const std::vector<android::gui::DisplayInfo>& displayInfo) { + mPointerController.onDisplayInfosChanged(displayInfo); +} + // --- PointerController --- std::shared_ptr<PointerController> PointerController::create( @@ -63,9 +68,16 @@ std::shared_ptr<PointerController> PointerController::create( PointerController::PointerController(const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper, const sp<SpriteController>& spriteController) - : mContext(policy, looper, spriteController, *this), mCursorController(mContext) { + : mContext(policy, looper, spriteController, *this), + mCursorController(mContext), + mDisplayInfoListener(new DisplayInfoListener(*this)) { std::scoped_lock lock(mLock); mLocked.presentation = Presentation::SPOT; + SurfaceComposerClient::getDefault()->addWindowInfosListener(mDisplayInfoListener); +} + +PointerController::~PointerController() { + SurfaceComposerClient::getDefault()->removeWindowInfosListener(mDisplayInfoListener); } bool PointerController::getBounds(float* outMinX, float* outMinY, float* outMaxX, @@ -74,7 +86,14 @@ bool PointerController::getBounds(float* outMinX, float* outMinY, float* outMaxX } void PointerController::move(float deltaX, float deltaY) { - mCursorController.move(deltaX, deltaY); + const int32_t displayId = mCursorController.getDisplayId(); + vec2 transformed; + { + std::scoped_lock lock(mLock); + const auto& transform = getTransformForDisplayLocked(displayId); + transformed = transformWithoutTranslation(transform, {deltaX, deltaY}); + } + mCursorController.move(transformed.x, transformed.y); } void PointerController::setButtonState(int32_t buttonState) { @@ -86,12 +105,26 @@ int32_t PointerController::getButtonState() const { } void PointerController::setPosition(float x, float y) { - std::scoped_lock lock(mLock); - mCursorController.setPosition(x, y); + const int32_t displayId = mCursorController.getDisplayId(); + vec2 transformed; + { + std::scoped_lock lock(mLock); + const auto& transform = getTransformForDisplayLocked(displayId); + transformed = transform.transform(x, y); + } + mCursorController.setPosition(transformed.x, transformed.y); } void PointerController::getPosition(float* outX, float* outY) const { + const int32_t displayId = mCursorController.getDisplayId(); mCursorController.getPosition(outX, outY); + { + std::scoped_lock lock(mLock); + const auto& transform = getTransformForDisplayLocked(displayId); + const auto xy = transform.inverse().transform(*outX, *outY); + *outX = xy.x; + *outY = xy.y; + } } int32_t PointerController::getDisplayId() const { @@ -130,11 +163,25 @@ void PointerController::setPresentation(Presentation presentation) { void PointerController::setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, BitSet32 spotIdBits, int32_t displayId) { std::scoped_lock lock(mLock); + std::array<PointerCoords, MAX_POINTERS> outSpotCoords{}; + const ui::Transform& transform = getTransformForDisplayLocked(displayId); + + for (BitSet32 idBits(spotIdBits); !idBits.isEmpty();) { + const uint32_t index = spotIdToIndex[idBits.clearFirstMarkedBit()]; + + const vec2 xy = transform.transform(spotCoords[index].getXYValue()); + outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_X, xy.x); + outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y); + + float pressure = spotCoords[index].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE); + outSpotCoords[index].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure); + } + auto it = mLocked.spotControllers.find(displayId); if (it == mLocked.spotControllers.end()) { mLocked.spotControllers.try_emplace(displayId, displayId, mContext); } - mLocked.spotControllers.at(displayId).setSpots(spotCoords, spotIdToIndex, spotIdBits); + mLocked.spotControllers.at(displayId).setSpots(outSpotCoords.data(), spotIdToIndex, spotIdBits); } void PointerController::clearSpots() { @@ -194,7 +241,7 @@ void PointerController::doInactivityTimeout() { void PointerController::onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports) { std::unordered_set<int32_t> displayIdSet; - for (DisplayViewport viewport : viewports) { + for (const DisplayViewport& viewport : viewports) { displayIdSet.insert(viewport.displayId); } @@ -214,4 +261,17 @@ void PointerController::onDisplayViewportsUpdated(std::vector<DisplayViewport>& } } +void PointerController::onDisplayInfosChanged(const std::vector<gui::DisplayInfo>& displayInfo) { + std::scoped_lock lock(mLock); + mLocked.mDisplayInfos = displayInfo; +} + +const ui::Transform& PointerController::getTransformForDisplayLocked(int displayId) const { + const auto& di = mLocked.mDisplayInfos; + auto it = std::find_if(di.begin(), di.end(), [displayId](const gui::DisplayInfo& info) { + return info.displayId == displayId; + }); + return it != di.end() ? it->transform : kIdentityTransform; +} + } // namespace android diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h index 97567bab202b..796077f6c38c 100644 --- a/libs/input/PointerController.h +++ b/libs/input/PointerController.h @@ -47,7 +47,7 @@ public: const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper, const sp<SpriteController>& spriteController); - virtual ~PointerController() = default; + ~PointerController() override; virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const; virtual void move(float deltaX, float deltaY); @@ -72,6 +72,8 @@ public: void reloadPointerResources(); void onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports); + void onDisplayInfosChanged(const std::vector<gui::DisplayInfo>& displayInfos); + private: friend PointerControllerContext::LooperCallback; friend PointerControllerContext::MessageHandler; @@ -85,9 +87,23 @@ private: struct Locked { Presentation presentation; + std::vector<gui::DisplayInfo> mDisplayInfos; std::unordered_map<int32_t /* displayId */, TouchSpotController> spotControllers; } mLocked GUARDED_BY(mLock); + class DisplayInfoListener : public gui::WindowInfosListener { + public: + explicit DisplayInfoListener(PointerController& pc) : mPointerController(pc){}; + void onWindowInfosChanged(const std::vector<android::gui::WindowInfo>&, + const std::vector<android::gui::DisplayInfo>&) override; + + private: + PointerController& mPointerController; + }; + sp<DisplayInfoListener> mDisplayInfoListener; + + const ui::Transform& getTransformForDisplayLocked(int displayId) const REQUIRES(mLock); + PointerController(const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper, const sp<SpriteController>& spriteController); void clearSpotsLocked(); |