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

Commit dc70e405 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Introduce WindowInfo::InputConfig flag to control input behavior"

parents 17b449fc 4d5c52ff
Loading
Loading
Loading
Loading
+31 −28
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@
#define LOG_TAG "WindowInfo"
#define LOG_NDEBUG 0

#include <android-base/stringprintf.h>
#include <binder/Parcel.h>
#include <gui/WindowInfo.h>

@@ -27,6 +26,14 @@
namespace android::gui {

// --- WindowInfo ---
void WindowInfo::setInputConfig(Flags<InputConfig> config, bool value) {
    if (value) {
        inputConfig |= config;
        return;
    }
    inputConfig &= ~config;
}

void WindowInfo::addTouchableRegion(const Rect& region) {
    touchableRegion.orSelf(region);
}
@@ -40,7 +47,7 @@ bool WindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
}

bool WindowInfo::supportsSplitTouch() const {
    return flags.test(Flag::SPLIT_TOUCH);
    return inputConfig.test(InputConfig::SPLIT_TOUCH);
}

bool WindowInfo::isSpy() const {
@@ -58,20 +65,19 @@ bool WindowInfo::overlaps(const WindowInfo* other) const {
}

bool WindowInfo::operator==(const WindowInfo& info) const {
    return info.token == token && info.id == id && info.name == name && info.flags == flags &&
            info.type == type && info.dispatchingTimeout == dispatchingTimeout &&
            info.frameLeft == frameLeft && info.frameTop == frameTop &&
            info.frameRight == frameRight && info.frameBottom == frameBottom &&
            info.surfaceInset == surfaceInset && info.globalScaleFactor == globalScaleFactor &&
            info.transform == transform && info.touchableRegion.hasSameRects(touchableRegion) &&
            info.visible == visible && info.trustedOverlay == trustedOverlay &&
            info.focusable == focusable && info.touchOcclusionMode == touchOcclusionMode &&
            info.hasWallpaper == hasWallpaper && info.paused == paused &&
            info.ownerPid == ownerPid && info.ownerUid == ownerUid &&
            info.packageName == packageName && info.inputFeatures == inputFeatures &&
    return info.token == token && info.id == id && info.name == name &&
            info.dispatchingTimeout == dispatchingTimeout && info.frameLeft == frameLeft &&
            info.frameTop == frameTop && info.frameRight == frameRight &&
            info.frameBottom == frameBottom && info.surfaceInset == surfaceInset &&
            info.globalScaleFactor == globalScaleFactor && info.transform == transform &&
            info.touchableRegion.hasSameRects(touchableRegion) &&
            info.touchOcclusionMode == touchOcclusionMode && info.ownerPid == ownerPid &&
            info.ownerUid == ownerUid && info.packageName == packageName &&
            info.inputFeatures == inputFeatures && info.inputConfig == inputConfig &&
            info.displayId == displayId &&
            info.replaceTouchableRegionWithCrop == replaceTouchableRegionWithCrop &&
            info.applicationInfo == applicationInfo;
            info.applicationInfo == applicationInfo && info.layoutParamsType == layoutParamsType &&
            info.layoutParamsFlags == layoutParamsFlags;
}

status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
@@ -85,13 +91,18 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
    }
    parcel->writeInt32(1);

    // Ensure that the size of the flags that we use is 32 bits for writing into the parcel.
    static_assert(sizeof(inputFeatures) == 4u);
    static_assert(sizeof(inputConfig) == 4u);

    // clang-format off
    status_t status = parcel->writeStrongBinder(token) ?:
        parcel->writeInt64(dispatchingTimeout.count()) ?:
        parcel->writeInt32(id) ?:
        parcel->writeUtf8AsUtf16(name) ?:
        parcel->writeInt32(flags.get()) ?:
        parcel->writeInt32(static_cast<std::underlying_type_t<WindowInfo::Type>>(type)) ?:
        parcel->writeInt32(layoutParamsFlags.get()) ?:
        parcel->writeInt32(
                static_cast<std::underlying_type_t<WindowInfo::Type>>(layoutParamsType)) ?:
        parcel->writeInt32(frameLeft) ?:
        parcel->writeInt32(frameTop) ?:
        parcel->writeInt32(frameRight) ?:
