Loading core/java/android/hardware/input/KeyGestureEvent.java +25 −1 Original line number Diff line number Diff line Loading @@ -113,6 +113,10 @@ public final class KeyGestureEvent { public static final int KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS = 65; public static final int KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS = 66; public static final int KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS = 67; public static final int KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW = 68; public static final int KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW = 69; public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 70; public static final int KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE = 71; public static final int FLAG_CANCELLED = 1; Loading Loading @@ -194,7 +198,11 @@ public final class KeyGestureEvent { KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS, KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS, KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS, KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS, KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW, KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW, KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW, KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE, }) @Retention(RetentionPolicy.SOURCE) public @interface KeyGestureType { Loading Loading @@ -541,6 +549,14 @@ public final class KeyGestureEvent { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE; case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION; case KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SNAP_LEFT_FREEFORM_WINDOW; case KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SNAP_RIGHT_FREEFORM_WINDOW; case KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MAXIMIZE_FREEFORM_WINDOW; case KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RESTORE_FREEFORM_WINDOW_SIZE; default: return LOG_EVENT_UNSPECIFIED; } Loading Loading @@ -749,6 +765,14 @@ public final class KeyGestureEvent { return "KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS"; case KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS: return "KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS"; case KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW: return "KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW"; case KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW: return "KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW"; case KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW: return "KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW"; case KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE: return "KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE"; default: return Integer.toHexString(value); } Loading services/core/java/com/android/server/input/KeyGestureController.java +49 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.hardware.input.Flags.useKeyGestureEventHandler; import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiPressGestures; import static com.android.server.flags.Flags.newBugreportKeyboardShortcut; import static com.android.window.flags.Flags.enableMoveToNextDisplayShortcut; import static com.android.window.flags.Flags.enableTaskResizingKeyboardShortcuts; import android.annotation.BinderThread; import android.annotation.MainThread; Loading Loading @@ -734,6 +735,54 @@ final class KeyGestureController { } } break; case KeyEvent.KEYCODE_LEFT_BRACKET: if (enableTaskResizingKeyboardShortcuts()) { if (firstDown && event.isAltPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW, KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken, /* flags = */0); } } break; case KeyEvent.KEYCODE_RIGHT_BRACKET: if (enableTaskResizingKeyboardShortcuts()) { if (firstDown && event.isAltPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW, KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken, /* flags = */0); } } break; case KeyEvent.KEYCODE_EQUALS: if (enableTaskResizingKeyboardShortcuts()) { if (firstDown && event.isAltPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW, KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken, /* flags = */0); } } break; case KeyEvent.KEYCODE_MINUS: if (enableTaskResizingKeyboardShortcuts()) { if (firstDown && event.isAltPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE, KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken, /* flags = */0); } } break; case KeyEvent.KEYCODE_SLASH: if (firstDown && event.isMetaPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_META_ON, Loading tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt +80 −0 Original line number Diff line number Diff line Loading @@ -883,6 +883,86 @@ class KeyGestureControllerTests { ) } @Test @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS) fun testSnapLeftFreeformTask() { val keyGestureController = KeyGestureController(context, testLooper.looper) testKeyGestureInternal( keyGestureController, TestData( "ALT + [ -> Resizes a task to fit the left half of the screen", intArrayOf( KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_LEFT_BRACKET ), KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW, intArrayOf(KeyEvent.KEYCODE_LEFT_BRACKET), KeyEvent.META_ALT_ON, intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ) ) } @Test @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS) fun testSnapRightFreeformTask() { val keyGestureController = KeyGestureController(context, testLooper.looper) testKeyGestureInternal( keyGestureController, TestData( "ALT + ] -> Resizes a task to fit the right half of the screen", intArrayOf( KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_RIGHT_BRACKET ), KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW, intArrayOf(KeyEvent.KEYCODE_RIGHT_BRACKET), KeyEvent.META_ALT_ON, intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ) ) } @Test @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS) fun testMaximizeFreeformTask() { val keyGestureController = KeyGestureController(context, testLooper.looper) testKeyGestureInternal( keyGestureController, TestData( "ALT + '=' -> Maximizes a task to fit the screen", intArrayOf( KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_EQUALS ), KeyGestureEvent.KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW, intArrayOf(KeyEvent.KEYCODE_EQUALS), KeyEvent.META_ALT_ON, intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ) ) } @Test @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS) fun testRestoreFreeformTask() { val keyGestureController = KeyGestureController(context, testLooper.looper) testKeyGestureInternal( keyGestureController, TestData( "ALT + '-' -> Restores a task size to its previous bounds", intArrayOf( KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_MINUS ), KeyGestureEvent.KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE, intArrayOf(KeyEvent.KEYCODE_MINUS), KeyEvent.META_ALT_ON, intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ) ) } @Test fun testCapsLockPressNotified() { val keyGestureController = KeyGestureController(context, testLooper.looper) Loading Loading
core/java/android/hardware/input/KeyGestureEvent.java +25 −1 Original line number Diff line number Diff line Loading @@ -113,6 +113,10 @@ public final class KeyGestureEvent { public static final int KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS = 65; public static final int KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS = 66; public static final int KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS = 67; public static final int KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW = 68; public static final int KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW = 69; public static final int KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW = 70; public static final int KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE = 71; public static final int FLAG_CANCELLED = 1; Loading Loading @@ -194,7 +198,11 @@ public final class KeyGestureEvent { KEY_GESTURE_TYPE_TOGGLE_STICKY_KEYS, KEY_GESTURE_TYPE_TOGGLE_BOUNCE_KEYS, KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS, KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS, KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW, KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW, KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW, KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE, }) @Retention(RetentionPolicy.SOURCE) public @interface KeyGestureType { Loading Loading @@ -541,6 +549,14 @@ public final class KeyGestureEvent { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE; case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION; case KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SNAP_LEFT_FREEFORM_WINDOW; case KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SNAP_RIGHT_FREEFORM_WINDOW; case KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MAXIMIZE_FREEFORM_WINDOW; case KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RESTORE_FREEFORM_WINDOW_SIZE; default: return LOG_EVENT_UNSPECIFIED; } Loading Loading @@ -749,6 +765,14 @@ public final class KeyGestureEvent { return "KEY_GESTURE_TYPE_TOGGLE_SLOW_KEYS"; case KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS: return "KEY_GESTURE_TYPE_TOGGLE_MOUSE_KEYS"; case KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW: return "KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW"; case KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW: return "KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW"; case KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW: return "KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW"; case KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE: return "KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE"; default: return Integer.toHexString(value); } Loading
services/core/java/com/android/server/input/KeyGestureController.java +49 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.hardware.input.Flags.useKeyGestureEventHandler; import static com.android.hardware.input.Flags.useKeyGestureEventHandlerMultiPressGestures; import static com.android.server.flags.Flags.newBugreportKeyboardShortcut; import static com.android.window.flags.Flags.enableMoveToNextDisplayShortcut; import static com.android.window.flags.Flags.enableTaskResizingKeyboardShortcuts; import android.annotation.BinderThread; import android.annotation.MainThread; Loading Loading @@ -734,6 +735,54 @@ final class KeyGestureController { } } break; case KeyEvent.KEYCODE_LEFT_BRACKET: if (enableTaskResizingKeyboardShortcuts()) { if (firstDown && event.isAltPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW, KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken, /* flags = */0); } } break; case KeyEvent.KEYCODE_RIGHT_BRACKET: if (enableTaskResizingKeyboardShortcuts()) { if (firstDown && event.isAltPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW, KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken, /* flags = */0); } } break; case KeyEvent.KEYCODE_EQUALS: if (enableTaskResizingKeyboardShortcuts()) { if (firstDown && event.isAltPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW, KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken, /* flags = */0); } } break; case KeyEvent.KEYCODE_MINUS: if (enableTaskResizingKeyboardShortcuts()) { if (firstDown && event.isAltPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_ALT_ON, KeyGestureEvent.KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE, KeyGestureEvent.ACTION_GESTURE_COMPLETE, displayId, focusedToken, /* flags = */0); } } break; case KeyEvent.KEYCODE_SLASH: if (firstDown && event.isMetaPressed()) { return handleKeyGesture(deviceId, new int[]{keyCode}, KeyEvent.META_META_ON, Loading
tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt +80 −0 Original line number Diff line number Diff line Loading @@ -883,6 +883,86 @@ class KeyGestureControllerTests { ) } @Test @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS) fun testSnapLeftFreeformTask() { val keyGestureController = KeyGestureController(context, testLooper.looper) testKeyGestureInternal( keyGestureController, TestData( "ALT + [ -> Resizes a task to fit the left half of the screen", intArrayOf( KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_LEFT_BRACKET ), KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_LEFT_FREEFORM_WINDOW, intArrayOf(KeyEvent.KEYCODE_LEFT_BRACKET), KeyEvent.META_ALT_ON, intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ) ) } @Test @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS) fun testSnapRightFreeformTask() { val keyGestureController = KeyGestureController(context, testLooper.looper) testKeyGestureInternal( keyGestureController, TestData( "ALT + ] -> Resizes a task to fit the right half of the screen", intArrayOf( KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_RIGHT_BRACKET ), KeyGestureEvent.KEY_GESTURE_TYPE_SNAP_RIGHT_FREEFORM_WINDOW, intArrayOf(KeyEvent.KEYCODE_RIGHT_BRACKET), KeyEvent.META_ALT_ON, intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ) ) } @Test @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS) fun testMaximizeFreeformTask() { val keyGestureController = KeyGestureController(context, testLooper.looper) testKeyGestureInternal( keyGestureController, TestData( "ALT + '=' -> Maximizes a task to fit the screen", intArrayOf( KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_EQUALS ), KeyGestureEvent.KEY_GESTURE_TYPE_MAXIMIZE_FREEFORM_WINDOW, intArrayOf(KeyEvent.KEYCODE_EQUALS), KeyEvent.META_ALT_ON, intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ) ) } @Test @EnableFlags(com.android.window.flags.Flags.FLAG_ENABLE_TASK_RESIZING_KEYBOARD_SHORTCUTS) fun testRestoreFreeformTask() { val keyGestureController = KeyGestureController(context, testLooper.looper) testKeyGestureInternal( keyGestureController, TestData( "ALT + '-' -> Restores a task size to its previous bounds", intArrayOf( KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_MINUS ), KeyGestureEvent.KEY_GESTURE_TYPE_RESTORE_FREEFORM_WINDOW_SIZE, intArrayOf(KeyEvent.KEYCODE_MINUS), KeyEvent.META_ALT_ON, intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE) ) ) } @Test fun testCapsLockPressNotified() { val keyGestureController = KeyGestureController(context, testLooper.looper) Loading