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

Commit b398162b authored by Josep del Rio's avatar Josep del Rio Committed by Josep del Río
Browse files

Trigger system key user activity during keyguard

This CL changes the user activity handling in input so system keys will
always trigger user activity bypassing the DISABLE_USER_ACTIVITY flag that is used in the keyguard.

With the current information at our disposal, we believe that the flag
in question was added to avoid accidental screen touches from waking
up the device and consume the battery. However, this concern does not
exist with system keys as accidental presses should be a lot rarer.

Bug: 272052147
Test: Flashed and tried using system shortcuts
Change-Id: I89c3402a6ae4c2c75927e548ff38c871eb60479c
parent 06f057d9
Loading
Loading
Loading
Loading
+33 −9
Original line number Diff line number Diff line
@@ -498,14 +498,14 @@ bool isConnectionResponsive(const Connection& connection) {
// Returns true if the event type passed as argument represents a user activity.
bool isUserActivityEvent(const EventEntry& eventEntry) {
    switch (eventEntry.type) {
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET:
        case EventEntry::Type::DRAG:
        case EventEntry::Type::FOCUS:
        case EventEntry::Type::POINTER_CAPTURE_CHANGED:
        case EventEntry::Type::DRAG:
        case EventEntry::Type::TOUCH_MODE_CHANGED:
        case EventEntry::Type::SENSOR:
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::TOUCH_MODE_CHANGED:
            return false;
        case EventEntry::Type::DEVICE_RESET:
        case EventEntry::Type::KEY:
        case EventEntry::Type::MOTION:
            return true;
@@ -1684,6 +1684,8 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<Key
                doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
            };
            postCommandLocked(std::move(command));
            // Poke user activity for keys not passed to user
            pokeUserActivityLocked(*entry);
            return false; // wait for the command to run
        } else {
            entry->interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
@@ -1700,6 +1702,8 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<Key
                           *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
                                                             : InputEventInjectionResult::FAILED);
        mReporter->reportDroppedKey(entry->id);
        // Poke user activity for undispatched keys
        pokeUserActivityLocked(*entry);
        return true;
    }

@@ -3010,13 +3014,11 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
    }
    int32_t displayId = getTargetDisplayId(eventEntry);
    sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
    const WindowInfo* windowDisablingUserActivityInfo = nullptr;
    if (focusedWindowHandle != nullptr) {
        const WindowInfo* info = focusedWindowHandle->getInfo();
        if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
            if (DEBUG_DISPATCH_CYCLE) {
                ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
            }
            return;
            windowDisablingUserActivityInfo = info;
        }
    }

@@ -3027,7 +3029,13 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
            if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
                return;
            }

            if (windowDisablingUserActivityInfo != nullptr) {
                if (DEBUG_DISPATCH_CYCLE) {
                    ALOGD("Not poking user activity: disabled by window '%s'.",
                          windowDisablingUserActivityInfo->name.c_str());
                }
                return;
            }
            if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
                eventType = USER_ACTIVITY_EVENT_TOUCH;
            }
@@ -3038,6 +3046,22 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
            if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
                return;
            }
            // If the key code is unknown, we don't consider it user activity
            if (keyEntry.keyCode == AKEYCODE_UNKNOWN) {
                return;
            }
            // Don't inhibit events that were intercepted or are not passed to
            // the apps, like system shortcuts
            if (windowDisablingUserActivityInfo != nullptr &&
                keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP &&
                keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER) {
                if (DEBUG_DISPATCH_CYCLE) {
                    ALOGD("Not poking user activity: disabled by window '%s'.",
                          windowDisablingUserActivityInfo->name.c_str());
                }
                return;
            }

            eventType = USER_ACTIVITY_EVENT_BUTTON;
            break;
        }
+129 −1
Original line number Diff line number Diff line
@@ -404,6 +404,16 @@ public:
        mInterceptKeyTimeout = timeout;
    }

    void assertUserActivityPoked() {
        std::scoped_lock lock(mLock);
        ASSERT_TRUE(mPokedUserActivity) << "Expected user activity to have been poked";
    }

    void assertUserActivityNotPoked() {
        std::scoped_lock lock(mLock);
        ASSERT_FALSE(mPokedUserActivity) << "Expected user activity not to have been poked";
    }

private:
    std::mutex mLock;
    std::unique_ptr<InputEvent> mFilteredEvent GUARDED_BY(mLock);
@@ -425,6 +435,7 @@ private:

    sp<IBinder> mDropTargetWindowToken GUARDED_BY(mLock);
    bool mNotifyDropWindowWasCalled GUARDED_BY(mLock) = false;
    bool mPokedUserActivity GUARDED_BY(mLock) = false;

    std::chrono::milliseconds mInterceptKeyTimeout = 0ms;

