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

Commit 2fd4f0e0 authored by Bharat Singh's avatar Bharat Singh Committed by Android (Google) Code Review
Browse files

Merge "[SysUI][Floaty] Send KeyEvent with FLAG_LONG_PRESS on long power press" into main

parents 9b3faeef 44824f37
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ import static com.android.server.wm.WindowManagerPolicyProto.ROTATION;
import static com.android.server.wm.WindowManagerPolicyProto.ROTATION_MODE;
import static com.android.server.wm.WindowManagerPolicyProto.SCREEN_ON_FULLY;
import static com.android.server.wm.WindowManagerPolicyProto.WINDOW_MANAGER_DRAW_COMPLETE;
import static com.android.systemui.shared.Flags.enableLppSqueezeEffect;

import android.accessibilityservice.AccessibilityService;
import android.annotation.Nullable;
@@ -1502,6 +1503,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        Slog.d(TAG, "powerLongPress: eventTime=" + eventTime
                + " mLongPressOnPowerBehavior=" + mLongPressOnPowerBehavior);

        // Sending a synthetic KeyEvent to StatusBar service with flag FLAG_LONG_PRESS set, when
        // power button is long pressed
        if (enableLppSqueezeEffect()) {
            // Long press is detected in a callback, so there's no explicit hardware KeyEvent
            // available here. Instead, we create a synthetic power key event that has properties
            // similar to the original one.
            final KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KEYCODE_POWER);
            event.setFlags(KeyEvent.FLAG_LONG_PRESS);
            // setting both downTime and eventTime as same as downTime is sent as eventTime for long
            // press event in SingleKeyGestureDetector's handler
            event.setTime(eventTime, eventTime);
            sendSystemKeyToStatusBarAsync(event);
        }

        switch (behavior) {
            case LONG_PRESS_POWER_NOTHING:
                break;
+1 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ android_test {
        "androidx.test.rules",
        "androidx.test.runner",
        "com.android.window.flags.window-aconfig-java",
        "cts-input-lib",
        "flag-junit",
        "flickerlib",
        "frameworks-base-testutils",
+86 −0
Original line number Diff line number Diff line
@@ -15,22 +15,46 @@
 */
package com.android.server.policy;

import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.KeyEvent.ACTION_DOWN;
import static android.view.KeyEvent.ACTION_UP;
import static android.view.KeyEvent.FLAG_LONG_PRESS;
import static android.view.KeyEvent.KEYCODE_POWER;
import static android.view.KeyEvent.KEYCODE_VOLUME_UP;

import static com.android.cts.input.inputeventmatchers.InputEventMatchersKt.withKeyAction;
import static com.android.cts.input.inputeventmatchers.InputEventMatchersKt.withKeyCode;
import static com.android.cts.input.inputeventmatchers.InputEventMatchersKt.withKeyFlags;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_ASSISTANT;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_GLOBAL_ACTIONS;
import static com.android.server.policy.PhoneWindowManager.POWER_MULTI_PRESS_TIMEOUT_MILLIS;
import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_POWER_DREAM_OR_SLEEP;
import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_POWER_GO_TO_SLEEP;

import static org.hamcrest.Matchers.allOf;

import android.os.RemoteException;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.view.Display;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;

import androidx.annotation.NonNull;

import com.android.cts.input.BlockingQueueEventVerifier;
import com.android.systemui.shared.Flags;

import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Test class for power key gesture.
 *
@@ -149,4 +173,66 @@ public class PowerKeyGestureTests extends ShortcutKeyTestBase {
        sendKey(KEYCODE_POWER);
        mPhoneWindowManager.assertNoPowerSleep();
    }

    @EnableFlags(Flags.FLAG_ENABLE_LPP_SQUEEZE_EFFECT)
    @Test
    public void testPowerLongPress_flagEnabled_shouldSendSyntheticKeyEvent()
            throws RemoteException {
        final BlockingQueue<InputEvent> eventQueue = new LinkedBlockingQueue<>();
        final BlockingQueueEventVerifier verifier = new BlockingQueueEventVerifier(eventQueue);
        mPhoneWindowManager.overrideLongPressPowerForSyntheticEvent(LONG_PRESS_POWER_ASSISTANT,
                eventQueue);
        sendKeyForTriggeringSyntheticEvent();
        verifier.assertReceivedKey(allOf(withKeyCode(KEYCODE_POWER), withKeyAction(ACTION_DOWN)));
        verifier.assertReceivedKey(allOf(withKeyCode(KEYCODE_POWER), withKeyAction(ACTION_DOWN),
                withKeyFlags(FLAG_LONG_PRESS)));
        verifier.assertReceivedKey(allOf(withKeyCode(KEYCODE_POWER), withKeyAction(ACTION_UP)));
    }

    @DisableFlags(Flags.FLAG_ENABLE_LPP_SQUEEZE_EFFECT)
    @Test
    public void testPowerLongPress_flagDisabled_shouldNotSendSyntheticKeyEvent()
            throws RemoteException {
        final BlockingQueue<InputEvent> eventQueue = new LinkedBlockingQueue<>();
        final BlockingQueueEventVerifier verifier = new BlockingQueueEventVerifier(eventQueue);
        mPhoneWindowManager.overrideLongPressPowerForSyntheticEvent(LONG_PRESS_POWER_ASSISTANT,
                eventQueue);
        sendKeyForTriggeringSyntheticEvent();
        verifier.assertReceivedKey(allOf(withKeyCode(KEYCODE_POWER), withKeyAction(ACTION_DOWN)));
        verifier.assertReceivedKey(allOf(withKeyCode(KEYCODE_POWER), withKeyAction(ACTION_UP)));
    }

    private void sendKeyForTriggeringSyntheticEvent() {
        // send power button key down event (without setting long press flag) and move time forward
        // by long press duration timeout, it should send a synthetic power button down event with
        // long press flag set
        final long time = mPhoneWindowManager.getCurrentTime();
        final KeyEvent downEvent = getPowerButtonKeyEvent(ACTION_DOWN, time);
        mPhoneWindowManager.interceptKeyBeforeQueueing(downEvent);
        mPhoneWindowManager.dispatchAllPendingEvents();
        mPhoneWindowManager.moveTimeForward(SingleKeyGestureDetector.sDefaultLongPressTimeout);

        // send power button key up event to emulate power button has been released
        final KeyEvent upEvent = getPowerButtonKeyEvent(ACTION_UP, time);
        mPhoneWindowManager.interceptKeyBeforeQueueing(upEvent);
        mPhoneWindowManager.dispatchAllPendingEvents();
    }

    @NonNull
    private KeyEvent getPowerButtonKeyEvent(final int action, final long time) {
        final KeyEvent downEvent = new KeyEvent(
                /* downTime */ time,
                /* eventTime */ time,
                /* action */ action,
                /* keyCode */ KEYCODE_POWER,
                /* repeat */ 0,
                /* metaState */ 0,
                /* deviceId */ KeyCharacterMap.VIRTUAL_KEYBOARD,
                /* scanCode */ 0,
                /* flags */ 0,
                /* source */ InputDevice.SOURCE_KEYBOARD
        );
        downEvent.setDisplayId(DEFAULT_DISPLAY);
        return downEvent;
    }
}
+12 −2
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_SHUT
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
import static com.android.server.policy.PhoneWindowManager.POWER_VOLUME_UP_BEHAVIOR_MUTE;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyList;
@@ -130,9 +129,9 @@ import org.mockito.MockSettings;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.quality.Strictness;
import org.mockito.stubbing.Answer;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.function.Supplier;

class TestPhoneWindowManager {
@@ -544,6 +543,17 @@ class TestPhoneWindowManager {
        }
    }

    void overrideLongPressPowerForSyntheticEvent(final int behavior,
            final BlockingQueue<InputEvent> eventQueue) throws RemoteException {
        mPhoneWindowManager.getStatusBarService();
        spyOn(mPhoneWindowManager.mStatusBarService);
        Mockito.doAnswer(invocation -> {
            eventQueue.add(new KeyEvent(invocation.getArgument(0)));
            return null;
        }).when(mPhoneWindowManager.mStatusBarService).handleSystemKey(any());
        overrideLongPressOnPower(behavior);
    }

    void overrideLongPressOnHomeBehavior(int behavior) {
        mPhoneWindowManager.mLongPressOnHomeBehavior = behavior;
    }