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

Commit 958da934 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Request focus using setFocusedWindow

Switch from using setInputWindow to setFocusedWindow to set the focused
window for a display. setInputWindows will still handle window state
changes such as visibility and focusability which can take focus away
from the currently focused window.

This change explicitly defines how mirrored window or windows sharing a
window token handles focus. For a window to be focusable, all the
windows sharing its window token must be focusable and at least one of
the window must be visible. This different from the previous behaviour
where z-order and the state of a single window determined focus via
setInputWindows.

In addition, if focus is requested on an invisible window, the request
is queued up until the window becomes focus or a new request is made.
Any key events are queued and delivered to the new window as it becomes
focused. This allows the system to deliver any key events to the new
window between the time that the system wants to show a new window and
the window is ready to receive input.

Test: atest inputflinger_tests
Test: atest CtsWindowManagerDeviceTestCases
Test: atest FlickerTests

Change-Id: Id09cce42f55fb7d36a3eb0aa9d28f6a44bd1cf07
parent 1b66d525
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -493,6 +493,14 @@ bool InputWindowCommands::merge(const InputWindowCommands& other) {
    return changes;
}

bool InputWindowCommands::empty() const {
    bool empty = true;
#ifndef NO_INPUT
    empty = focusRequests.empty() && !syncInputWindows;
#endif
    return empty;
}

void InputWindowCommands::clear() {
#ifndef NO_INPUT
    focusRequests.clear();
+3 −1
Original line number Diff line number Diff line
@@ -1365,11 +1365,13 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInput
}

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocusedWindow(
        const sp<IBinder>& token, const sp<IBinder>& focusedToken, nsecs_t timestampNanos) {
        const sp<IBinder>& token, const sp<IBinder>& focusedToken, nsecs_t timestampNanos,
        int32_t displayId) {
    FocusRequest request;
    request.token = token;
    request.focusedToken = focusedToken;
    request.timestamp = timestampNanos;
    request.displayId = displayId;
    return setFocusedWindow(request);
}

+1 −0
Original line number Diff line number Diff line
@@ -311,6 +311,7 @@ struct InputWindowCommands {

    // Merges the passed in commands and returns true if there were any changes.
    bool merge(const InputWindowCommands& other);
    bool empty() const;
    void clear();
    status_t write(Parcel& output) const;
    status_t read(const Parcel& input);
+1 −1
Original line number Diff line number Diff line
@@ -509,7 +509,7 @@ public:
#ifndef NO_INPUT
        Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
        Transaction& setFocusedWindow(const sp<IBinder>& token, const sp<IBinder>& focusedToken,
                                      nsecs_t timestampNanos);
                                      nsecs_t timestampNanos, int32_t displayId);
        Transaction& setFocusedWindow(const FocusRequest& request);
        Transaction& syncInputWindows();
#endif
+16 −43
Original line number Diff line number Diff line
@@ -47,8 +47,7 @@

using android::os::IInputFlinger;

namespace android {
namespace test {
namespace android::test {

using Transaction = SurfaceComposerClient::Transaction;

@@ -176,6 +175,13 @@ public:
        t.apply(true);
    }

