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

Commit e8c959f0 authored by Vishnu Nair's avatar Vishnu Nair Committed by Android (Google) Code Review
Browse files

Merge "SurfaceFlinger: Drop input for blacked out layers"

parents 401e35dd 16a938f8
Loading
Loading
Loading
Loading
+88 −13
Original line number Original line Diff line number Diff line
@@ -220,7 +220,7 @@ public:
        t.apply(true);
        t.apply(true);
    }
    }


    void requestFocus() {
    void requestFocus(int displayId = ADISPLAY_ID_DEFAULT) {
        SurfaceComposerClient::Transaction t;
        SurfaceComposerClient::Transaction t;
        FocusRequest request;
        FocusRequest request;
        request.token = mInputInfo.token;
        request.token = mInputInfo.token;
@@ -228,7 +228,7 @@ public:
        request.focusedToken = nullptr;
        request.focusedToken = nullptr;
        request.focusedWindowName = "";
        request.focusedWindowName = "";
        request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
        request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
        request.displayId = 0;
        request.displayId = displayId;
        t.setFocusedWindow(request);
        t.setFocusedWindow(request);
        t.apply(true);
        t.apply(true);
    }
    }
@@ -255,11 +255,6 @@ private:


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


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

        InputApplicationInfo aInfo;
        InputApplicationInfo aInfo;
        aInfo.token = new BBinder();
        aInfo.token = new BBinder();
        aInfo.name = "Test app info";
        aInfo.name = "Test app info";
@@ -373,23 +368,33 @@ public:
    int32_t mBufferPostDelay;
    int32_t mBufferPostDelay;
};
};


void injectTap(int x, int y) {
void injectTapOnDisplay(int x, int y, int displayId) {
    char *buf1, *buf2;
    char *buf1, *buf2, *bufDisplayId;
    asprintf(&buf1, "%d", x);
    asprintf(&buf1, "%d", x);
    asprintf(&buf2, "%d", y);
    asprintf(&buf2, "%d", y);
    asprintf(&bufDisplayId, "%d", displayId);
    if (fork() == 0) {
    if (fork() == 0) {
        execlp("input", "input", "tap", buf1, buf2, NULL);
        execlp("input", "input", "-d", bufDisplayId, "tap", buf1, buf2, NULL);
    }
    }
}
}


void injectKey(uint32_t keycode) {
void injectTap(int x, int y) {
    char *buf1;
    injectTapOnDisplay(x, y, ADISPLAY_ID_DEFAULT);
}

void injectKeyOnDisplay(uint32_t keycode, int displayId) {
    char *buf1, *bufDisplayId;
    asprintf(&buf1, "%d", keycode);
    asprintf(&buf1, "%d", keycode);
    asprintf(&bufDisplayId, "%d", displayId);
    if (fork() == 0) {
    if (fork() == 0) {
        execlp("input", "input", "keyevent", buf1, NULL);
        execlp("input", "input", "-d", bufDisplayId, "keyevent", buf1, NULL);
    }
    }
}
}


void injectKey(uint32_t keycode) {
    injectKeyOnDisplay(keycode, ADISPLAY_ID_NONE);
}

TEST_F(InputSurfacesTest, can_receive_input) {
TEST_F(InputSurfacesTest, can_receive_input) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);
    surface->showAt(100, 100);
@@ -946,4 +951,74 @@ TEST_F(InputSurfacesTest, drop_input_policy) {
    injectKey(AKEYCODE_V);
    injectKey(AKEYCODE_V);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}
}

class MultiDisplayTests : public InputSurfacesTest {
public:
    MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
    void TearDown() {
        if (mVirtualDisplay) {
            SurfaceComposerClient::destroyDisplay(mVirtualDisplay);
        }
        InputSurfacesTest::TearDown();
    }

    void createDisplay(int32_t width, int32_t height, bool isSecure, ui::LayerStack layerStack) {
        sp<IGraphicBufferConsumer> consumer;
        BufferQueue::createBufferQueue(&mProducer, &consumer);
        consumer->setConsumerName(String8("Virtual disp consumer"));
        consumer->setDefaultBufferSize(width, height);

        mVirtualDisplay = SurfaceComposerClient::createDisplay(String8("VirtualDisplay"), isSecure);
        SurfaceComposerClient::Transaction t;
        t.setDisplaySurface(mVirtualDisplay, mProducer);
        t.setDisplayFlags(mVirtualDisplay, 0x01 /* DisplayDevice::eReceivesInput */);
        t.setDisplayLayerStack(mVirtualDisplay, layerStack);
        t.apply(true);
    }

    sp<IBinder> mVirtualDisplay;
    sp<IGraphicBufferProducer> mProducer;
};

TEST_F(MultiDisplayTests, drop_input_for_secure_layer_on_nonsecure_display) {
    ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
    createDisplay(1000, 1000, false /*isSecure*/, layerStack);
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) {
        t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
        t.setLayerStack(sc, layerStack);
    });
    surface->showAt(100, 100);

    injectTap(101, 101);

    EXPECT_EQ(surface->consumeEvent(100), nullptr);

    surface->requestFocus(layerStack.id);
    surface->assertFocusChange(true);
    injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);
}