@@ -105,16 +116,12 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
        parcel->writeFloat(transform.dtdy()) ?:
        parcel->writeFloat(transform.dsdy()) ?:
        parcel->writeFloat(transform.ty()) ?:
        parcel->writeBool(visible) ?:
        parcel->writeBool(focusable) ?:
        parcel->writeBool(hasWallpaper) ?:
        parcel->writeBool(paused) ?:
        parcel->writeBool(trustedOverlay) ?:
        parcel->writeInt32(static_cast<int32_t>(touchOcclusionMode)) ?:
        parcel->writeInt32(ownerPid) ?:
        parcel->writeInt32(ownerUid) ?:
        parcel->writeUtf8AsUtf16(packageName) ?:
        parcel->writeInt32(inputFeatures.get()) ?:
        parcel->writeInt32(inputConfig.get()) ?:
        parcel->writeInt32(displayId) ?:
        applicationInfo.writeToParcel(parcel) ?:
        parcel->write(touchableRegion) ?:
@@ -141,8 +148,8 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
        return status;
    }

    flags = Flags<Flag>(parcel->readInt32());
    type = static_cast<Type>(parcel->readInt32());
    layoutParamsFlags = Flags<Flag>(parcel->readInt32());
    layoutParamsType = static_cast<Type>(parcel->readInt32());
    float dsdx, dtdx, tx, dtdy, dsdy, ty;
    int32_t touchOcclusionModeInt;
    // clang-format off
@@ -159,11 +166,6 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
        parcel->readFloat(&dtdy) ?:
        parcel->readFloat(&dsdy) ?:
        parcel->readFloat(&ty) ?:
        parcel->readBool(&visible) ?:
        parcel->readBool(&focusable) ?:
        parcel->readBool(&hasWallpaper) ?:
        parcel->readBool(&paused) ?:
        parcel->readBool(&trustedOverlay) ?:
        parcel->readInt32(&touchOcclusionModeInt) ?:
        parcel->readInt32(&ownerPid) ?:
        parcel->readInt32(&ownerUid) ?:
@@ -177,6 +179,7 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
    touchOcclusionMode = static_cast<TouchOcclusionMode>(touchOcclusionModeInt);

    inputFeatures = Flags<Feature>(parcel->readInt32());
    inputConfig = Flags<InputConfig>(parcel->readInt32());
    // clang-format off
    status = parcel->readInt32(&displayId) ?:
        applicationInfo.readFromParcel(parcel) ?:
+36 −12
Original line number Diff line number Diff line
@@ -151,6 +151,34 @@ struct WindowInfo : public Parcelable {
        // clang-format on
    };

    // Flags used to determine configuration of this input window.
    // Input windows can be configured with two sets of flags: InputFeature (WindowInfo::Feature
    // defined above), and InputConfig. When adding a new configuration for an input window:
    //   - If you are adding a new flag that's visible and accessible to apps, it should be added
    //   as an InputFeature.
    //   - If you are adding an internal behaviour that is used within the system or shell and is
    //   not exposed to apps, it should be added as an InputConfig.
    enum class InputConfig : uint32_t {
        // clang-format off
        NONE                         = 0,
        NOT_VISIBLE                  = 1 << 0,
        NOT_FOCUSABLE                = 1 << 1,
        NOT_TOUCHABLE                = 1 << 2,
        NOT_TOUCH_MODAL              = 1 << 3,
        SPLIT_TOUCH                  = 1 << 4,
        DUPLICATE_TOUCH_TO_WALLPAPER = 1 << 5,
        IS_WALLPAPER                 = 1 << 6,
        PAUSE_DISPATCHING            = 1 << 7,
        // This flag is set when the window is of a trusted type that is allowed to silently
        // overlay other windows for the purpose of implementing the secure views feature.
        // Trusted overlays, such as IME windows, can partly obscure other windows without causing
        // motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
        TRUSTED_OVERLAY              = 1 << 8,
        WATCH_OUTSIDE_TOUCH          = 1 << 9,
        SLIPPERY                     = 1 << 10,
        // clang-format on
    };

    /* These values are filled in by the WM and passed through SurfaceFlinger
     * unless specified otherwise.
     */