    void requestFocus() {
        SurfaceComposerClient::Transaction t;
        t.setFocusedWindow(mInputInfo.token, nullptr, systemTime(SYSTEM_TIME_MONOTONIC),
                           0 /* displayId */);
        t.apply(true);
    }

private:
    void waitForEventAvailable() {
        struct pollfd fd;
@@ -281,7 +287,6 @@ void injectTap(int x, int y) {
TEST_F(InputSurfacesTest, can_receive_input) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);
    surface->assertFocusChange(true);

    injectTap(101, 101);

@@ -297,12 +302,9 @@ TEST_F(InputSurfacesTest, can_receive_input) {
TEST_F(InputSurfacesTest, input_respects_positioning) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);
    surface->assertFocusChange(true);

    std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
    surface2->showAt(200, 200);
    surface->assertFocusChange(false);
    surface2->assertFocusChange(true);

    injectTap(201, 201);
    surface2->expectTap(1, 1);
@@ -329,16 +331,11 @@ TEST_F(InputSurfacesTest, input_respects_layering) {
    std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);

    surface->showAt(10, 10);
    surface->assertFocusChange(true);
    surface2->showAt(10, 10);
    surface->assertFocusChange(false);
    surface2->assertFocusChange(true);

    surface->doTransaction([](auto &t, auto &sc) {
         t.setLayer(sc, LAYER_BASE + 1);
    });
    surface2->assertFocusChange(false);
    surface->assertFocusChange(true);

    injectTap(11, 11);
    surface->expectTap(1, 1);
@@ -346,8 +343,6 @@ TEST_F(InputSurfacesTest, input_respects_layering) {
    surface2->doTransaction([](auto &t, auto &sc) {
         t.setLayer(sc, LAYER_BASE + 1);
    });
    surface2->assertFocusChange(true);
    surface->assertFocusChange(false);

    injectTap(11, 11);
    surface2->expectTap(1, 1);
@@ -355,8 +350,6 @@ TEST_F(InputSurfacesTest, input_respects_layering) {
    surface2->doTransaction([](auto &t, auto &sc) {
         t.hide(sc);
    });
    surface2->assertFocusChange(false);
    surface->assertFocusChange(true);

    injectTap(11, 11);
    surface->expectTap(1, 1);
@@ -369,12 +362,9 @@ TEST_F(InputSurfacesTest, input_respects_surface_insets) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    bgSurface->showAt(100, 100);
    bgSurface->assertFocusChange(true);

    fgSurface->mInputInfo.surfaceInset = 5;
    fgSurface->showAt(100, 100);
    fgSurface->assertFocusChange(true);
    bgSurface->assertFocusChange(false);

    injectTap(106, 106);
    fgSurface->expectTap(1, 1);
@@ -388,12 +378,9 @@ TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) {
    std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100);
    parentSurface->showAt(100, 100);
    parentSurface->assertFocusChange(true);

    childSurface->mInputInfo.surfaceInset = 10;
    childSurface->showAt(100, 100);
    childSurface->assertFocusChange(true);
    parentSurface->assertFocusChange(false);

    childSurface->doTransaction([&](auto &t, auto &sc) {
        t.setPosition(sc, -5, -5);
@@ -412,12 +399,9 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) {
    std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    bgSurface->showAt(100, 100);
    bgSurface->assertFocusChange(true);

    fgSurface->mInputInfo.surfaceInset = 5;
    fgSurface->showAt(100, 100);
    bgSurface->assertFocusChange(false);
    fgSurface->assertFocusChange(true);

    fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });

@@ -434,7 +418,6 @@ TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) {
    // In case we pass the very big inset without any checking.
    fgSurface->mInputInfo.surfaceInset = INT32_MAX;
    fgSurface->showAt(100, 100);
    fgSurface->assertFocusChange(true);

    fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });

@@ -451,7 +434,6 @@ TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
        t.setTransparentRegionHint(sc, transparentRegion);
    });
    surface->showAt(100, 100);
    surface->assertFocusChange(true);
    injectTap(101, 101);
    surface->expectTap(1, 1);
}
@@ -466,10 +448,7 @@ TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
            InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);

    bgSurface->showAt(10, 10);
    bgSurface->assertFocusChange(true);
    bufferSurface->showAt(10, 10);
    bgSurface->assertFocusChange(false);
    bufferSurface->assertFocusChange(true);

    injectTap(11, 11);
    bufferSurface->expectTap(1, 1);
@@ -486,10 +465,7 @@ TEST_F(InputSurfacesTest, input_ignores_buffer_layer_alpha) {
    postBuffer(bufferSurface->mSurfaceControl);

    bgSurface->showAt(10, 10);
    bgSurface->assertFocusChange(true);
    bufferSurface->showAt(10, 10);
    bufferSurface->assertFocusChange(true);
    bgSurface->assertFocusChange(false);

    injectTap(11, 11);
    bufferSurface->expectTap(1, 1);
@@ -505,10 +481,7 @@ TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) {
    std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);

    bgSurface->showAt(10, 10);
    bgSurface->assertFocusChange(true);
    fgSurface->showAt(10, 10);
    bgSurface->assertFocusChange(false);
    fgSurface->assertFocusChange(true);

    injectTap(11, 11);
    fgSurface->expectTap(1, 1);
@@ -525,17 +498,12 @@ TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
            InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);

    bgSurface->showAt(10, 10);
    bgSurface->assertFocusChange(true);
    containerSurface->showAt(10, 10);
    bgSurface->assertFocusChange(false);
    containerSurface->assertFocusChange(true);

    injectTap(11, 11);
    containerSurface->expectTap(1, 1);

    containerSurface->doTransaction([](auto &t, auto &sc) { t.hide(sc); });
    containerSurface->assertFocusChange(false);
    bgSurface->assertFocusChange(true);

    injectTap(11, 11);
    bgSurface->expectTap(1, 1);
@@ -544,7 +512,6 @@ TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
TEST_F(InputSurfacesTest, input_respects_outscreen) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(-1, -1);
    surface->assertFocusChange(true);

    injectTap(0, 0);
    surface->expectTap(1, 1);
@@ -556,11 +523,17 @@ TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
            InputSurface::makeCursorInputSurface(mComposerClient, 10, 10);

    surface->showAt(10, 10);
    surface->assertFocusChange(true);
    cursorSurface->showAt(10, 10);

    injectTap(11, 11);
    surface->expectTap(1, 1);
}

TEST_F(InputSurfacesTest, can_be_focused) {
    std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    surface->showAt(100, 100);
    surface->requestFocus();

    surface->assertFocusChange(true);
}
}
} // namespace android::test
Loading