TEST_F(MultiDisplayTests, dont_drop_input_for_secure_layer_on_secure_display) {
    ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
    createDisplay(1000, 1000, true /*isSecure*/, layerStack);
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) {
        t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
        t.setLayerStack(sc, layerStack);
    });
    surface->showAt(100, 100);

    injectTapOnDisplay(101, 101, layerStack.id);
    EXPECT_NE(surface->consumeEvent(), nullptr);
    EXPECT_NE(surface->consumeEvent(), nullptr);

    surface->requestFocus(layerStack.id);
    surface->assertFocusChange(true);
    injectKeyOnDisplay(AKEYCODE_V, layerStack.id);

    surface->expectKey(AKEYCODE_V);
}

} // namespace android::test
} // namespace android::test
+8 −2
Original line number Original line Diff line number Diff line
@@ -2154,7 +2154,7 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet
    if (traceFlags & SurfaceTracing::TRACE_INPUT) {
    if (traceFlags & SurfaceTracing::TRACE_INPUT) {
        WindowInfo info;
        WindowInfo info;
        if (useDrawing) {
        if (useDrawing) {
            info = fillInputInfo(ui::Transform());
            info = fillInputInfo(ui::Transform(), /* displayIsSecure */ true);
        } else {
        } else {
            info = state.inputInfo;
            info = state.inputInfo;
        }
        }
@@ -2356,7 +2356,7 @@ void Layer::handleDropInputMode(gui::WindowInfo& info) const {
    }
    }
}
}


WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform) {
WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure) {
    if (!hasInputInfo()) {
    if (!hasInputInfo()) {
        mDrawingState.inputInfo.name = getName();
        mDrawingState.inputInfo.name = getName();
        mDrawingState.inputInfo.ownerUid = mOwnerUid;
        mDrawingState.inputInfo.ownerUid = mOwnerUid;
@@ -2385,6 +2385,12 @@ WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform) {
    fillTouchOcclusionMode(info);
    fillTouchOcclusionMode(info);
    handleDropInputMode(info);
    handleDropInputMode(info);


    // If the window will be blacked out on a display because the display does not have the secure
    // flag and the layer has the secure flag set, then drop input.
    if (!displayIsSecure && isSecure()) {
        info.inputFeatures |= WindowInfo::Feature::DROP_INPUT;
    }

    auto cropLayer = mDrawingState.touchableRegionCrop.promote();
    auto cropLayer = mDrawingState.touchableRegionCrop.promote();
    if (info.replaceTouchableRegionWithCrop) {
    if (info.replaceTouchableRegionWithCrop) {
        const Rect bounds(cropLayer ? cropLayer->mScreenBounds : mScreenBounds);
        const Rect bounds(cropLayer ? cropLayer->mScreenBounds : mScreenBounds);
+1 −1
Original line number Original line Diff line number Diff line
@@ -854,7 +854,7 @@ public:
    bool getPremultipledAlpha() const;
    bool getPremultipledAlpha() const;
    void setInputInfo(const gui::WindowInfo& info);
    void setInputInfo(const gui::WindowInfo& info);


    gui::WindowInfo fillInputInfo(const ui::Transform& displayTransform);
    gui::WindowInfo fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure);


    /**
    /**
     * Returns whether this layer has an explicitly set input-info.
     * Returns whether this layer has an explicitly set input-info.
+11 −8
Original line number Original line Diff line number Diff line
@@ -3089,16 +3089,19 @@ void SurfaceFlinger::notifyWindowInfos() {
    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
        if (!layer->needsInputInfo()) return;
        if (!layer->needsInputInfo()) return;


        const DisplayDevice* display = nullptr;
        const DisplayDevice* display = ON_MAIN_THREAD(getDisplayWithInputByLayer(layer)).get();
        if (enablePerWindowInputRotation()) {
        ui::Transform displayTransform = ui::Transform();
            display = ON_MAIN_THREAD(getDisplayWithInputByLayer(layer)).get();
        }


        if (enablePerWindowInputRotation()) {
            // When calculating the screen bounds we ignore the transparent region since it may
            // When calculating the screen bounds we ignore the transparent region since it may
            // result in an unwanted offset.
            // result in an unwanted offset.
            const auto it = displayTransforms.find(display);
            const auto it = displayTransforms.find(display);
        windowInfos.push_back(
            if (it != displayTransforms.end()) {
                layer->fillInputInfo(it != displayTransforms.end() ? it->second : ui::Transform()));
                displayTransform = it->second;
            }
        }
        const bool displayIsSecure = !display || display->isSecure();
        windowInfos.push_back(layer->fillInputInfo(displayTransform, displayIsSecure));
    });
    });
    mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos,
    mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos,
                                                    mInputWindowCommands.syncInputWindows);
                                                    mInputWindowCommands.syncInputWindows);