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

Commit 5e8ae0d5 authored by Arthur Hung's avatar Arthur Hung Committed by Android (Google) Code Review
Browse files

Merge "Synthesize cancellation events when device is disabled"

parents c1489084 2141d54f
Loading
Loading
Loading
Loading
+20 −8
Original line number Diff line number Diff line
@@ -127,7 +127,6 @@ void KeyboardInputMapper::dump(std::string& dump) {
    dump += StringPrintf(INDENT3 "Orientation: %d\n", getOrientation());
    dump += StringPrintf(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size());
    dump += StringPrintf(INDENT3 "MetaState: 0x%0x\n", mMetaState);
    dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime);
}

std::optional<DisplayViewport> KeyboardInputMapper::findViewport(
@@ -196,9 +195,7 @@ void KeyboardInputMapper::dumpParameters(std::string& dump) {
}

void KeyboardInputMapper::reset(nsecs_t when) {
    mMetaState = AMETA_NONE;
    mDownTime = 0;
    mKeyDowns.clear();
    cancelAllDownKeys(when);
    mCurrentHidUsage = 0;

    resetLedState();
@@ -281,6 +278,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down,
        policyFlags = 0;
    }

    nsecs_t downTime = when;
    if (down) {
        // Rotate key codes according to orientation if needed.
        if (mParameters.orientationAware) {
@@ -292,6 +290,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down,
        if (keyDownIndex >= 0) {
            // key repeat, be sure to use same keycode as before in case of rotation
            keyCode = mKeyDowns[keyDownIndex].keyCode;
            downTime = mKeyDowns[keyDownIndex].downTime;
        } else {
            // key down
            if ((policyFlags & POLICY_FLAG_VIRTUAL) &&
@@ -305,16 +304,16 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down,
            KeyDown keyDown;
            keyDown.keyCode = keyCode;
            keyDown.scanCode = scanCode;
            keyDown.downTime = when;
            mKeyDowns.push_back(keyDown);
        }

        mDownTime = when;
    } else {
        // Remove key down.
        ssize_t keyDownIndex = findKeyDown(scanCode);
        if (keyDownIndex >= 0) {
            // key up, be sure to use same keycode as before in case of rotation
            keyCode = mKeyDowns[keyDownIndex].keyCode;
            downTime = mKeyDowns[keyDownIndex].downTime;
            mKeyDowns.erase(mKeyDowns.begin() + (size_t)keyDownIndex);
        } else {
            // key was not actually down
@@ -333,8 +332,6 @@ void KeyboardInputMapper::processKey(nsecs_t when, nsecs_t readTime, bool down,
        keyMetaState = mMetaState;
    }

    nsecs_t downTime = mDownTime;

    // Key down on external an keyboard should wake the device.
    // We don't do this for internal keyboards to prevent them from waking up in your pocket.
    // For internal keyboards and devices for which the default wake behavior is explicitly
@@ -473,4 +470,19 @@ std::optional<int32_t> KeyboardInputMapper::getAssociatedDisplayId() {
    return std::nullopt;
}

void KeyboardInputMapper::cancelAllDownKeys(nsecs_t when) {
    size_t n = mKeyDowns.size();
    for (size_t i = 0; i < n; i++) {
        NotifyKeyArgs args(getContext()->getNextId(), when, systemTime(SYSTEM_TIME_MONOTONIC),
                           getDeviceId(), mSource, getDisplayId(), 0 /*policyFlags*/,
                           AKEY_EVENT_ACTION_UP,
                           AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED,
                           mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE,
                           mKeyDowns[i].downTime);
        getListener().notifyKey(&args);
    }
    mKeyDowns.clear();
    mMetaState = AMETA_NONE;
}

} // namespace android
+2 −1
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ private:
    std::optional<DisplayViewport> mViewport;

    struct KeyDown {
        nsecs_t downTime;
        int32_t keyCode;
        int32_t scanCode;
    };
@@ -59,7 +60,6 @@ private:

    std::vector<KeyDown> mKeyDowns; // keys that are down
    int32_t mMetaState;
    nsecs_t mDownTime; // time of most recent key down

    int32_t mCurrentHidUsage; // most recent HID usage seen this packet, or 0 if none

@@ -98,6 +98,7 @@ private:
    void updateLedStateForModifier(LedState& ledState, int32_t led, int32_t modifier, bool reset);
    std::optional<DisplayViewport> findViewport(nsecs_t when,
                                                const InputReaderConfiguration* config);
    void cancelAllDownKeys(nsecs_t when);
};

} // namespace android
+31 −0
Original line number Diff line number Diff line
@@ -4088,6 +4088,37 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) {
    ASSERT_EQ(AMETA_NONE, mapper2.getMetaState());
}

TEST_F(KeyboardInputMapperTest, Process_DisabledDevice) {
    const int32_t USAGE_A = 0x070004;
    mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
    mFakeEventHub->addKey(EVENTHUB_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);

    KeyboardInputMapper& mapper =
            addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD,
                                                       AINPUT_KEYBOARD_TYPE_ALPHABETIC);
    // Key down by scan code.
    process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_HOME, 1);
    NotifyKeyArgs args;
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
    ASSERT_EQ(DEVICE_ID, args.deviceId);
    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
    ASSERT_EQ(KEY_HOME, args.scanCode);
    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);

    // Disable device, it should synthesize cancellation events for down events.
    mFakePolicy->addDisabledDevice(DEVICE_ID);
    configureDevice(InputReaderConfiguration::CHANGE_ENABLED_STATE);

    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
    ASSERT_EQ(KEY_HOME, args.scanCode);
    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_CANCELED, args.flags);
}

// --- KeyboardInputMapperTest_ExternalDevice ---

class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest {