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

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

Merge changes Ib7e34368,I444cf8c5

* changes:
  Reland: Send WindowInfo even if the window isn't associated with a DisplayDevice
  Reland: InputDispatcher: Allow all windows to be removed from a display
parents 45d65e7d da0f62ce
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -1184,18 +1184,23 @@ public:
    std::vector<sp<IGraphicBufferProducer>> mProducers;
};

TEST_F(MultiDisplayTests, drop_input_if_layer_on_invalid_display) {
TEST_F(MultiDisplayTests, drop_touch_if_layer_on_invalid_display) {
    ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
    // Do not create a display associated with the LayerStack.
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
    surface->showAt(100, 100);

    // Touches should be dropped if the layer is on an invalid display.
    injectTapOnDisplay(101, 101, layerStack.id);
    EXPECT_EQ(surface->consumeEvent(100), nullptr);

    // However, we still let the window be focused and receive keys.
    surface->requestFocus(layerStack.id);
    injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
    surface->assertFocusChange(true);

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

TEST_F(MultiDisplayTests, virtual_display_receives_input) {
+7 −0
Original line number Diff line number Diff line
@@ -6372,6 +6372,13 @@ void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& window

    { // acquire lock
        std::scoped_lock _l(mLock);

        // Ensure that we have an entry created for all existing displays so that if a displayId has
        // no windows, we can tell that the windows were removed from the display.
        for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
            handlesPerDisplay[displayId];
        }

        mDisplayInfos.clear();
        for (const auto& displayInfo : displayInfos) {
            mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
+29 −0
Original line number Diff line number Diff line
@@ -2370,6 +2370,35 @@ TEST_F(InputDispatcherTest, ActionOutsideSentOnlyWhenAWindowIsTouched) {
    thirdWindow->consumeMotionDown();
}

TEST_F(InputDispatcherTest, OnWindowInfosChanged_RemoveAllWindowsOnDisplay) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> window =
            new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
    window->setFocusable(true);

    mDispatcher->onWindowInfosChanged({*window->getInfo()}, {});
    setFocusedWindow(window);

    window->consumeFocusEvent(true);

    NotifyKeyArgs keyDown = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
    NotifyKeyArgs keyUp = generateKeyArgs(AKEY_EVENT_ACTION_UP, ADISPLAY_ID_DEFAULT);
    mDispatcher->notifyKey(&keyDown);
    mDispatcher->notifyKey(&keyUp);

    window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
    window->consumeKeyUp(ADISPLAY_ID_DEFAULT);

    // All windows are removed from the display. Ensure that we can no longer dispatch to it.
    mDispatcher->onWindowInfosChanged({}, {});

    window->consumeFocusEvent(false);

    mDispatcher->notifyKey(&keyDown);
    mDispatcher->notifyKey(&keyUp);
    window->assertNoEvents();
}

/**
 * Ensure the correct coordinate spaces are used by InputDispatcher.
 *
+14 −3
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@
namespace android {
namespace {
constexpr int kDumpTableRowLength = 159;
const ui::Transform kIdentityTransform;
} // namespace

using namespace ftl::flag_operators;
@@ -2209,7 +2210,8 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet
    if ((traceFlags & LayerTracing::TRACE_INPUT) && needsInputInfo()) {
        WindowInfo info;
        if (useDrawing) {
            info = fillInputInfo(ui::Transform(), /* displayIsSecure */ true);
            info = fillInputInfo(
                    InputDisplayArgs{.transform = &kIdentityTransform, .isSecure = true});
        } else {
            info = state.inputInfo;
        }
@@ -2416,7 +2418,7 @@ void Layer::handleDropInputMode(gui::WindowInfo& info) const {
    }
}

WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure) {
WindowInfo Layer::fillInputInfo(const InputDisplayArgs& displayArgs) {
    if (!hasInputInfo()) {
        mDrawingState.inputInfo.name = getName();
        mDrawingState.inputInfo.ownerUid = mOwnerUid;
@@ -2425,12 +2427,21 @@ WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool disp
        mDrawingState.inputInfo.displayId = getLayerStack().id;
    }

    const ui::Transform& displayTransform =
            displayArgs.transform != nullptr ? *displayArgs.transform : kIdentityTransform;

    WindowInfo info = mDrawingState.inputInfo;
    info.id = sequence;
    info.displayId = getLayerStack().id;

    fillInputFrameInfo(info, displayTransform);

    if (displayArgs.transform == nullptr) {
        // Do not let the window receive touches if it is not associated with a valid display
        // transform. We still allow the window to receive keys and prevent ANRs.
        info.inputConfig |= WindowInfo::InputConfig::NOT_TOUCHABLE;
    }

    // For compatibility reasons we let layers which can receive input
    // receive input before they have actually submitted a buffer. Because
    // of this we use canReceiveInput instead of isVisible to check the
@@ -2448,7 +2459,7 @@ WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool disp

    // 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()) {
    if (!displayArgs.isSecure && isSecure()) {
        info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT;
    }

+5 −1
Original line number Diff line number Diff line
@@ -854,7 +854,11 @@ public:
    bool getPremultipledAlpha() const;
    void setInputInfo(const gui::WindowInfo& info);

    gui::WindowInfo fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure);
    struct InputDisplayArgs {
        const ui::Transform* transform = nullptr;
        bool isSecure = false;
    };
    gui::WindowInfo fillInputInfo(const InputDisplayArgs& displayArgs);

    /**
     * Returns whether this layer has an explicitly set input-info.
Loading