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

Commit 4b6ad2d0 authored by Arpit Singh's avatar Arpit Singh
Browse files

Add method to mark displays secure to hide pointer indicators

In this CL adds a method to mark some displays secure, it will be used
to allow pointer controller to hide touch indicators from the mirrored
displays.

Test: atest PointerChoreographerTest
Bug: 325252005
Change-Id: Iafe7fbc62de39f9fc40119238d7404b97068516a
parent 150407d3
Loading
Loading
Loading
Loading
+99 −1
Original line number Diff line number Diff line
@@ -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"

@@ -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) {
@@ -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;

@@ -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;

@@ -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;

@@ -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;

@@ -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(
@@ -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);

@@ -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};
@@ -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);
@@ -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();
}
@@ -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) {
@@ -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
+21 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "PointerChoreographerPolicyInterface.h"

#include <android-base/thread_annotations.h>
#include <gui/WindowInfosListener.h>
#include <type_traits>

namespace android {
@@ -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;
@@ -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:
@@ -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>()>>;
+5 −0
Original line number Diff line number Diff line
@@ -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
+16 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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;
}
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <input/DisplayViewport.h>
#include <input/Input.h>
#include <utils/BitSet.h>
#include <unordered_set>

namespace android {

@@ -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);
@@ -55,6 +57,7 @@ public:
    void assertPointerIconNotSet();
    void assertCustomPointerIconSet(PointerIconStyle iconId);
    void assertCustomPointerIconNotSet();
    void assertIsHiddenOnMirroredDisplays(int32_t displayId, bool isHidden);
    bool isPointerShown();

private:
@@ -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