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

Commit 6bf9b30d authored by Sergey Pinkevich's avatar Sergey Pinkevich
Browse files

Send key gesture event on external display

When Home is clicked on external display, send this event to be handled on Launcher side

Bug: 427579352
Flag: com.android.window.flags.enable_launcher_handle_go_home_keyboard_shortcut
Test: manually

Change-Id: Ice07931180ad9ba2ae7f09a24a55fcf013f68304
parent ea686dc6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ public final class KeyGestureEvent {
    public static final int KEY_GESTURE_TYPE_QUIT_FOCUSED_DESKTOP_TASK = 81;
    public static final int KEY_GESTURE_TYPE_TOGGLE_FULLSCREEN = 82;
    public static final int KEY_GESTURE_TYPE_TAKE_PARTIAL_SCREENSHOT = 83;
    public static final int KEY_GESTURE_TYPE_REJECT_HOME_ON_EXTERNAL_DISPLAY = 84;

    public static final int FLAG_CANCELLED = 1 << 0;
    public static final int FLAG_LONG_PRESS = 1 << 1;
@@ -234,6 +235,7 @@ public final class KeyGestureEvent {
            KEY_GESTURE_TYPE_QUIT_FOCUSED_DESKTOP_TASK,
            KEY_GESTURE_TYPE_TOGGLE_FULLSCREEN,
            KEY_GESTURE_TYPE_TAKE_PARTIAL_SCREENSHOT,
            KEY_GESTURE_TYPE_REJECT_HOME_ON_EXTERNAL_DISPLAY,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface KeyGestureType {
@@ -840,6 +842,8 @@ public final class KeyGestureEvent {
                return "KEY_GESTURE_TYPE_TOGGLE_FULLSCREEN";
            case KEY_GESTURE_TYPE_TAKE_PARTIAL_SCREENSHOT:
                return "KEY_GESTURE_TYPE_TAKE_PARTIAL_SCREENSHOT";
            case KEY_GESTURE_TYPE_REJECT_HOME_ON_EXTERNAL_DISPLAY:
                return "KEY_GESTURE_TYPE_REJECT_HOME_ON_EXTERNAL_DISPLAY";
            default:
                return Integer.toHexString(value);
        }
+3 −0
Original line number Diff line number Diff line
@@ -207,6 +207,9 @@ public enum DesktopExperienceFlags {
            Flags.FLAG_ENABLE_INTERACTIVE_PICTURE_IN_PICTURE),
    ENABLE_KEYBOARD_SHORTCUTS_TO_SWITCH_DESKS(Flags::keyboardShortcutsToSwitchDesks, true,
            Flags.FLAG_KEYBOARD_SHORTCUTS_TO_SWITCH_DESKS),
    ENABLE_LAUNCHER_HANDLE_GO_HOME_KEYBOARD_SHORTCUT(
            Flags::enableLauncherHandleGoHomeKeyboardShortcut, false,
            Flags.FLAG_ENABLE_LAUNCHER_HANDLE_GO_HOME_KEYBOARD_SHORTCUT),
    ENABLE_MIRROR_DISPLAY_NO_ACTIVITY(Flags::enableMirrorDisplayNoActivity, true,
            Flags.FLAG_ENABLE_MIRROR_DISPLAY_NO_ACTIVITY),
    ENABLE_MODALS_FULLSCREEN_WITH_PLATFORM_SIGNATURE(
+22 −4
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.STATE_OFF;
import static android.view.Display.TYPE_EXTERNAL;
import static android.view.KeyEvent.KEYCODE_BACK;
import static android.view.KeyEvent.KEYCODE_HOME;
import static android.view.KeyEvent.KEYCODE_POWER;
@@ -200,6 +201,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.HapticFeedbackConstants;
import android.view.IDisplayFoldListener;
import android.view.InputDevice;
@@ -216,6 +218,7 @@ import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.autofill.AutofillManagerInternal;
import android.widget.Toast;
import android.window.DesktopExperienceFlags;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -6310,11 +6313,26 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            Log.d(TAG, "startDockOrHome: startReason= " + startReason);
        }

        DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
        boolean isDisplayExternal = displayInfo != null && displayInfo.type == TYPE_EXTERNAL;
        if (DesktopExperienceFlags.ENABLE_LAUNCHER_HANDLE_GO_HOME_KEYBOARD_SHORTCUT.isTrue()
                && isDisplayExternal) {
            // TODO(b/441952247): Clean up using home gesture handling in WM Core
            mInputManagerInternal.handleKeyGestureInKeyGestureController(
                    new KeyGestureEvent.Builder()
                            .setKeyGestureType(
                                 KeyGestureEvent.KEY_GESTURE_TYPE_REJECT_HOME_ON_EXTERNAL_DISPLAY)
                            .setKeycodes(new int[]{KEYCODE_HOME})
                            .setDisplayId(displayId)
                            .setAction(ACTION_COMPLETE)
                            .build());
        } else {
            int userId = mUserManagerInternal.getUserAssignedToDisplay(displayId);
            // Start home.
            mActivityTaskManagerInternal.startHomeOnDisplay(userId, startReason,
                    displayId, true /* allowInstrumenting */, fromHomeKey);
        }
    }

    void startDockOrHome(int displayId, boolean fromHomeKey, boolean awakenFromDreams) {
        startDockOrHome(displayId, fromHomeKey, awakenFromDreams, /*startReason*/
+12 −2
Original line number Diff line number Diff line
@@ -20,11 +20,10 @@ import static android.bluetooth.BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.DEFAULT_DISPLAY_GROUP;
import static android.view.Display.TYPE_INTERNAL;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManagerGlobal.ADD_OKAY;
import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_UNKNOWN;
import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH;

import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

@@ -38,6 +37,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH;
import static com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_UNKNOWN;
import static com.android.server.policy.PhoneWindowManager.EXTRA_TRIGGER_HUB;
import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_POWER_DREAM_OR_AWAKE_OR_SLEEP;
import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_POWER_GO_TO_SLEEP;
@@ -62,6 +63,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.input.InputManager;
import android.hardware.input.KeyGestureEvent;
import android.os.Bundle;
@@ -78,6 +80,7 @@ import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.service.dreams.DreamManagerInternal;
import android.testing.TestableContext;
import android.view.DisplayInfo;

import androidx.test.filters.SmallTest;

@@ -148,6 +151,9 @@ public class PhoneWindowManagerTests {
    private StatusBarManagerInternal mStatusBarManagerInternal;
    @Mock
    private UserManagerInternal mUserManagerInternal;
    @Mock
    private DisplayManagerInternal mDisplayManagerInternal;
    private final DisplayInfo mDisplayInfo = new DisplayInfo();

    @Mock
    private PowerManager mPowerManager;
@@ -708,6 +714,10 @@ public class PhoneWindowManagerTests {
        when(mAtmInternal.startHomeOnDisplay(
                anyInt(), anyString(), anyInt(), anyBoolean(), anyBoolean())).thenReturn(false);
        mPhoneWindowManager.mUserManagerInternal = mock(UserManagerInternal.class);

        mPhoneWindowManager.mDisplayManagerInternal = mDisplayManagerInternal;
        mDisplayInfo.type = TYPE_INTERNAL;
        when(mDisplayManagerInternal.getDisplayInfo(anyInt())).thenReturn(mDisplayInfo);
    }

    private class TestInjector extends PhoneWindowManager.Injector {