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

Commit c7df484a authored by Linus Tufvesson's avatar Linus Tufvesson
Browse files

Allow windowhandles with NO_INPUT_CHANNEL - DO NOT MERGE

This allows container surfaces to be considered visible in
InputDispatcher and prevent touches from passing through them. In
particular this is used by ActivityRecordInputSink to block touches that
would otherwise pass through the area available to the activity.

Bug: 194480991
Bug: 222292477
Test: Manually tested that blocking still works
Test: atest InputSurfacesTest
Change-Id: Iacfc952139311363b914b1d6bffc2b4190133d02
(cherry picked from commit a1858820)
parent c9aeff39
Loading
Loading
Loading
Loading
+59 −34
Original line number Diff line number Diff line
@@ -66,17 +66,40 @@ static const int LAYER_BASE = INT32_MAX - 10;

class InputSurface {
public:
    InputSurface(const sp<SurfaceControl> &sc, int width, int height) {
    InputSurface(const sp<SurfaceControl> &sc, int width, int height, bool noInputChannel = false) {
        mSurfaceControl = sc;

        InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel);

        mInputFlinger = getInputFlinger();
        if (noInputChannel) {
            mInputInfo.inputFeatures = InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
        } else {
            InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel);
            mInputFlinger->registerInputChannel(mServerChannel);
            mInputInfo.token = mServerChannel->getConnectionToken();
            mInputConsumer = new InputConsumer(mClientChannel);
        }

        populateInputInfo(width, height);
        mInputInfo.name = "Test info";
        mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
        mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION;
        mInputInfo.dispatchingTimeout = seconds_to_nanoseconds(5);
        mInputInfo.globalScaleFactor = 1.0;
        mInputInfo.canReceiveKeys = true;
        mInputInfo.hasFocus = true;
        mInputInfo.hasWallpaper = false;
        mInputInfo.paused = false;
        mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
        // TODO: Fill in from SF?
        mInputInfo.ownerPid = 11111;
        mInputInfo.ownerUid = 11111;
        mInputInfo.inputFeatures = 0;
        mInputInfo.displayId = 0;

        mInputConsumer = new InputConsumer(mClientChannel);
        InputApplicationInfo aInfo;
        aInfo.token = new BBinder();
        aInfo.name = "Test app info";
        aInfo.dispatchingTimeout = seconds_to_nanoseconds(5);
        mInputInfo.applicationInfo = aInfo;
    }

    static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient> &scc,
@@ -105,6 +128,16 @@ public:
        return std::make_unique<InputSurface>(surfaceControl, width, height);
    }

    static std::unique_ptr<InputSurface> makeContainerInputSurfaceNoInputChannel(
            const sp<SurfaceComposerClient> &scc, int width, int height) {
        sp<SurfaceControl> surfaceControl =
                scc->createSurface(String8("Test Container Surface"), 0 /* bufHeight */,
                                   0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
                                   ISurfaceComposerClient::eFXSurfaceContainer);
        return std::make_unique<InputSurface>(surfaceControl, width, height,
                                              true /* noInputChannel */);
    }

    static std::unique_ptr<InputSurface> makeCursorInputSurface(
            const sp<SurfaceComposerClient> &scc, int width, int height) {
        sp<SurfaceControl> surfaceControl =
@@ -173,8 +206,10 @@ public:
    }

    ~InputSurface() {
        if (mInputInfo.token) {
            mInputFlinger->unregisterInputChannel(mServerChannel);
        }
    }

    void doTransaction(std::function<void(SurfaceComposerClient::Transaction&,
                    const sp<SurfaceControl>&)> transactionBody) {
@@ -203,33 +238,6 @@ private:
        poll(&fd, 1, timeoutMs);
    }

    void populateInputInfo(int width, int height) {
        mInputInfo.token = mServerChannel->getConnectionToken();
        mInputInfo.name = "Test info";
        mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
        mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION;
        mInputInfo.dispatchingTimeout = seconds_to_nanoseconds(5);
        mInputInfo.globalScaleFactor = 1.0;
        mInputInfo.canReceiveKeys = true;
        mInputInfo.hasFocus = true;
        mInputInfo.hasWallpaper = false;
        mInputInfo.paused = false;

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

        // TODO: Fill in from SF?
        mInputInfo.ownerPid = 11111;
        mInputInfo.ownerUid = 11111;
        mInputInfo.inputFeatures = 0;
        mInputInfo.displayId = 0;

        InputApplicationInfo aInfo;
        aInfo.token = new BBinder();
        aInfo.name = "Test app info";
        aInfo.dispatchingTimeout = seconds_to_nanoseconds(5);

        mInputInfo.applicationInfo = aInfo;
    }
public:
    sp<SurfaceControl> mSurfaceControl;
    sp<InputChannel> mServerChannel, mClientChannel;
@@ -589,6 +597,23 @@ TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
    surface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, child_container_with_no_input_channel_blocks_parent) {
    std::unique_ptr<InputSurface> parent = makeSurface(100, 100);
    parent->showAt(100, 100);
    parent->assertFocusChange(true);
    injectTap(101, 101);
    parent->expectTap(1, 1);

    std::unique_ptr<InputSurface> childContainerSurface =
            InputSurface::makeContainerInputSurfaceNoInputChannel(mComposerClient, 100, 100);
    childContainerSurface->showAt(0, 0);
    childContainerSurface->doTransaction(
            [&](auto &t, auto &sc) { t.reparent(sc, parent->mSurfaceControl->getHandle()); });
    injectTap(101, 101);

    EXPECT_EQ(parent->consumeEvent(100), nullptr);
}

TEST_F(InputSurfacesTest, drop_input_policy) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction(
+2 −1
Original line number Diff line number Diff line
@@ -2514,7 +2514,8 @@ sp<Layer> Layer::getClonedRoot() {
}

bool Layer::hasInputInfo() const {
    return mDrawingState.inputInfo.token != nullptr;
    return mDrawingState.inputInfo.token != nullptr ||
            mDrawingState.inputInfo.inputFeatures & InputWindowInfo::INPUT_FEATURE_NO_INPUT_CHANNEL;
}

bool Layer::canReceiveInput() const {