@@ -164,8 +192,6 @@ struct WindowInfo : public Parcelable {
    // This uniquely identifies the input window.
    int32_t id = -1;
    std::string name;
    Flags<Flag> flags;
    Type type = Type::UNKNOWN;
    std::chrono::nanoseconds dispatchingTimeout = std::chrono::seconds(5);

    /* These values are filled in by SurfaceFlinger. */
@@ -198,26 +224,24 @@ struct WindowInfo : public Parcelable {
     * to absolute coordinates by SurfaceFlinger once the frame is computed.
     */
    Region touchableRegion;
    bool visible = false;
    bool focusable = false;
    bool hasWallpaper = false;
    bool paused = false;
    /* This flag is set when the window is of a trusted type that is allowed to silently
     * overlay other windows for the purpose of implementing the secure views feature.
     * Trusted overlays, such as IME windows, can partly obscure other windows without causing
     * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
     */
    bool trustedOverlay = false;

    TouchOcclusionMode touchOcclusionMode = TouchOcclusionMode::BLOCK_UNTRUSTED;
    int32_t ownerPid = -1;
    int32_t ownerUid = -1;
    std::string packageName;
    Flags<Feature> inputFeatures;
    Flags<InputConfig> inputConfig;
    int32_t displayId = ADISPLAY_ID_NONE;
    InputApplicationInfo applicationInfo;
    bool replaceTouchableRegionWithCrop = false;
    wp<IBinder> touchableRegionCropHandle;

    // The window's layout params flags and type set by WM.
    Type layoutParamsType = Type::UNKNOWN;
    Flags<Flag> layoutParamsFlags;

    void setInputConfig(Flags<InputConfig> config, bool value);

    void addTouchableRegion(const Rect& region);

    bool touchableRegionContainsPoint(int32_t x, int32_t y) const;
+11 −14
Original line number Diff line number Diff line
@@ -266,13 +266,10 @@ private:
    void populateInputInfo(int width, int height) {
        mInputInfo.token = mClientChannel->getConnectionToken();
        mInputInfo.name = "Test info";
        mInputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL;
        mInputInfo.type = WindowInfo::Type::BASE_APPLICATION;
        mInputInfo.dispatchingTimeout = 5s;
        mInputInfo.globalScaleFactor = 1.0;
        mInputInfo.focusable = true;
        mInputInfo.hasWallpaper = false;
        mInputInfo.paused = false;
        mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCH_MODAL, true);
        mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_VISIBLE, false);

        mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));

@@ -750,7 +747,7 @@ TEST_F(InputSurfacesTest, touch_flag_obscured) {
    // Add non touchable window to fully cover touchable window. Window behind gets touch, but
    // with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
    std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
    nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
    nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    nonTouchableSurface->mInputInfo.ownerUid = 22222;
    // Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
    // the default obscured/untrusted touch filter introduced in S.
@@ -770,8 +767,8 @@ TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) {
    // AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
    std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
    nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
    parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
    nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    nonTouchableSurface->mInputInfo.ownerUid = 22222;
    parentSurface->mInputInfo.ownerUid = 22222;
    nonTouchableSurface->showAt(0, 0);
@@ -794,8 +791,8 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) {
    // the touchable window. Window behind gets touch with no obscured flags.
    std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
    nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
    parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
    nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    nonTouchableSurface->mInputInfo.ownerUid = 22222;
    parentSurface->mInputInfo.ownerUid = 22222;
    nonTouchableSurface->showAt(0, 0);
@@ -815,7 +812,7 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) {

    std::unique_ptr<InputSurface> bufferSurface =
            InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
    bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
    bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    bufferSurface->mInputInfo.ownerUid = 22222;

    surface->showAt(10, 10);
@@ -830,7 +827,7 @@ TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {

    std::unique_ptr<BlastInputSurface> bufferSurface =
            BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
    bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
    bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    bufferSurface->mInputInfo.ownerUid = 22222;

    surface->showAt(10, 10);
@@ -883,7 +880,7 @@ TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) {
            [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
    surface->showAt(100, 100);
    std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
    obscuringSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
    obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    obscuringSurface->mInputInfo.ownerUid = 22222;
    obscuringSurface->showAt(100, 100);
    injectTap(101, 101);
@@ -902,7 +899,7 @@ TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) {
            [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
    surface->showAt(100, 100);
    std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
    obscuringSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
    obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
    obscuringSurface->mInputInfo.ownerUid = 22222;
    obscuringSurface->showAt(190, 190);

+6 −12
Original line number Diff line number Diff line
@@ -49,8 +49,8 @@ TEST(WindowInfo, Parcelling) {
    i.windowToken = new BBinder();
    i.id = 1;
    i.name = "Foobar";
    i.flags = WindowInfo::Flag::SLIPPERY;
    i.type = WindowInfo::Type::INPUT_METHOD;
    i.layoutParamsFlags = WindowInfo::Flag::SLIPPERY;
    i.layoutParamsType = WindowInfo::Type::INPUT_METHOD;
    i.dispatchingTimeout = 12s;
    i.frameLeft = 93;
    i.frameTop = 34;
@@ -60,15 +60,12 @@ TEST(WindowInfo, Parcelling) {
    i.globalScaleFactor = 0.3;
    i.alpha = 0.7;
    i.transform.set({0.4, -1, 100, 0.5, 0, 40, 0, 0, 1});
    i.visible = false;
    i.focusable = false;
    i.hasWallpaper = false;
    i.paused = false;
    i.touchOcclusionMode = TouchOcclusionMode::ALLOW;
    i.ownerPid = 19;
    i.ownerUid = 24;
    i.packageName = "com.example.package";
    i.inputFeatures = WindowInfo::Feature::DISABLE_USER_ACTIVITY;
    i.inputConfig = WindowInfo::InputConfig::NOT_FOCUSABLE;
    i.displayId = 34;
    i.replaceTouchableRegionWithCrop = true;
    i.touchableRegionCropHandle = touchableRegionCropHandle;
@@ -85,8 +82,8 @@ TEST(WindowInfo, Parcelling) {
    ASSERT_EQ(i.windowToken, i2.windowToken);
    ASSERT_EQ(i.id, i2.id);
    ASSERT_EQ(i.name, i2.name);
    ASSERT_EQ(i.flags, i2.flags);
    ASSERT_EQ(i.type, i2.type);
    ASSERT_EQ(i.layoutParamsFlags, i2.layoutParamsFlags);
    ASSERT_EQ(i.layoutParamsType, i2.layoutParamsType);
    ASSERT_EQ(i.dispatchingTimeout, i2.dispatchingTimeout);
    ASSERT_EQ(i.frameLeft, i2.frameLeft);
    ASSERT_EQ(i.frameTop, i2.frameTop);
@@ -96,15 +93,12 @@ TEST(WindowInfo, Parcelling) {
    ASSERT_EQ(i.globalScaleFactor, i2.globalScaleFactor);
    ASSERT_EQ(i.alpha, i2.alpha);
    ASSERT_EQ(i.transform, i2.transform);
    ASSERT_EQ(i.visible, i2.visible);
    ASSERT_EQ(i.focusable, i2.focusable);
    ASSERT_EQ(i.hasWallpaper, i2.hasWallpaper);
    ASSERT_EQ(i.paused, i2.paused);
    ASSERT_EQ(i.touchOcclusionMode, i2.touchOcclusionMode);
    ASSERT_EQ(i.ownerPid, i2.ownerPid);
    ASSERT_EQ(i.ownerUid, i2.ownerUid);
    ASSERT_EQ(i.packageName, i2.packageName);
    ASSERT_EQ(i.inputFeatures, i2.inputFeatures);
    ASSERT_EQ(i.inputConfig, i2.inputConfig);
    ASSERT_EQ(i.displayId, i2.displayId);
    ASSERT_EQ(i.replaceTouchableRegionWithCrop, i2.replaceTouchableRegionWithCrop);
    ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle);
+0 −5
Original line number Diff line number Diff line
@@ -193,7 +193,6 @@ public:
    void updateInfo() {
        mInfo.token = mClientChannel->getConnectionToken();
        mInfo.name = "FakeWindowHandle";
        mInfo.type = WindowInfo::Type::APPLICATION;
        mInfo.dispatchingTimeout = DISPATCHING_TIMEOUT;
        mInfo.frameLeft = mFrame.left;
        mInfo.frameTop = mFrame.top;
@@ -202,10 +201,6 @@ public:
        mInfo.globalScaleFactor = 1.0;
        mInfo.touchableRegion.clear();
        mInfo.addTouchableRegion(mFrame);
        mInfo.visible = true;
        mInfo.focusable = true;
        mInfo.hasWallpaper = false;
        mInfo.paused = false;
        mInfo.ownerPid = INJECTOR_PID;
        mInfo.ownerUid = INJECTOR_UID;
        mInfo.displayId = ADISPLAY_ID_DEFAULT;
Loading