@@ -578,7 +589,10 @@ private:
        mLastNotifySwitch = NotifySwitchArgs(/*id=*/1, when, policyFlags, switchValues, switchMask);
    }

    void pokeUserActivity(nsecs_t, int32_t, int32_t) override {}
    void pokeUserActivity(nsecs_t, int32_t, int32_t) override {
        std::scoped_lock lock(mLock);
        mPokedUserActivity = true;
    }

    void onPointerDownOutsideFocus(const sp<IBinder>& newToken) override {
        std::scoped_lock lock(mLock);
@@ -1190,6 +1204,10 @@ public:
        mInfo.setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, noInputChannel);
    }

    void setDisableUserActivity(bool disableUserActivity) {
        mInfo.setInputConfig(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY, disableUserActivity);
    }

    void setAlpha(float alpha) { mInfo.alpha = alpha; }

    void setTouchOcclusionMode(TouchOcclusionMode mode) { mInfo.touchOcclusionMode = mode; }
@@ -1742,6 +1760,28 @@ static NotifyKeyArgs generateKeyArgs(int32_t action, int32_t displayId = ADISPLA
    return args;
}

static NotifyKeyArgs generateSystemShortcutArgs(int32_t action,
                                                int32_t displayId = ADISPLAY_ID_NONE) {
    nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
    // Define a valid key event.
    NotifyKeyArgs args(/*id=*/0, currentTime, /*readTime=*/0, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
                       displayId, 0, action, /* flags */ 0, AKEYCODE_C, KEY_C, AMETA_META_ON,
                       currentTime);

    return args;
}

static NotifyKeyArgs generateAssistantKeyArgs(int32_t action,
                                              int32_t displayId = ADISPLAY_ID_NONE) {
    nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
    // Define a valid key event.
    NotifyKeyArgs args(/*id=*/0, currentTime, /*readTime=*/0, DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
                       displayId, 0, action, /* flags */ 0, AKEYCODE_ASSIST, KEY_ASSISTANT,
                       AMETA_NONE, currentTime);

    return args;
}

[[nodiscard]] static NotifyMotionArgs generateMotionArgs(int32_t action, int32_t source,
                                                         int32_t displayId,
                                                         const std::vector<PointF>& points) {
@@ -4531,6 +4571,94 @@ TEST_F(InputDispatcherTest, FocusedWindow_ReceivesFocusEventAndKeyEvent) {

    // Window should receive key down event.
    window->consumeKeyDown(ADISPLAY_ID_DEFAULT);

    // Should have poked user activity
    mFakePolicy->assertUserActivityPoked();
}

TEST_F(InputDispatcherTest, FocusedWindow_DisableUserActivity) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher,
                                                             "Fake Window", ADISPLAY_ID_DEFAULT);

    window->setDisableUserActivity(true);
    window->setFocusable(true);
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
    setFocusedWindow(window);

    window->consumeFocusEvent(true);

    mDispatcher->notifyKey(generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT));

    // Window should receive key down event.
    window->consumeKeyDown(ADISPLAY_ID_DEFAULT);

    // Should have poked user activity
    mFakePolicy->assertUserActivityNotPoked();
}

TEST_F(InputDispatcherTest, FocusedWindow_DoesNotReceiveSystemShortcut) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher,
                                                             "Fake Window", ADISPLAY_ID_DEFAULT);

    window->setFocusable(true);
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
    setFocusedWindow(window);

    window->consumeFocusEvent(true);

    mDispatcher->notifyKey(generateSystemShortcutArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT));
    mDispatcher->waitForIdle();

    // System key is not passed down
    window->assertNoEvents();

    // Should have poked user activity
    mFakePolicy->assertUserActivityPoked();
}

TEST_F(InputDispatcherTest, FocusedWindow_DoesNotReceiveAssistantKey) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher,
                                                             "Fake Window", ADISPLAY_ID_DEFAULT);

    window->setFocusable(true);
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
    setFocusedWindow(window);

    window->consumeFocusEvent(true);

    mDispatcher->notifyKey(generateAssistantKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT));
    mDispatcher->waitForIdle();

    // System key is not passed down
    window->assertNoEvents();

    // Should have poked user activity
    mFakePolicy->assertUserActivityPoked();
}

TEST_F(InputDispatcherTest, FocusedWindow_SystemKeyIgnoresDisableUserActivity) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher,
                                                             "Fake Window", ADISPLAY_ID_DEFAULT);

    window->setDisableUserActivity(true);
    window->setFocusable(true);
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
    setFocusedWindow(window);

    window->consumeFocusEvent(true);

    mDispatcher->notifyKey(generateSystemShortcutArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT));
    mDispatcher->waitForIdle();

    // System key is not passed down
    window->assertNoEvents();

    // Should have poked user activity
    mFakePolicy->assertUserActivityPoked();
}

TEST_F(InputDispatcherTest, UnfocusedWindow_DoesNotReceiveFocusEventOrKeyEvent) {