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

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

Merge "Move focus dispatch to input (1/2)"

parents 1f73350c f1035d4f
Loading
Loading
Loading
Loading
+61 −7
Original line number Diff line number Diff line
@@ -112,22 +112,31 @@ public:
        if (consumed != OK) {
            return nullptr;
        }
        mInputConsumer->sendFinishedSignal(seqId, true);
        status_t status = mInputConsumer->sendFinishedSignal(seqId, true);
        EXPECT_EQ(OK, status) << "Could not send finished signal";
        return ev;
    }

    void assertFocusChange(bool hasFocus) {
        InputEvent *ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, ev->getType());
        FocusEvent *focusEvent = static_cast<FocusEvent *>(ev);
        EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
    }

    void expectTap(int x, int y) {
        InputEvent* ev = consumeEvent();
        EXPECT_TRUE(ev != nullptr);
        EXPECT_TRUE(ev->getType() == AINPUT_EVENT_TYPE_MOTION);
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
        MotionEvent* mev = static_cast<MotionEvent*>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
        EXPECT_EQ(x, mev->getX(0));
        EXPECT_EQ(y, mev->getY(0));

        ev = consumeEvent();
        EXPECT_TRUE(ev != nullptr);
        EXPECT_TRUE(ev->getType() == AINPUT_EVENT_TYPE_MOTION);
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
        mev = static_cast<MotionEvent*>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
    }
@@ -212,7 +221,7 @@ public:
        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());

        const auto display = mComposerClient->getInternalDisplayToken();
        ASSERT_FALSE(display == nullptr);
        ASSERT_NE(display, nullptr);

        DisplayInfo info;
        ASSERT_EQ(NO_ERROR, mComposerClient->getDisplayInfo(display, &info));
@@ -259,18 +268,28 @@ 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);

    EXPECT_TRUE(surface->consumeEvent() != nullptr);
    EXPECT_NE(surface->consumeEvent(), nullptr);
}

/**
 * Set up two surfaces side-by-side. Tap each surface.
 * Next, swap the positions of the two surfaces. Inject tap into the two
 * original locations. Ensure that the tap is received by the surfaces in the
 * reverse order.
 */
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);
@@ -297,11 +316,16 @@ 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);
@@ -309,6 +333,8 @@ 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);
@@ -316,6 +342,8 @@ 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);
@@ -328,9 +356,12 @@ 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);
@@ -344,9 +375,12 @@ 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);
@@ -365,9 +399,12 @@ 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); });

@@ -384,6 +421,7 @@ 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); });

@@ -400,6 +438,7 @@ 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);
}
@@ -414,7 +453,10 @@ 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);
@@ -431,7 +473,10 @@ 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);
@@ -447,7 +492,10 @@ 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);
@@ -464,12 +512,17 @@ 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);
@@ -478,6 +531,7 @@ 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);
+15 −0
Original line number Diff line number Diff line
@@ -111,6 +111,21 @@ void DeviceResetEntry::appendDescription(std::string& msg) const {
    msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
}

// --- FocusEntry ---

// Focus notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries
FocusEntry::FocusEntry(uint32_t sequenceNum, nsecs_t eventTime, sp<IBinder> connectionToken,
                       bool hasFocus)
      : EventEntry(sequenceNum, Type::FOCUS, eventTime, POLICY_FLAG_PASS_TO_USER),
        connectionToken(connectionToken),
        hasFocus(hasFocus) {}

FocusEntry::~FocusEntry() {}

void FocusEntry::appendDescription(std::string& msg) const {
    msg += StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
}

// --- KeyEntry ---

KeyEntry::KeyEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
+20 −1
Original line number Diff line number Diff line
@@ -33,7 +33,13 @@ namespace android::inputdispatcher {
constexpr uint32_t SYNTHESIZED_EVENT_SEQUENCE_NUM = 0;

struct EventEntry {
    enum class Type { CONFIGURATION_CHANGED, DEVICE_RESET, KEY, MOTION };
    enum class Type {
        CONFIGURATION_CHANGED,
        DEVICE_RESET,
        FOCUS,
        KEY,
        MOTION,
    };

    static const char* typeToString(Type type) {
        switch (type) {
@@ -41,6 +47,8 @@ struct EventEntry {
                return "CONFIGURATION_CHANGED";
            case Type::DEVICE_RESET:
                return "DEVICE_RESET";
            case Type::FOCUS:
                return "FOCUS";
            case Type::KEY:
                return "KEY";
            case Type::MOTION:
@@ -102,6 +110,17 @@ protected:
    virtual ~DeviceResetEntry();
};

struct FocusEntry : EventEntry {
    sp<IBinder> connectionToken;
    bool hasFocus;

    FocusEntry(uint32_t sequenceNum, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus);
    virtual void appendDescription(std::string& msg) const;

protected:
    virtual ~FocusEntry();
};

struct KeyEntry : EventEntry {
    int32_t deviceId;
    uint32_t source;
+53 −1
Original line number Diff line number Diff line
@@ -530,6 +530,14 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
            break;
        }

        case EventEntry::Type::FOCUS: {
            FocusEntry* typedEntry = static_cast<FocusEntry*>(mPendingEvent);
            dispatchFocusLocked(currentTime, typedEntry);
            done = true;
            dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
            break;
        }

        case EventEntry::Type::KEY: {
            KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
            if (isAppSwitchDue) {
@@ -634,7 +642,8 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
            break;
        }
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET: {
        case EventEntry::Type::DEVICE_RESET:
        case EventEntry::Type::FOCUS: {
            // nothing to do
            break;
        }
@@ -773,6 +782,7 @@ void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason
            }
            break;
        }
        case EventEntry::Type::FOCUS:
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET: {
            LOG_ALWAYS_FATAL("Should not drop %s events", EventEntry::typeToString(entry.type));
@@ -933,6 +943,25 @@ bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceReset
    return true;
}

void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) {
    FocusEntry* focusEntry =
            new FocusEntry(SYNTHESIZED_EVENT_SEQUENCE_NUM, now(), window.getToken(), hasFocus);
    enqueueInboundEventLocked(focusEntry);
}

void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) {
    sp<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
    if (channel == nullptr) {
        return; // Window has gone away
    }
    InputTarget target;
    target.inputChannel = channel;
    target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
    entry->dispatchInProgress = true;

    dispatchEventLocked(currentTime, entry, {target});
}

bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
                                        DropReason* dropReason, nsecs_t* nextWakeupTime) {
    // Preprocessing.
@@ -1315,6 +1344,7 @@ int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
            displayId = motionEntry.displayId;
            break;
        }
        case EventEntry::Type::FOCUS:
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET: {
            ALOGE("%s events do not have a target display", EventEntry::typeToString(entry.type));
@@ -2062,6 +2092,10 @@ std::string InputDispatcher::getApplicationWindowLabel(
}

void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
    if (eventEntry.type == EventEntry::Type::FOCUS) {
        // Focus events are passed to apps, but do not represent user activity.
        return;
    }
    int32_t displayId = getTargetDisplayId(eventEntry);
    sp<InputWindowHandle> focusedWindowHandle =
            getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
@@ -2096,6 +2130,7 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
            eventType = USER_ACTIVITY_EVENT_BUTTON;
            break;
        }
        case EventEntry::Type::FOCUS:
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET: {
            LOG_ALWAYS_FATAL("%s events are not user activity",
@@ -2292,6 +2327,9 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio

            break;
        }
        case EventEntry::Type::FOCUS: {
            break;
        }
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET: {
            LOG_ALWAYS_FATAL("%s events should not go to apps",
@@ -2427,6 +2465,14 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                reportTouchEventForStatistics(*motionEntry);
                break;
            }
            case EventEntry::Type::FOCUS: {
                FocusEntry* focusEntry = static_cast<FocusEntry*>(eventEntry);
                status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
                                                                      focusEntry->hasFocus,
                                                                      mInTouchMode);
                break;
            }

            case EventEntry::Type::CONFIGURATION_CHANGED:
            case EventEntry::Type::DEVICE_RESET: {
                LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
@@ -2666,6 +2712,10 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
                                                     *cancelationEventEntry));
                    break;
                }
                case EventEntry::Type::FOCUS: {
                    LOG_ALWAYS_FATAL("Canceling focus events is not supported");
                    break;
                }
                case EventEntry::Type::CONFIGURATION_CHANGED:
                case EventEntry::Type::DEVICE_RESET: {
                    LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
@@ -3456,6 +3506,7 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>&
                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
                                               "focus left window");
                    synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
                    enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
                }
                mFocusedWindowHandlesByDisplay.erase(displayId);
            }
@@ -3465,6 +3516,7 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>&
                          newFocusedWindowHandle->getName().c_str(), displayId);
                }
                mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
                enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
            }

            if (mFocusedDisplayId == displayId) {
+4 −0
Original line number Diff line number Diff line
@@ -157,6 +157,9 @@ private:
    // Cleans up input state when dropping an inbound event.
    void dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) REQUIRES(mLock);

    // Enqueues a focus event.
    void enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) REQUIRES(mLock);

    // Adds an event to a queue of recent events for debugging purposes.
    void addRecentEventLocked(EventEntry* entry) REQUIRES(mLock);

@@ -299,6 +302,7 @@ private:
                           nsecs_t* nextWakeupTime) REQUIRES(mLock);
    bool dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason,
                              nsecs_t* nextWakeupTime) REQUIRES(mLock);
    void dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) REQUIRES(mLock);
    void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
                             const std::vector<InputTarget>& inputTargets) REQUIRES(mLock);

Loading