Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3a57dcd7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I7f8683f7,I7417c007 into main

* changes:
  Refactor processing of relative pointer movements
  Refactor PointerChoreographer lock
parents 2721b5c6 5cd7497f
Loading
Loading
Loading
Loading
+67 −67
Original line number Diff line number Diff line
@@ -139,23 +139,24 @@ PointerChoreographer::PointerChoreographer(
        mShowTouchesEnabled(false),
        mStylusPointerIconEnabled(false),
        mCurrentFocusedDisplay(ui::LogicalDisplayId::DEFAULT),
        mIsWindowInfoListenerRegistered(false),
        mWindowInfoListener(sp<PointerChoreographerDisplayInfoListener>::make(this)),
        mRegisterListener(registerListener),
        mUnregisterListener(unregisterListener) {}

PointerChoreographer::~PointerChoreographer() {
    std::scoped_lock _l(mLock);
    if (mWindowInfoListener == nullptr) {
        return;
    if (mIsWindowInfoListenerRegistered) {
        mUnregisterListener(mWindowInfoListener);
        mIsWindowInfoListenerRegistered = false;
    }
    mWindowInfoListener->onPointerChoreographerDestroyed();
    mUnregisterListener(mWindowInfoListener);
}

void PointerChoreographer::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
    PointerDisplayChange pointerDisplayChange;

    { // acquire lock
        std::scoped_lock _l(mLock);
        std::scoped_lock _l(getLock());

        mInputDeviceInfos = args.inputDeviceInfos;
        pointerDisplayChange = updatePointerControllersLocked();
@@ -191,7 +192,7 @@ void PointerChoreographer::fadeMouseCursorOnKeyPress(const android::NotifyKeyArg
        return;
    }

    std::scoped_lock _l(mLock);
    std::scoped_lock _l(getLock());
    ui::LogicalDisplayId targetDisplay = args.displayId;
    if (targetDisplay == ui::LogicalDisplayId::INVALID) {
        targetDisplay = mCurrentFocusedDisplay;
@@ -204,7 +205,7 @@ void PointerChoreographer::fadeMouseCursorOnKeyPress(const android::NotifyKeyArg
}

NotifyMotionArgs PointerChoreographer::processMotion(const NotifyMotionArgs& args) {
    std::scoped_lock _l(mLock);
    std::scoped_lock _l(getLock());

    if (isFromMouse(args)) {
        return processMouseEventLocked(args);
@@ -242,14 +243,7 @@ NotifyMotionArgs PointerChoreographer::processMouseEventLocked(const NotifyMotio
        pc.setPosition(args.xCursorPosition, args.yCursorPosition);
    } else {
        // This is a relative mouse, so move the cursor by the specified amount.
        const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
        const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
        pc.move(deltaX, deltaY);
        const auto [x, y] = pc.getPosition();
        newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
        newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
        newArgs.xCursorPosition = x;
        newArgs.yCursorPosition = y;
        processPointerDeviceMotionEventLocked(/*byref*/ newArgs, /*byref*/ pc);
    }
    if (canUnfadeOnDisplay(displayId)) {
        pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
@@ -265,24 +259,9 @@ NotifyMotionArgs PointerChoreographer::processTouchpadEventLocked(const NotifyMo
    newArgs.displayId = displayId;
    if (args.getPointerCount() == 1 && args.classification == MotionClassification::NONE) {
        // This is a movement of the mouse pointer.
        const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
        const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
        pc.move(deltaX, deltaY);
        if (canUnfadeOnDisplay(displayId)) {
            pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
        }

        const auto [x, y] = pc.getPosition();
        newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
        newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
        newArgs.xCursorPosition = x;
        newArgs.yCursorPosition = y;
        processPointerDeviceMotionEventLocked(/*byref*/ newArgs, /*byref*/ pc);
    } else {
        // This is a trackpad gesture with fake finger(s) that should not move the mouse pointer.
        if (canUnfadeOnDisplay(displayId)) {
            pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
        }

        const auto [x, y] = pc.getPosition();
        for (uint32_t i = 0; i < newArgs.getPointerCount(); i++) {
            newArgs.pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X,
@@ -293,9 +272,25 @@ NotifyMotionArgs PointerChoreographer::processTouchpadEventLocked(const NotifyMo
        newArgs.xCursorPosition = x;
        newArgs.yCursorPosition = y;
    }
    if (canUnfadeOnDisplay(displayId)) {
        pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
    }
    return newArgs;
}

void PointerChoreographer::processPointerDeviceMotionEventLocked(NotifyMotionArgs& newArgs,
                                                                 PointerControllerInterface& pc) {
    const float deltaX = newArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
    const float deltaY = newArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);

    pc.move(deltaX, deltaY);
    const auto [x, y] = pc.getPosition();
    newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
    newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
    newArgs.xCursorPosition = x;
    newArgs.yCursorPosition = y;
}

void PointerChoreographer::processDrawingTabletEventLocked(const android::NotifyMotionArgs& args) {
    if (args.displayId == ui::LogicalDisplayId::INVALID) {
        return;
@@ -433,7 +428,7 @@ void PointerChoreographer::notifyDeviceReset(const NotifyDeviceResetArgs& args)
}

void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args) {
    std::scoped_lock _l(mLock);
    std::scoped_lock _l(getLock());
    mTouchPointersByDevice.erase(args.deviceId);
    mStylusPointersByDevice.erase(args.deviceId);
    mDrawingTabletPointersByDevice.erase(args.deviceId);
@@ -447,17 +442,22 @@ void PointerChoreographer::onControllerAddedOrRemovedLocked() {
    bool requireListener = !mTouchPointersByDevice.empty() || !mMousePointersByDisplay.empty() ||
            !mDrawingTabletPointersByDevice.empty() || !mStylusPointersByDevice.empty();

    if (requireListener && mWindowInfoListener == nullptr) {
        mWindowInfoListener = sp<PointerChoreographerDisplayInfoListener>::make(this);
        mWindowInfoListener->setInitialDisplayInfos(mRegisterListener(mWindowInfoListener));
        onPrivacySensitiveDisplaysChangedLocked(mWindowInfoListener->getPrivacySensitiveDisplays());
    } else if (!requireListener && mWindowInfoListener != nullptr) {
    // PointerChoreographer uses Listener's lock which is already held by caller
    base::ScopedLockAssertion assumeLocked(mWindowInfoListener->mLock);

    if (requireListener && !mIsWindowInfoListenerRegistered) {
        mIsWindowInfoListenerRegistered = true;
        mWindowInfoListener->setInitialDisplayInfosLocked(mRegisterListener(mWindowInfoListener));
        onPrivacySensitiveDisplaysChangedLocked(
                mWindowInfoListener->getPrivacySensitiveDisplaysLocked());
    } else if (!requireListener && mIsWindowInfoListenerRegistered) {
        mIsWindowInfoListenerRegistered = false;
        mUnregisterListener(mWindowInfoListener);
        mWindowInfoListener = nullptr;
    } else if (requireListener && mWindowInfoListener != nullptr) {
    } else if (requireListener) {
        // controller may have been added to an existing privacy sensitive display, we need to
        // update all controllers again
        onPrivacySensitiveDisplaysChangedLocked(mWindowInfoListener->getPrivacySensitiveDisplays());
        onPrivacySensitiveDisplaysChangedLocked(
                mWindowInfoListener->getPrivacySensitiveDisplaysLocked());
    }
}

@@ -494,7 +494,7 @@ void PointerChoreographer::onPrivacySensitiveDisplaysChangedLocked(
void PointerChoreographer::notifyPointerCaptureChanged(
        const NotifyPointerCaptureChangedArgs& args) {
    if (args.request.isEnable()) {
        std::scoped_lock _l(mLock);
        std::scoped_lock _l(getLock());
        for (const auto& [_, mousePointerController] : mMousePointersByDisplay) {
            mousePointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
        }
@@ -502,14 +502,8 @@ void PointerChoreographer::notifyPointerCaptureChanged(
    mNextListener.notify(args);
}

void PointerChoreographer::onPrivacySensitiveDisplaysChanged(
        const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays) {
    std::scoped_lock _l(mLock);
    onPrivacySensitiveDisplaysChangedLocked(privacySensitiveDisplays);
}

void PointerChoreographer::dump(std::string& dump) {
    std::scoped_lock _l(mLock);
    std::scoped_lock _l(getLock());

    dump += "PointerChoreographer:\n";
    dump += StringPrintf(INDENT "Show Touches Enabled: %s\n",
@@ -579,6 +573,10 @@ bool PointerChoreographer::canUnfadeOnDisplay(ui::LogicalDisplayId displayId) {
    return mDisplaysWithPointersHidden.find(displayId) == mDisplaysWithPointersHidden.end();
}

std::mutex& PointerChoreographer::getLock() const {
    return mWindowInfoListener->mLock;
}

PointerChoreographer::PointerDisplayChange PointerChoreographer::updatePointerControllersLocked() {
    std::set<ui::LogicalDisplayId /*displayId*/> mouseDisplaysToKeep;
    std::set<DeviceId> touchDevicesToKeep;
@@ -641,7 +639,7 @@ PointerChoreographer::PointerDisplayChange PointerChoreographer::updatePointerCo
    std::erase_if(mDrawingTabletPointersByDevice, [&drawingTabletDevicesToKeep](const auto& pair) {
        return drawingTabletDevicesToKeep.find(pair.first) == drawingTabletDevicesToKeep.end();
    });
    std::erase_if(mMouseDevices, [&](DeviceId id) REQUIRES(mLock) {
    std::erase_if(mMouseDevices, [&](DeviceId id) REQUIRES(getLock()) {
        return std::find_if(mInputDeviceInfos.begin(), mInputDeviceInfos.end(),
                            [id](const auto& info) { return info.getId() == id; }) ==
                mInputDeviceInfos.end();
@@ -677,7 +675,7 @@ void PointerChoreographer::setDefaultMouseDisplayId(ui::LogicalDisplayId display
    PointerDisplayChange pointerDisplayChange;

    { // acquire lock
        std::scoped_lock _l(mLock);
        std::scoped_lock _l(getLock());

        mDefaultMouseDisplayId = displayId;
        pointerDisplayChange = updatePointerControllersLocked();
@@ -690,7 +688,7 @@ void PointerChoreographer::setDisplayViewports(const std::vector<DisplayViewport
    PointerDisplayChange pointerDisplayChange;

    { // acquire lock
        std::scoped_lock _l(mLock);
        std::scoped_lock _l(getLock());
        for (const auto& viewport : viewports) {
            const ui::LogicalDisplayId displayId = viewport.displayId;
            if (const auto it = mMousePointersByDisplay.find(displayId);
@@ -719,7 +717,7 @@ void PointerChoreographer::setDisplayViewports(const std::vector<DisplayViewport

std::optional<DisplayViewport> PointerChoreographer::getViewportForPointerDevice(
        ui::LogicalDisplayId associatedDisplayId) {
    std::scoped_lock _l(mLock);
    std::scoped_lock _l(getLock());
    const ui::LogicalDisplayId resolvedDisplayId = getTargetMouseDisplayLocked(associatedDisplayId);
    if (const auto viewport = findViewportByIdLocked(resolvedDisplayId); viewport) {
        return *viewport;
@@ -728,7 +726,7 @@ std::optional<DisplayViewport> PointerChoreographer::getViewportForPointerDevice
}

FloatPoint PointerChoreographer::getMouseCursorPosition(ui::LogicalDisplayId displayId) {
    std::scoped_lock _l(mLock);
    std::scoped_lock _l(getLock());
    const ui::LogicalDisplayId resolvedDisplayId = getTargetMouseDisplayLocked(displayId);
    if (auto it = mMousePointersByDisplay.find(resolvedDisplayId);
        it != mMousePointersByDisplay.end()) {
@@ -741,7 +739,7 @@ void PointerChoreographer::setShowTouchesEnabled(bool enabled) {
    PointerDisplayChange pointerDisplayChange;

    { // acquire lock
        std::scoped_lock _l(mLock);
        std::scoped_lock _l(getLock());
        if (mShowTouchesEnabled == enabled) {
            return;
        }
@@ -756,7 +754,7 @@ void PointerChoreographer::setStylusPointerIconEnabled(bool enabled) {
    PointerDisplayChange pointerDisplayChange;

    { // acquire lock
        std::scoped_lock _l(mLock);
        std::scoped_lock _l(getLock());
        if (mStylusPointerIconEnabled == enabled) {
            return;
        }
@@ -770,7 +768,7 @@ void PointerChoreographer::setStylusPointerIconEnabled(bool enabled) {
bool PointerChoreographer::setPointerIcon(
        std::variant<std::unique_ptr<SpriteIcon>, PointerIconStyle> icon,
        ui::LogicalDisplayId displayId, DeviceId deviceId) {
    std::scoped_lock _l(mLock);
    std::scoped_lock _l(getLock());
    if (deviceId < 0) {
        LOG(WARNING) << "Invalid device id " << deviceId << ". Cannot set pointer icon.";
        return false;
@@ -821,7 +819,7 @@ bool PointerChoreographer::setPointerIcon(
}

void PointerChoreographer::setPointerIconVisibility(ui::LogicalDisplayId displayId, bool visible) {
    std::scoped_lock lock(mLock);
    std::scoped_lock lock(getLock());
    if (visible) {
        mDisplaysWithPointersHidden.erase(displayId);
        // We do not unfade the icons here, because we don't know when the last event happened.
@@ -843,14 +841,14 @@ void PointerChoreographer::setPointerIconVisibility(ui::LogicalDisplayId display
}

void PointerChoreographer::setFocusedDisplay(ui::LogicalDisplayId displayId) {
    std::scoped_lock lock(mLock);
    std::scoped_lock lock(getLock());
    mCurrentFocusedDisplay = displayId;
}

PointerChoreographer::ControllerConstructor PointerChoreographer::getMouseControllerConstructor(
        ui::LogicalDisplayId displayId) {
    std::function<std::shared_ptr<PointerControllerInterface>()> ctor =
            [this, displayId]() REQUIRES(mLock) {
            [this, displayId]() REQUIRES(getLock()) {
                auto pc = mPolicy.createPointerController(
                        PointerControllerInterface::ControllerType::MOUSE);
                if (const auto viewport = findViewportByIdLocked(displayId); viewport) {
@@ -864,7 +862,7 @@ PointerChoreographer::ControllerConstructor PointerChoreographer::getMouseContro
PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusControllerConstructor(
        ui::LogicalDisplayId displayId) {
    std::function<std::shared_ptr<PointerControllerInterface>()> ctor =
            [this, displayId]() REQUIRES(mLock) {
            [this, displayId]() REQUIRES(getLock()) {
                auto pc = mPolicy.createPointerController(
                        PointerControllerInterface::ControllerType::STYLUS);
                if (const auto viewport = findViewportByIdLocked(displayId); viewport) {
@@ -875,9 +873,11 @@ PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusContr
    return ConstructorDelegate(std::move(ctor));
}

// --- PointerChoreographer::PointerChoreographerDisplayInfoListener ---

void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfosChanged(
        const gui::WindowInfosUpdate& windowInfosUpdate) {
    std::scoped_lock _l(mListenerLock);
    std::scoped_lock _l(mLock);
    if (mPointerChoreographer == nullptr) {
        return;
    }
@@ -885,25 +885,25 @@ void PointerChoreographer::PointerChoreographerDisplayInfoListener::onWindowInfo
            getPrivacySensitiveDisplaysFromWindowInfos(windowInfosUpdate.windowInfos);
    if (newPrivacySensitiveDisplays != mPrivacySensitiveDisplays) {
        mPrivacySensitiveDisplays = std::move(newPrivacySensitiveDisplays);
        mPointerChoreographer->onPrivacySensitiveDisplaysChanged(mPrivacySensitiveDisplays);
        // PointerChoreographer uses Listener's lock.
        base::ScopedLockAssertion assumeLocked(mPointerChoreographer->getLock());
        mPointerChoreographer->onPrivacySensitiveDisplaysChangedLocked(mPrivacySensitiveDisplays);
    }
}

void PointerChoreographer::PointerChoreographerDisplayInfoListener::setInitialDisplayInfos(
void PointerChoreographer::PointerChoreographerDisplayInfoListener::setInitialDisplayInfosLocked(
        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);
PointerChoreographer::PointerChoreographerDisplayInfoListener::getPrivacySensitiveDisplaysLocked() {
    return mPrivacySensitiveDisplays;
}

void PointerChoreographer::PointerChoreographerDisplayInfoListener::
        onPointerChoreographerDestroyed() {
    std::scoped_lock _l(mListenerLock);
    std::scoped_lock _l(mLock);
    mPointerChoreographer = nullptr;
}

+54 −40
Original line number Diff line number Diff line
@@ -118,31 +118,40 @@ public:
private:
    using PointerDisplayChange = std::optional<
            std::tuple<ui::LogicalDisplayId /*displayId*/, FloatPoint /*cursorPosition*/>>;
    [[nodiscard]] PointerDisplayChange updatePointerControllersLocked() REQUIRES(mLock);
    [[nodiscard]] PointerDisplayChange calculatePointerDisplayChangeToNotify() REQUIRES(mLock);

    // PointerChoreographer's DisplayInfoListener can outlive the PointerChoreographer because when
    // the listener is registered and called from display thread, a strong pointer to the listener
    // (which can extend its lifecycle) is given away.
    // If we use two locks it can also cause deadlocks due to race in acquiring them between the
    // display and reader thread.
    // To avoid these problems we use DisplayInfoListener's lock in PointerChoreographer.
    std::mutex& getLock() const;

    [[nodiscard]] PointerDisplayChange updatePointerControllersLocked() REQUIRES(getLock());
    [[nodiscard]] PointerDisplayChange calculatePointerDisplayChangeToNotify() REQUIRES(getLock());
    const DisplayViewport* findViewportByIdLocked(ui::LogicalDisplayId displayId) const
            REQUIRES(mLock);
            REQUIRES(getLock());
    ui::LogicalDisplayId getTargetMouseDisplayLocked(ui::LogicalDisplayId associatedDisplayId) const
            REQUIRES(mLock);
            REQUIRES(getLock());
    std::pair<ui::LogicalDisplayId /*displayId*/, PointerControllerInterface&>
    ensureMouseControllerLocked(ui::LogicalDisplayId associatedDisplayId) REQUIRES(mLock);
    InputDeviceInfo* findInputDeviceLocked(DeviceId deviceId) REQUIRES(mLock);
    bool canUnfadeOnDisplay(ui::LogicalDisplayId displayId) REQUIRES(mLock);
    ensureMouseControllerLocked(ui::LogicalDisplayId associatedDisplayId) REQUIRES(getLock());
    InputDeviceInfo* findInputDeviceLocked(DeviceId deviceId) REQUIRES(getLock());
    bool canUnfadeOnDisplay(ui::LogicalDisplayId displayId) REQUIRES(getLock());

    void fadeMouseCursorOnKeyPress(const NotifyKeyArgs& args);
    NotifyMotionArgs processMotion(const NotifyMotionArgs& args);
    NotifyMotionArgs processMouseEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
    NotifyMotionArgs processTouchpadEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
    void processDrawingTabletEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
    void processTouchscreenAndStylusEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
    void processStylusHoverEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
    NotifyMotionArgs processMouseEventLocked(const NotifyMotionArgs& args) REQUIRES(getLock());
    NotifyMotionArgs processTouchpadEventLocked(const NotifyMotionArgs& args) REQUIRES(getLock());
    void processDrawingTabletEventLocked(const NotifyMotionArgs& args) REQUIRES(getLock());
    void processTouchscreenAndStylusEventLocked(const NotifyMotionArgs& args) REQUIRES(getLock());
    void processStylusHoverEventLocked(const NotifyMotionArgs& args) REQUIRES(getLock());
    void processPointerDeviceMotionEventLocked(NotifyMotionArgs& newArgs,
                                               PointerControllerInterface& pc) REQUIRES(getLock());
    void processDeviceReset(const NotifyDeviceResetArgs& args);
    void onControllerAddedOrRemovedLocked() REQUIRES(mLock);
    void onControllerAddedOrRemovedLocked() REQUIRES(getLock());
    void onPrivacySensitiveDisplaysChangedLocked(
            const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays)
            REQUIRES(mLock);
    void onPrivacySensitiveDisplaysChanged(
            const std::unordered_set<ui::LogicalDisplayId>& privacySensitiveDisplays);
            REQUIRES(getLock());

    /* This listener keeps tracks of visible privacy sensitive displays and updates the
     * choreographer if there are any changes.
@@ -156,49 +165,50 @@ private:
        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 setInitialDisplayInfosLocked(const std::vector<gui::WindowInfo>& windowInfos)
                REQUIRES(mLock);
        std::unordered_set<ui::LogicalDisplayId> getPrivacySensitiveDisplaysLocked()
                REQUIRES(mLock);
        void onPointerChoreographerDestroyed();

        // This lock is also used by PointerChoreographer. See PointerChoreographer::getLock().
        std::mutex mLock;

    private:
        std::mutex mListenerLock;
        PointerChoreographer* mPointerChoreographer GUARDED_BY(mListenerLock);
        PointerChoreographer* mPointerChoreographer GUARDED_BY(mLock);
        std::unordered_set<ui::LogicalDisplayId /*displayId*/> mPrivacySensitiveDisplays
                GUARDED_BY(mListenerLock);
                GUARDED_BY(mLock);
    };
    sp<PointerChoreographerDisplayInfoListener> mWindowInfoListener GUARDED_BY(mLock);

    using ControllerConstructor =
            ConstructorDelegate<std::function<std::shared_ptr<PointerControllerInterface>()>>;
    ControllerConstructor mTouchControllerConstructor GUARDED_BY(mLock);
    ControllerConstructor mTouchControllerConstructor GUARDED_BY(getLock());
    ControllerConstructor getMouseControllerConstructor(ui::LogicalDisplayId displayId)
            REQUIRES(mLock);
            REQUIRES(getLock());
    ControllerConstructor getStylusControllerConstructor(ui::LogicalDisplayId displayId)
            REQUIRES(mLock);

    std::mutex mLock;
            REQUIRES(getLock());

    InputListenerInterface& mNextListener;
    PointerChoreographerPolicyInterface& mPolicy;

    std::map<ui::LogicalDisplayId, std::shared_ptr<PointerControllerInterface>>
            mMousePointersByDisplay GUARDED_BY(mLock);
            mMousePointersByDisplay GUARDED_BY(getLock());
    std::map<DeviceId, std::shared_ptr<PointerControllerInterface>> mTouchPointersByDevice
            GUARDED_BY(mLock);
            GUARDED_BY(getLock());
    std::map<DeviceId, std::shared_ptr<PointerControllerInterface>> mStylusPointersByDevice
            GUARDED_BY(mLock);
            GUARDED_BY(getLock());
    std::map<DeviceId, std::shared_ptr<PointerControllerInterface>> mDrawingTabletPointersByDevice
            GUARDED_BY(mLock);

    ui::LogicalDisplayId mDefaultMouseDisplayId GUARDED_BY(mLock);
    ui::LogicalDisplayId mNotifiedPointerDisplayId GUARDED_BY(mLock);
    std::vector<InputDeviceInfo> mInputDeviceInfos GUARDED_BY(mLock);
    std::set<DeviceId> mMouseDevices GUARDED_BY(mLock);
    std::vector<DisplayViewport> mViewports GUARDED_BY(mLock);
    bool mShowTouchesEnabled GUARDED_BY(mLock);
    bool mStylusPointerIconEnabled GUARDED_BY(mLock);
            GUARDED_BY(getLock());

    ui::LogicalDisplayId mDefaultMouseDisplayId GUARDED_BY(getLock());
    ui::LogicalDisplayId mNotifiedPointerDisplayId GUARDED_BY(getLock());
    std::vector<InputDeviceInfo> mInputDeviceInfos GUARDED_BY(getLock());
    std::set<DeviceId> mMouseDevices GUARDED_BY(getLock());
    std::vector<DisplayViewport> mViewports GUARDED_BY(getLock());
    bool mShowTouchesEnabled GUARDED_BY(getLock());
    bool mStylusPointerIconEnabled GUARDED_BY(getLock());
    std::set<ui::LogicalDisplayId /*displayId*/> mDisplaysWithPointersHidden;
    ui::LogicalDisplayId mCurrentFocusedDisplay GUARDED_BY(mLock);
    ui::LogicalDisplayId mCurrentFocusedDisplay GUARDED_BY(getLock());

protected:
    using WindowListenerRegisterConsumer = std::function<std::vector<gui::WindowInfo>(
@@ -211,6 +221,10 @@ protected:
                                  const WindowListenerUnregisterConsumer& unregisterListener);

private:
    // WindowInfoListener object should always exist while PointerChoreographer exists, because we
    // need to use the lock from it. But we don't always need to register the listener.
    bool mIsWindowInfoListenerRegistered GUARDED_BY(getLock());
    const sp<PointerChoreographerDisplayInfoListener> mWindowInfoListener;
    const WindowListenerRegisterConsumer mRegisterListener;
    const WindowListenerUnregisterConsumer mUnregisterListener;
};