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

Commit 25767a01 authored by Arpit Singh's avatar Arpit Singh Committed by Android (Google) Code Review
Browse files

Merge "Add method to mark displays secure to hide pointer indicators" into main

parents d844150e 4b6ad2d0
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