Merge "Make sure views are added back when updating" into main
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 61d8702..8975191 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -162,6 +162,13 @@
* @hide
*/
int BIOMETRIC_ERROR_POWER_PRESSED = 19;
+
+ /**
+ * Mandatory biometrics is not in effect.
+ * @hide
+ */
+ int BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE = 20;
+
/**
* This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
* because the authentication attempt was unsuccessful.
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index de1cac4..9bc46b9 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -80,6 +80,20 @@
BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT;
/**
+ * Lockout error.
+ * @hide
+ */
+ public static final int BIOMETRIC_ERROR_LOCKOUT =
+ BiometricConstants.BIOMETRIC_ERROR_LOCKOUT;
+
+ /**
+ * Mandatory biometrics is not effective.
+ * @hide
+ */
+ public static final int BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE =
+ BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
+
+ /**
* A security vulnerability has been discovered and the sensor is unavailable until a
* security update has addressed this issue. This error can be received if for example,
* authentication was requested with {@link Authenticators#BIOMETRIC_STRONG}, but the
@@ -113,7 +127,9 @@
BIOMETRIC_ERROR_HW_UNAVAILABLE,
BIOMETRIC_ERROR_NONE_ENROLLED,
BIOMETRIC_ERROR_NO_HARDWARE,
- BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED})
+ BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
+ BIOMETRIC_ERROR_LOCKOUT,
+ BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE})
@Retention(RetentionPolicy.SOURCE)
public @interface BiometricError {}
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 98e11375..83f2685 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -25,7 +25,7 @@
import android.hardware.input.IInputDeviceBatteryState;
import android.hardware.input.IKeyboardBacklightListener;
import android.hardware.input.IKeyboardBacklightState;
-import android.hardware.input.IKeyboardSystemShortcutListener;
+import android.hardware.input.IKeyGestureEventListener;
import android.hardware.input.IStickyModifierStateListener;
import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.KeyboardLayoutSelectionResult;
@@ -241,13 +241,13 @@
KeyGlyphMap getKeyGlyphMap(int deviceId);
- @EnforcePermission("MONITOR_KEYBOARD_SYSTEM_SHORTCUTS")
+ @EnforcePermission("MANAGE_KEY_GESTURES")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
- + "android.Manifest.permission.MONITOR_KEYBOARD_SYSTEM_SHORTCUTS)")
- void registerKeyboardSystemShortcutListener(IKeyboardSystemShortcutListener listener);
+ + "android.Manifest.permission.MANAGE_KEY_GESTURES)")
+ void registerKeyGestureEventListener(IKeyGestureEventListener listener);
- @EnforcePermission("MONITOR_KEYBOARD_SYSTEM_SHORTCUTS")
+ @EnforcePermission("MANAGE_KEY_GESTURES")
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
- + "android.Manifest.permission.MONITOR_KEYBOARD_SYSTEM_SHORTCUTS)")
- void unregisterKeyboardSystemShortcutListener(IKeyboardSystemShortcutListener listener);
+ + "android.Manifest.permission.MANAGE_KEY_GESTURES)")
+ void unregisterKeyGestureEventListener(IKeyGestureEventListener listener);
}
diff --git a/core/java/android/hardware/input/IKeyboardSystemShortcutListener.aidl b/core/java/android/hardware/input/IKeyGestureEventListener.aidl
similarity index 71%
rename from core/java/android/hardware/input/IKeyboardSystemShortcutListener.aidl
rename to core/java/android/hardware/input/IKeyGestureEventListener.aidl
index 8d44917..2c430f1 100644
--- a/core/java/android/hardware/input/IKeyboardSystemShortcutListener.aidl
+++ b/core/java/android/hardware/input/IKeyGestureEventListener.aidl
@@ -17,11 +17,10 @@
package android.hardware.input;
/** @hide */
-oneway interface IKeyboardSystemShortcutListener {
+oneway interface IKeyGestureEventListener {
/**
- * Called when the keyboard system shortcut is triggered.
+ * Called when a key gesture event occurs.
*/
- void onKeyboardSystemShortcutTriggered(int deviceId, in int[] keycodes, int modifierState,
- int shortcut);
+ void onKeyGestureEvent(int deviceId, in int[] keycodes, int modifierState, int shortcut);
}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 6bc522b..04cfcd8 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -1378,33 +1378,31 @@
}
/**
- * Registers a keyboard system shortcut listener for {@link KeyboardSystemShortcut} being
- * triggered.
+ * Registers a key gesture event listener for {@link KeyGestureEvent} being triggered.
*
* @param executor an executor on which the callback will be called
- * @param listener the {@link KeyboardSystemShortcutListener}
+ * @param listener the {@link KeyGestureEventListener}
* @throws IllegalArgumentException if {@code listener} has already been registered previously.
* @throws NullPointerException if {@code listener} or {@code executor} is null.
* @hide
- * @see #unregisterKeyboardSystemShortcutListener(KeyboardSystemShortcutListener)
+ * @see #unregisterKeyGestureEventListener(KeyGestureEventListener)
*/
- @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_SYSTEM_SHORTCUTS)
- public void registerKeyboardSystemShortcutListener(@NonNull Executor executor,
- @NonNull KeyboardSystemShortcutListener listener) throws IllegalArgumentException {
- mGlobal.registerKeyboardSystemShortcutListener(executor, listener);
+ @RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ public void registerKeyGestureEventListener(@NonNull Executor executor,
+ @NonNull KeyGestureEventListener listener) throws IllegalArgumentException {
+ mGlobal.registerKeyGestureEventListener(executor, listener);
}
/**
- * Unregisters a previously added keyboard system shortcut listener.
+ * Unregisters a previously added key gesture event listener.
*
- * @param listener the {@link KeyboardSystemShortcutListener}
+ * @param listener the {@link KeyGestureEventListener}
* @hide
- * @see #registerKeyboardSystemShortcutListener(Executor, KeyboardSystemShortcutListener)
+ * @see #registerKeyGestureEventListener(Executor, KeyGestureEventListener)
*/
- @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_SYSTEM_SHORTCUTS)
- public void unregisterKeyboardSystemShortcutListener(
- @NonNull KeyboardSystemShortcutListener listener) {
- mGlobal.unregisterKeyboardSystemShortcutListener(listener);
+ @RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ public void unregisterKeyGestureEventListener(@NonNull KeyGestureEventListener listener) {
+ mGlobal.unregisterKeyGestureEventListener(listener);
}
/**
@@ -1510,19 +1508,18 @@
}
/**
- * A callback used to be notified about keyboard system shortcuts being triggered.
+ * A callback used to notify about key gesture event on completion.
*
- * @see #registerKeyboardSystemShortcutListener(Executor, KeyboardSystemShortcutListener)
- * @see #unregisterKeyboardSystemShortcutListener(KeyboardSystemShortcutListener)
+ * @see #registerKeyGestureEventListener(Executor, KeyGestureEventListener)
+ * @see #unregisterKeyGestureEventListener(KeyGestureEventListener)
* @hide
*/
- public interface KeyboardSystemShortcutListener {
+ public interface KeyGestureEventListener {
/**
- * Called when a keyboard system shortcut is triggered.
+ * Called when a key gesture event occurs.
*
- * @param systemShortcut the shortcut info about the shortcut that was triggered.
+ * @param event the gesture event that occurred.
*/
- void onKeyboardSystemShortcutTriggered(int deviceId,
- @NonNull KeyboardSystemShortcut systemShortcut);
+ void onKeyGestureEvent(@NonNull KeyGestureEvent event);
}
}
diff --git a/core/java/android/hardware/input/InputManagerGlobal.java b/core/java/android/hardware/input/InputManagerGlobal.java
index f7fa557..03cf7c5 100644
--- a/core/java/android/hardware/input/InputManagerGlobal.java
+++ b/core/java/android/hardware/input/InputManagerGlobal.java
@@ -25,8 +25,8 @@
import android.hardware.SensorManager;
import android.hardware.input.InputManager.InputDeviceBatteryListener;
import android.hardware.input.InputManager.InputDeviceListener;
+import android.hardware.input.InputManager.KeyGestureEventListener;
import android.hardware.input.InputManager.KeyboardBacklightListener;
-import android.hardware.input.InputManager.KeyboardSystemShortcutListener;
import android.hardware.input.InputManager.OnTabletModeChangedListener;
import android.hardware.input.InputManager.StickyModifierStateListener;
import android.hardware.lights.Light;
@@ -111,13 +111,13 @@
@Nullable
private IStickyModifierStateListener mStickyModifierStateListener;
- private final Object mKeyboardSystemShortcutListenerLock = new Object();
- @GuardedBy("mKeyboardSystemShortcutListenerLock")
+ private final Object mKeyGestureEventListenerLock = new Object();
+ @GuardedBy("mKeyGestureEventListenerLock")
@Nullable
- private ArrayList<KeyboardSystemShortcutListenerDelegate> mKeyboardSystemShortcutListeners;
- @GuardedBy("mKeyboardSystemShortcutListenerLock")
+ private ArrayList<KeyGestureEventListenerDelegate> mKeyGestureEventListeners;
+ @GuardedBy("mKeyGestureEventListenerLock")
@Nullable
- private IKeyboardSystemShortcutListener mKeyboardSystemShortcutListener;
+ private IKeyGestureEventListener mKeyGestureEventListener;
// InputDeviceSensorManager gets notified synchronously from the binder thread when input
// devices change, so it must be synchronized with the input device listeners.
@@ -1064,94 +1064,92 @@
}
}
- private static final class KeyboardSystemShortcutListenerDelegate {
- final KeyboardSystemShortcutListener mListener;
+ private static final class KeyGestureEventListenerDelegate {
+ final KeyGestureEventListener mListener;
final Executor mExecutor;
- KeyboardSystemShortcutListenerDelegate(KeyboardSystemShortcutListener listener,
+ KeyGestureEventListenerDelegate(KeyGestureEventListener listener,
Executor executor) {
mListener = listener;
mExecutor = executor;
}
- void onKeyboardSystemShortcutTriggered(int deviceId,
- KeyboardSystemShortcut systemShortcut) {
- mExecutor.execute(() ->
- mListener.onKeyboardSystemShortcutTriggered(deviceId, systemShortcut));
+ void onKeyGestureEvent(KeyGestureEvent event) {
+ mExecutor.execute(() -> mListener.onKeyGestureEvent(event));
}
}
- private class LocalKeyboardSystemShortcutListener extends IKeyboardSystemShortcutListener.Stub {
+ private class LocalKeyGestureEventListener extends IKeyGestureEventListener.Stub {
@Override
- public void onKeyboardSystemShortcutTriggered(int deviceId, int[] keycodes,
- int modifierState, int shortcut) {
- synchronized (mKeyboardSystemShortcutListenerLock) {
- if (mKeyboardSystemShortcutListeners == null) return;
- final int numListeners = mKeyboardSystemShortcutListeners.size();
+ public void onKeyGestureEvent(int deviceId, int[] keycodes, int modifierState,
+ int gestureType) {
+ synchronized (mKeyGestureEventListenerLock) {
+ if (mKeyGestureEventListeners == null) return;
+ final int numListeners = mKeyGestureEventListeners.size();
for (int i = 0; i < numListeners; i++) {
- mKeyboardSystemShortcutListeners.get(i)
- .onKeyboardSystemShortcutTriggered(deviceId,
- new KeyboardSystemShortcut(keycodes, modifierState, shortcut));
+ mKeyGestureEventListeners.get(i)
+ .onKeyGestureEvent(
+ new KeyGestureEvent(deviceId, keycodes, modifierState,
+ gestureType));
}
}
}
}
/**
- * @see InputManager#registerKeyboardSystemShortcutListener(Executor,
- * KeyboardSystemShortcutListener)
+ * @see InputManager#registerKeyGestureEventListener(Executor,
+ * KeyGestureEventListener)
*/
- @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_SYSTEM_SHORTCUTS)
- void registerKeyboardSystemShortcutListener(@NonNull Executor executor,
- @NonNull KeyboardSystemShortcutListener listener) throws IllegalArgumentException {
+ @RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ void registerKeyGestureEventListener(@NonNull Executor executor,
+ @NonNull KeyGestureEventListener listener) throws IllegalArgumentException {
Objects.requireNonNull(executor, "executor should not be null");
Objects.requireNonNull(listener, "listener should not be null");
- synchronized (mKeyboardSystemShortcutListenerLock) {
- if (mKeyboardSystemShortcutListener == null) {
- mKeyboardSystemShortcutListeners = new ArrayList<>();
- mKeyboardSystemShortcutListener = new LocalKeyboardSystemShortcutListener();
+ synchronized (mKeyGestureEventListenerLock) {
+ if (mKeyGestureEventListener == null) {
+ mKeyGestureEventListeners = new ArrayList<>();
+ mKeyGestureEventListener = new LocalKeyGestureEventListener();
try {
- mIm.registerKeyboardSystemShortcutListener(mKeyboardSystemShortcutListener);
+ mIm.registerKeyGestureEventListener(mKeyGestureEventListener);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
- final int numListeners = mKeyboardSystemShortcutListeners.size();
+ final int numListeners = mKeyGestureEventListeners.size();
for (int i = 0; i < numListeners; i++) {
- if (mKeyboardSystemShortcutListeners.get(i).mListener == listener) {
+ if (mKeyGestureEventListeners.get(i).mListener == listener) {
throw new IllegalArgumentException("Listener has already been registered!");
}
}
- KeyboardSystemShortcutListenerDelegate delegate =
- new KeyboardSystemShortcutListenerDelegate(listener, executor);
- mKeyboardSystemShortcutListeners.add(delegate);
+ KeyGestureEventListenerDelegate delegate =
+ new KeyGestureEventListenerDelegate(listener, executor);
+ mKeyGestureEventListeners.add(delegate);
}
}
/**
- * @see InputManager#unregisterKeyboardSystemShortcutListener(KeyboardSystemShortcutListener)
+ * @see InputManager#unregisterKeyGestureEventListener(KeyGestureEventListener)
*/
- @RequiresPermission(Manifest.permission.MONITOR_KEYBOARD_SYSTEM_SHORTCUTS)
- void unregisterKeyboardSystemShortcutListener(
- @NonNull KeyboardSystemShortcutListener listener) {
+ @RequiresPermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ void unregisterKeyGestureEventListener(@NonNull KeyGestureEventListener listener) {
Objects.requireNonNull(listener, "listener should not be null");
- synchronized (mKeyboardSystemShortcutListenerLock) {
- if (mKeyboardSystemShortcutListeners == null) {
+ synchronized (mKeyGestureEventListenerLock) {
+ if (mKeyGestureEventListeners == null) {
return;
}
- mKeyboardSystemShortcutListeners.removeIf((delegate) -> delegate.mListener == listener);
- if (mKeyboardSystemShortcutListeners.isEmpty()) {
+ mKeyGestureEventListeners.removeIf((delegate) -> delegate.mListener == listener);
+ if (mKeyGestureEventListeners.isEmpty()) {
try {
- mIm.unregisterKeyboardSystemShortcutListener(mKeyboardSystemShortcutListener);
+ mIm.unregisterKeyGestureEventListener(mKeyGestureEventListener);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- mKeyboardSystemShortcutListeners = null;
- mKeyboardSystemShortcutListener = null;
+ mKeyGestureEventListeners = null;
+ mKeyGestureEventListener = null;
}
}
}
diff --git a/core/java/android/hardware/input/KeyGestureEvent.java b/core/java/android/hardware/input/KeyGestureEvent.java
new file mode 100644
index 0000000..7a8dd33
--- /dev/null
+++ b/core/java/android/hardware/input/KeyGestureEvent.java
@@ -0,0 +1,531 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.DataClass;
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Provides information about the keyboard gesture event being triggered by an external keyboard.
+ *
+ * @hide
+ */
+@DataClass(genToString = true, genEqualsHashCode = true)
+public class KeyGestureEvent {
+
+ private final int mDeviceId;
+ @NonNull
+ private final int[] mKeycodes;
+ private final int mModifierState;
+ @KeyGestureType
+ private final int mKeyGestureType;
+
+
+ public static final int KEY_GESTURE_TYPE_UNSPECIFIED =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED;
+ public static final int KEY_GESTURE_TYPE_HOME =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME;
+ public static final int KEY_GESTURE_TYPE_RECENT_APPS =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RECENT_APPS;
+ public static final int KEY_GESTURE_TYPE_BACK =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BACK;
+ public static final int KEY_GESTURE_TYPE_APP_SWITCH =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__APP_SWITCH;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_ASSISTANT =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_ASSISTANT;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_VOICE_ASSISTANT;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SYSTEM_SETTINGS;
+ public static final int KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_NOTIFICATION_PANEL;
+ public static final int KEY_GESTURE_TYPE_TOGGLE_TASKBAR =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_TASKBAR;
+ public static final int KEY_GESTURE_TYPE_TAKE_SCREENSHOT =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TAKE_SCREENSHOT;
+ public static final int KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_SHORTCUT_HELPER;
+ public static final int KEY_GESTURE_TYPE_BRIGHTNESS_UP =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_UP;
+ public static final int KEY_GESTURE_TYPE_BRIGHTNESS_DOWN =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_DOWN;
+ public static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_UP;
+ public static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_DOWN;
+ public static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_TOGGLE;
+ public static final int KEY_GESTURE_TYPE_VOLUME_UP =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_UP;
+ public static final int KEY_GESTURE_TYPE_VOLUME_DOWN =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_DOWN;
+ public static final int KEY_GESTURE_TYPE_VOLUME_MUTE =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_MUTE;
+ public static final int KEY_GESTURE_TYPE_ALL_APPS =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ALL_APPS;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_SEARCH =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SEARCH;
+ public static final int KEY_GESTURE_TYPE_LANGUAGE_SWITCH =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LANGUAGE_SWITCH;
+ public static final int KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ACCESSIBILITY_ALL_APPS;
+ public static final int KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_CAPS_LOCK;
+ public static final int KEY_GESTURE_TYPE_SYSTEM_MUTE =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_MUTE;
+ public static final int KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SPLIT_SCREEN_NAVIGATION;
+ public static final int KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__CHANGE_SPLITSCREEN_FOCUS;
+ public static final int KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TRIGGER_BUG_REPORT;
+ public static final int KEY_GESTURE_TYPE_LOCK_SCREEN =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LOCK_SCREEN;
+ public static final int KEY_GESTURE_TYPE_OPEN_NOTES =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_NOTES;
+ public static final int KEY_GESTURE_TYPE_TOGGLE_POWER =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_POWER;
+ public static final int KEY_GESTURE_TYPE_SYSTEM_NAVIGATION =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_NAVIGATION;
+ public static final int KEY_GESTURE_TYPE_SLEEP =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SLEEP;
+ public static final int KEY_GESTURE_TYPE_WAKEUP =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__WAKEUP;
+ public static final int KEY_GESTURE_TYPE_MEDIA_KEY =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MEDIA_KEY;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_EMAIL;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CONTACTS;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALENDAR;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALCULATOR;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MUSIC;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MAPS;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_GALLERY;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FILES;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS;
+ public static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME;
+ public static final int KEY_GESTURE_TYPE_DESKTOP_MODE =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE;
+ public static final int KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION =
+ FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION;
+
+
+
+ // Code below generated by codegen v1.0.23.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/hardware/input/KeyGestureEvent.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ @IntDef(prefix = "KEY_GESTURE_TYPE_", value = {
+ KEY_GESTURE_TYPE_UNSPECIFIED,
+ KEY_GESTURE_TYPE_HOME,
+ KEY_GESTURE_TYPE_RECENT_APPS,
+ KEY_GESTURE_TYPE_BACK,
+ KEY_GESTURE_TYPE_APP_SWITCH,
+ KEY_GESTURE_TYPE_LAUNCH_ASSISTANT,
+ KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT,
+ KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS,
+ KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
+ KEY_GESTURE_TYPE_TOGGLE_TASKBAR,
+ KEY_GESTURE_TYPE_TAKE_SCREENSHOT,
+ KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER,
+ KEY_GESTURE_TYPE_BRIGHTNESS_UP,
+ KEY_GESTURE_TYPE_BRIGHTNESS_DOWN,
+ KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP,
+ KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN,
+ KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE,
+ KEY_GESTURE_TYPE_VOLUME_UP,
+ KEY_GESTURE_TYPE_VOLUME_DOWN,
+ KEY_GESTURE_TYPE_VOLUME_MUTE,
+ KEY_GESTURE_TYPE_ALL_APPS,
+ KEY_GESTURE_TYPE_LAUNCH_SEARCH,
+ KEY_GESTURE_TYPE_LANGUAGE_SWITCH,
+ KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS,
+ KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK,
+ KEY_GESTURE_TYPE_SYSTEM_MUTE,
+ KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION,
+ KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS,
+ KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT,
+ KEY_GESTURE_TYPE_LOCK_SCREEN,
+ KEY_GESTURE_TYPE_OPEN_NOTES,
+ KEY_GESTURE_TYPE_TOGGLE_POWER,
+ KEY_GESTURE_TYPE_SYSTEM_NAVIGATION,
+ KEY_GESTURE_TYPE_SLEEP,
+ KEY_GESTURE_TYPE_WAKEUP,
+ KEY_GESTURE_TYPE_MEDIA_KEY,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER,
+ KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS,
+ KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME,
+ KEY_GESTURE_TYPE_DESKTOP_MODE,
+ KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @DataClass.Generated.Member
+ public @interface KeyGestureType {}
+
+ @DataClass.Generated.Member
+ public static String keyGestureTypeToString(@KeyGestureType int value) {
+ switch (value) {
+ case KEY_GESTURE_TYPE_UNSPECIFIED:
+ return "KEY_GESTURE_TYPE_UNSPECIFIED";
+ case KEY_GESTURE_TYPE_HOME:
+ return "KEY_GESTURE_TYPE_HOME";
+ case KEY_GESTURE_TYPE_RECENT_APPS:
+ return "KEY_GESTURE_TYPE_RECENT_APPS";
+ case KEY_GESTURE_TYPE_BACK:
+ return "KEY_GESTURE_TYPE_BACK";
+ case KEY_GESTURE_TYPE_APP_SWITCH:
+ return "KEY_GESTURE_TYPE_APP_SWITCH";
+ case KEY_GESTURE_TYPE_LAUNCH_ASSISTANT:
+ return "KEY_GESTURE_TYPE_LAUNCH_ASSISTANT";
+ case KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT:
+ return "KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT";
+ case KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS:
+ return "KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS";
+ case KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL:
+ return "KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL";
+ case KEY_GESTURE_TYPE_TOGGLE_TASKBAR:
+ return "KEY_GESTURE_TYPE_TOGGLE_TASKBAR";
+ case KEY_GESTURE_TYPE_TAKE_SCREENSHOT:
+ return "KEY_GESTURE_TYPE_TAKE_SCREENSHOT";
+ case KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER:
+ return "KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER";
+ case KEY_GESTURE_TYPE_BRIGHTNESS_UP:
+ return "KEY_GESTURE_TYPE_BRIGHTNESS_UP";
+ case KEY_GESTURE_TYPE_BRIGHTNESS_DOWN:
+ return "KEY_GESTURE_TYPE_BRIGHTNESS_DOWN";
+ case KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP:
+ return "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP";
+ case KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN:
+ return "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN";
+ case KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE:
+ return "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE";
+ case KEY_GESTURE_TYPE_VOLUME_UP:
+ return "KEY_GESTURE_TYPE_VOLUME_UP";
+ case KEY_GESTURE_TYPE_VOLUME_DOWN:
+ return "KEY_GESTURE_TYPE_VOLUME_DOWN";
+ case KEY_GESTURE_TYPE_VOLUME_MUTE:
+ return "KEY_GESTURE_TYPE_VOLUME_MUTE";
+ case KEY_GESTURE_TYPE_ALL_APPS:
+ return "KEY_GESTURE_TYPE_ALL_APPS";
+ case KEY_GESTURE_TYPE_LAUNCH_SEARCH:
+ return "KEY_GESTURE_TYPE_LAUNCH_SEARCH";
+ case KEY_GESTURE_TYPE_LANGUAGE_SWITCH:
+ return "KEY_GESTURE_TYPE_LANGUAGE_SWITCH";
+ case KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS:
+ return "KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS";
+ case KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK:
+ return "KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK";
+ case KEY_GESTURE_TYPE_SYSTEM_MUTE:
+ return "KEY_GESTURE_TYPE_SYSTEM_MUTE";
+ case KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION:
+ return "KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION";
+ case KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS:
+ return "KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS";
+ case KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT:
+ return "KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT";
+ case KEY_GESTURE_TYPE_LOCK_SCREEN:
+ return "KEY_GESTURE_TYPE_LOCK_SCREEN";
+ case KEY_GESTURE_TYPE_OPEN_NOTES:
+ return "KEY_GESTURE_TYPE_OPEN_NOTES";
+ case KEY_GESTURE_TYPE_TOGGLE_POWER:
+ return "KEY_GESTURE_TYPE_TOGGLE_POWER";
+ case KEY_GESTURE_TYPE_SYSTEM_NAVIGATION:
+ return "KEY_GESTURE_TYPE_SYSTEM_NAVIGATION";
+ case KEY_GESTURE_TYPE_SLEEP:
+ return "KEY_GESTURE_TYPE_SLEEP";
+ case KEY_GESTURE_TYPE_WAKEUP:
+ return "KEY_GESTURE_TYPE_WAKEUP";
+ case KEY_GESTURE_TYPE_MEDIA_KEY:
+ return "KEY_GESTURE_TYPE_MEDIA_KEY";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER";
+ case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS:
+ return "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS";
+ case KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME:
+ return "KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME";
+ case KEY_GESTURE_TYPE_DESKTOP_MODE:
+ return "KEY_GESTURE_TYPE_DESKTOP_MODE";
+ case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION:
+ return "KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION";
+ default: return Integer.toHexString(value);
+ }
+ }
+
+ @DataClass.Generated.Member
+ public KeyGestureEvent(
+ int deviceId,
+ @NonNull int[] keycodes,
+ int modifierState,
+ @KeyGestureType int keyGestureType) {
+ this.mDeviceId = deviceId;
+ this.mKeycodes = keycodes;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mKeycodes);
+ this.mModifierState = modifierState;
+ this.mKeyGestureType = keyGestureType;
+
+ if (!(mKeyGestureType == KEY_GESTURE_TYPE_UNSPECIFIED)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_HOME)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_RECENT_APPS)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_BACK)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_APP_SWITCH)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_ASSISTANT)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_TOGGLE_TASKBAR)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_TAKE_SCREENSHOT)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_BRIGHTNESS_UP)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_BRIGHTNESS_DOWN)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_VOLUME_UP)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_VOLUME_DOWN)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_VOLUME_MUTE)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_ALL_APPS)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_SEARCH)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LANGUAGE_SWITCH)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_SYSTEM_MUTE)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LOCK_SCREEN)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_OPEN_NOTES)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_TOGGLE_POWER)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_SYSTEM_NAVIGATION)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_SLEEP)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_WAKEUP)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_MEDIA_KEY)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_DESKTOP_MODE)
+ && !(mKeyGestureType == KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION)) {
+ throw new java.lang.IllegalArgumentException(
+ "keyGestureType was " + mKeyGestureType + " but must be one of: "
+ + "KEY_GESTURE_TYPE_UNSPECIFIED(" + KEY_GESTURE_TYPE_UNSPECIFIED + "), "
+ + "KEY_GESTURE_TYPE_HOME(" + KEY_GESTURE_TYPE_HOME + "), "
+ + "KEY_GESTURE_TYPE_RECENT_APPS(" + KEY_GESTURE_TYPE_RECENT_APPS + "), "
+ + "KEY_GESTURE_TYPE_BACK(" + KEY_GESTURE_TYPE_BACK + "), "
+ + "KEY_GESTURE_TYPE_APP_SWITCH(" + KEY_GESTURE_TYPE_APP_SWITCH + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_ASSISTANT(" + KEY_GESTURE_TYPE_LAUNCH_ASSISTANT + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT(" + KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS(" + KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS + "), "
+ + "KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL(" + KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL + "), "
+ + "KEY_GESTURE_TYPE_TOGGLE_TASKBAR(" + KEY_GESTURE_TYPE_TOGGLE_TASKBAR + "), "
+ + "KEY_GESTURE_TYPE_TAKE_SCREENSHOT(" + KEY_GESTURE_TYPE_TAKE_SCREENSHOT + "), "
+ + "KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER(" + KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER + "), "
+ + "KEY_GESTURE_TYPE_BRIGHTNESS_UP(" + KEY_GESTURE_TYPE_BRIGHTNESS_UP + "), "
+ + "KEY_GESTURE_TYPE_BRIGHTNESS_DOWN(" + KEY_GESTURE_TYPE_BRIGHTNESS_DOWN + "), "
+ + "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP(" + KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP + "), "
+ + "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN(" + KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN + "), "
+ + "KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE(" + KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE + "), "
+ + "KEY_GESTURE_TYPE_VOLUME_UP(" + KEY_GESTURE_TYPE_VOLUME_UP + "), "
+ + "KEY_GESTURE_TYPE_VOLUME_DOWN(" + KEY_GESTURE_TYPE_VOLUME_DOWN + "), "
+ + "KEY_GESTURE_TYPE_VOLUME_MUTE(" + KEY_GESTURE_TYPE_VOLUME_MUTE + "), "
+ + "KEY_GESTURE_TYPE_ALL_APPS(" + KEY_GESTURE_TYPE_ALL_APPS + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_SEARCH(" + KEY_GESTURE_TYPE_LAUNCH_SEARCH + "), "
+ + "KEY_GESTURE_TYPE_LANGUAGE_SWITCH(" + KEY_GESTURE_TYPE_LANGUAGE_SWITCH + "), "
+ + "KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS(" + KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS + "), "
+ + "KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK(" + KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK + "), "
+ + "KEY_GESTURE_TYPE_SYSTEM_MUTE(" + KEY_GESTURE_TYPE_SYSTEM_MUTE + "), "
+ + "KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION(" + KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION + "), "
+ + "KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS(" + KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS + "), "
+ + "KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT(" + KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT + "), "
+ + "KEY_GESTURE_TYPE_LOCK_SCREEN(" + KEY_GESTURE_TYPE_LOCK_SCREEN + "), "
+ + "KEY_GESTURE_TYPE_OPEN_NOTES(" + KEY_GESTURE_TYPE_OPEN_NOTES + "), "
+ + "KEY_GESTURE_TYPE_TOGGLE_POWER(" + KEY_GESTURE_TYPE_TOGGLE_POWER + "), "
+ + "KEY_GESTURE_TYPE_SYSTEM_NAVIGATION(" + KEY_GESTURE_TYPE_SYSTEM_NAVIGATION + "), "
+ + "KEY_GESTURE_TYPE_SLEEP(" + KEY_GESTURE_TYPE_SLEEP + "), "
+ + "KEY_GESTURE_TYPE_WAKEUP(" + KEY_GESTURE_TYPE_WAKEUP + "), "
+ + "KEY_GESTURE_TYPE_MEDIA_KEY(" + KEY_GESTURE_TYPE_MEDIA_KEY + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS(" + KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS + "), "
+ + "KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME(" + KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME + "), "
+ + "KEY_GESTURE_TYPE_DESKTOP_MODE(" + KEY_GESTURE_TYPE_DESKTOP_MODE + "), "
+ + "KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION(" + KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION + ")");
+ }
+
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public int getDeviceId() {
+ return mDeviceId;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull int[] getKeycodes() {
+ return mKeycodes;
+ }
+
+ @DataClass.Generated.Member
+ public int getModifierState() {
+ return mModifierState;
+ }
+
+ @DataClass.Generated.Member
+ public @KeyGestureType int getKeyGestureType() {
+ return mKeyGestureType;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "KeyGestureEvent { " +
+ "deviceId = " + mDeviceId + ", " +
+ "keycodes = " + java.util.Arrays.toString(mKeycodes) + ", " +
+ "modifierState = " + mModifierState + ", " +
+ "keyGestureType = " + keyGestureTypeToString(mKeyGestureType) +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public boolean equals(@Nullable Object o) {
+ // You can override field equality logic by defining either of the methods like:
+ // boolean fieldNameEquals(KeyGestureEvent other) { ... }
+ // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ @SuppressWarnings("unchecked")
+ KeyGestureEvent that = (KeyGestureEvent) o;
+ //noinspection PointlessBooleanExpression
+ return true
+ && mDeviceId == that.mDeviceId
+ && java.util.Arrays.equals(mKeycodes, that.mKeycodes)
+ && mModifierState == that.mModifierState
+ && mKeyGestureType == that.mKeyGestureType;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int hashCode() {
+ // You can override field hashCode logic by defining methods like:
+ // int fieldNameHashCode() { ... }
+
+ int _hash = 1;
+ _hash = 31 * _hash + mDeviceId;
+ _hash = 31 * _hash + java.util.Arrays.hashCode(mKeycodes);
+ _hash = 31 * _hash + mModifierState;
+ _hash = 31 * _hash + mKeyGestureType;
+ return _hash;
+ }
+
+ @DataClass.Generated(
+ time = 1723409092192L,
+ codegenVersion = "1.0.23",
+ sourceFile = "frameworks/base/core/java/android/hardware/input/KeyGestureEvent.java",
+ inputSignatures = "private final int mDeviceId\nprivate final @android.annotation.NonNull int[] mKeycodes\nprivate final int mModifierState\nprivate final @android.hardware.input.KeyGestureEvent.KeyGestureType int mKeyGestureType\npublic static final int KEY_GESTURE_TYPE_UNSPECIFIED\npublic static final int KEY_GESTURE_TYPE_HOME\npublic static final int KEY_GESTURE_TYPE_RECENT_APPS\npublic static final int KEY_GESTURE_TYPE_BACK\npublic static final int KEY_GESTURE_TYPE_APP_SWITCH\npublic static final int KEY_GESTURE_TYPE_LAUNCH_ASSISTANT\npublic static final int KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT\npublic static final int KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS\npublic static final int KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL\npublic static final int KEY_GESTURE_TYPE_TOGGLE_TASKBAR\npublic static final int KEY_GESTURE_TYPE_TAKE_SCREENSHOT\npublic static final int KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER\npublic static final int KEY_GESTURE_TYPE_BRIGHTNESS_UP\npublic static final int KEY_GESTURE_TYPE_BRIGHTNESS_DOWN\npublic static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP\npublic static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN\npublic static final int KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE\npublic static final int KEY_GESTURE_TYPE_VOLUME_UP\npublic static final int KEY_GESTURE_TYPE_VOLUME_DOWN\npublic static final int KEY_GESTURE_TYPE_VOLUME_MUTE\npublic static final int KEY_GESTURE_TYPE_ALL_APPS\npublic static final int KEY_GESTURE_TYPE_LAUNCH_SEARCH\npublic static final int KEY_GESTURE_TYPE_LANGUAGE_SWITCH\npublic static final int KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS\npublic static final int KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK\npublic static final int KEY_GESTURE_TYPE_SYSTEM_MUTE\npublic static final int KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION\npublic static final int KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS\npublic static final int KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT\npublic static final int KEY_GESTURE_TYPE_LOCK_SCREEN\npublic static final int KEY_GESTURE_TYPE_OPEN_NOTES\npublic static final int KEY_GESTURE_TYPE_TOGGLE_POWER\npublic static final int KEY_GESTURE_TYPE_SYSTEM_NAVIGATION\npublic static final int KEY_GESTURE_TYPE_SLEEP\npublic static final int KEY_GESTURE_TYPE_WAKEUP\npublic static final int KEY_GESTURE_TYPE_MEDIA_KEY\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER\npublic static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS\npublic static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME\npublic static final int KEY_GESTURE_TYPE_DESKTOP_MODE\npublic static final int KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION\nclass KeyGestureEvent extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true)")
+ @Deprecated
+ private void __metadata() {}
+
+
+ //@formatter:on
+ // End of generated code
+
+}
diff --git a/core/java/android/hardware/input/KeyboardSystemShortcut.java b/core/java/android/hardware/input/KeyboardSystemShortcut.java
deleted file mode 100644
index 89cf877..0000000
--- a/core/java/android/hardware/input/KeyboardSystemShortcut.java
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.input;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import com.android.internal.util.DataClass;
-import com.android.internal.util.FrameworkStatsLog;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Provides information about the keyboard shortcut being triggered by an external keyboard.
- *
- * @hide
- */
-@DataClass(genToString = true, genEqualsHashCode = true)
-public class KeyboardSystemShortcut {
-
- private static final String TAG = "KeyboardSystemShortcut";
-
- @NonNull
- private final int[] mKeycodes;
- private final int mModifierState;
- @SystemShortcut
- private final int mSystemShortcut;
-
-
- public static final int SYSTEM_SHORTCUT_UNSPECIFIED =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED;
- public static final int SYSTEM_SHORTCUT_HOME =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME;
- public static final int SYSTEM_SHORTCUT_RECENT_APPS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RECENT_APPS;
- public static final int SYSTEM_SHORTCUT_BACK =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BACK;
- public static final int SYSTEM_SHORTCUT_APP_SWITCH =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__APP_SWITCH;
- public static final int SYSTEM_SHORTCUT_LAUNCH_ASSISTANT =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_ASSISTANT;
- public static final int SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_VOICE_ASSISTANT;
- public static final int SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SYSTEM_SETTINGS;
- public static final int SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_NOTIFICATION_PANEL;
- public static final int SYSTEM_SHORTCUT_TOGGLE_TASKBAR =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_TASKBAR;
- public static final int SYSTEM_SHORTCUT_TAKE_SCREENSHOT =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TAKE_SCREENSHOT;
- public static final int SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_SHORTCUT_HELPER;
- public static final int SYSTEM_SHORTCUT_BRIGHTNESS_UP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_UP;
- public static final int SYSTEM_SHORTCUT_BRIGHTNESS_DOWN =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_DOWN;
- public static final int SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_UP;
- public static final int SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_DOWN;
- public static final int SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_TOGGLE;
- public static final int SYSTEM_SHORTCUT_VOLUME_UP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_UP;
- public static final int SYSTEM_SHORTCUT_VOLUME_DOWN =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_DOWN;
- public static final int SYSTEM_SHORTCUT_VOLUME_MUTE =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_MUTE;
- public static final int SYSTEM_SHORTCUT_ALL_APPS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ALL_APPS;
- public static final int SYSTEM_SHORTCUT_LAUNCH_SEARCH =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SEARCH;
- public static final int SYSTEM_SHORTCUT_LANGUAGE_SWITCH =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LANGUAGE_SWITCH;
- public static final int SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ACCESSIBILITY_ALL_APPS;
- public static final int SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_CAPS_LOCK;
- public static final int SYSTEM_SHORTCUT_SYSTEM_MUTE =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_MUTE;
- public static final int SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SPLIT_SCREEN_NAVIGATION;
- public static final int SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__CHANGE_SPLITSCREEN_FOCUS;
- public static final int SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TRIGGER_BUG_REPORT;
- public static final int SYSTEM_SHORTCUT_LOCK_SCREEN =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LOCK_SCREEN;
- public static final int SYSTEM_SHORTCUT_OPEN_NOTES =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_NOTES;
- public static final int SYSTEM_SHORTCUT_TOGGLE_POWER =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_POWER;
- public static final int SYSTEM_SHORTCUT_SYSTEM_NAVIGATION =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_NAVIGATION;
- public static final int SYSTEM_SHORTCUT_SLEEP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SLEEP;
- public static final int SYSTEM_SHORTCUT_WAKEUP =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__WAKEUP;
- public static final int SYSTEM_SHORTCUT_MEDIA_KEY =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MEDIA_KEY;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_EMAIL;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CONTACTS;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALENDAR;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALCULATOR;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MUSIC;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MAPS;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_GALLERY =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_GALLERY;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FILES =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FILES;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_WEATHER =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER;
- public static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FITNESS =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS;
- public static final int SYSTEM_SHORTCUT_LAUNCH_APPLICATION_BY_PACKAGE_NAME =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME;
- public static final int SYSTEM_SHORTCUT_DESKTOP_MODE =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE;
- public static final int SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION =
- FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION;
-
-
-
- // Code below generated by codegen v1.0.23.
- //
- // DO NOT MODIFY!
- // CHECKSTYLE:OFF Generated code
- //
- // To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/hardware/input/KeyboardSystemShortcut.java
- //
- // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
- // Settings > Editor > Code Style > Formatter Control
- //@formatter:off
-
-
- @IntDef(prefix = "SYSTEM_SHORTCUT_", value = {
- SYSTEM_SHORTCUT_UNSPECIFIED,
- SYSTEM_SHORTCUT_HOME,
- SYSTEM_SHORTCUT_RECENT_APPS,
- SYSTEM_SHORTCUT_BACK,
- SYSTEM_SHORTCUT_APP_SWITCH,
- SYSTEM_SHORTCUT_LAUNCH_ASSISTANT,
- SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT,
- SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS,
- SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL,
- SYSTEM_SHORTCUT_TOGGLE_TASKBAR,
- SYSTEM_SHORTCUT_TAKE_SCREENSHOT,
- SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER,
- SYSTEM_SHORTCUT_BRIGHTNESS_UP,
- SYSTEM_SHORTCUT_BRIGHTNESS_DOWN,
- SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP,
- SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN,
- SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE,
- SYSTEM_SHORTCUT_VOLUME_UP,
- SYSTEM_SHORTCUT_VOLUME_DOWN,
- SYSTEM_SHORTCUT_VOLUME_MUTE,
- SYSTEM_SHORTCUT_ALL_APPS,
- SYSTEM_SHORTCUT_LAUNCH_SEARCH,
- SYSTEM_SHORTCUT_LANGUAGE_SWITCH,
- SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS,
- SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK,
- SYSTEM_SHORTCUT_SYSTEM_MUTE,
- SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION,
- SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS,
- SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT,
- SYSTEM_SHORTCUT_LOCK_SCREEN,
- SYSTEM_SHORTCUT_OPEN_NOTES,
- SYSTEM_SHORTCUT_TOGGLE_POWER,
- SYSTEM_SHORTCUT_SYSTEM_NAVIGATION,
- SYSTEM_SHORTCUT_SLEEP,
- SYSTEM_SHORTCUT_WAKEUP,
- SYSTEM_SHORTCUT_MEDIA_KEY,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_GALLERY,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FILES,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_WEATHER,
- SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FITNESS,
- SYSTEM_SHORTCUT_LAUNCH_APPLICATION_BY_PACKAGE_NAME,
- SYSTEM_SHORTCUT_DESKTOP_MODE,
- SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION
- })
- @Retention(RetentionPolicy.SOURCE)
- @DataClass.Generated.Member
- public @interface SystemShortcut {}
-
- @DataClass.Generated.Member
- public static String systemShortcutToString(@SystemShortcut int value) {
- switch (value) {
- case SYSTEM_SHORTCUT_UNSPECIFIED:
- return "SYSTEM_SHORTCUT_UNSPECIFIED";
- case SYSTEM_SHORTCUT_HOME:
- return "SYSTEM_SHORTCUT_HOME";
- case SYSTEM_SHORTCUT_RECENT_APPS:
- return "SYSTEM_SHORTCUT_RECENT_APPS";
- case SYSTEM_SHORTCUT_BACK:
- return "SYSTEM_SHORTCUT_BACK";
- case SYSTEM_SHORTCUT_APP_SWITCH:
- return "SYSTEM_SHORTCUT_APP_SWITCH";
- case SYSTEM_SHORTCUT_LAUNCH_ASSISTANT:
- return "SYSTEM_SHORTCUT_LAUNCH_ASSISTANT";
- case SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT:
- return "SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT";
- case SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS:
- return "SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS";
- case SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL:
- return "SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL";
- case SYSTEM_SHORTCUT_TOGGLE_TASKBAR:
- return "SYSTEM_SHORTCUT_TOGGLE_TASKBAR";
- case SYSTEM_SHORTCUT_TAKE_SCREENSHOT:
- return "SYSTEM_SHORTCUT_TAKE_SCREENSHOT";
- case SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER:
- return "SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER";
- case SYSTEM_SHORTCUT_BRIGHTNESS_UP:
- return "SYSTEM_SHORTCUT_BRIGHTNESS_UP";
- case SYSTEM_SHORTCUT_BRIGHTNESS_DOWN:
- return "SYSTEM_SHORTCUT_BRIGHTNESS_DOWN";
- case SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP:
- return "SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP";
- case SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN:
- return "SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN";
- case SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE:
- return "SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE";
- case SYSTEM_SHORTCUT_VOLUME_UP:
- return "SYSTEM_SHORTCUT_VOLUME_UP";
- case SYSTEM_SHORTCUT_VOLUME_DOWN:
- return "SYSTEM_SHORTCUT_VOLUME_DOWN";
- case SYSTEM_SHORTCUT_VOLUME_MUTE:
- return "SYSTEM_SHORTCUT_VOLUME_MUTE";
- case SYSTEM_SHORTCUT_ALL_APPS:
- return "SYSTEM_SHORTCUT_ALL_APPS";
- case SYSTEM_SHORTCUT_LAUNCH_SEARCH:
- return "SYSTEM_SHORTCUT_LAUNCH_SEARCH";
- case SYSTEM_SHORTCUT_LANGUAGE_SWITCH:
- return "SYSTEM_SHORTCUT_LANGUAGE_SWITCH";
- case SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS:
- return "SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS";
- case SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK:
- return "SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK";
- case SYSTEM_SHORTCUT_SYSTEM_MUTE:
- return "SYSTEM_SHORTCUT_SYSTEM_MUTE";
- case SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION:
- return "SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION";
- case SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS:
- return "SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS";
- case SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT:
- return "SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT";
- case SYSTEM_SHORTCUT_LOCK_SCREEN:
- return "SYSTEM_SHORTCUT_LOCK_SCREEN";
- case SYSTEM_SHORTCUT_OPEN_NOTES:
- return "SYSTEM_SHORTCUT_OPEN_NOTES";
- case SYSTEM_SHORTCUT_TOGGLE_POWER:
- return "SYSTEM_SHORTCUT_TOGGLE_POWER";
- case SYSTEM_SHORTCUT_SYSTEM_NAVIGATION:
- return "SYSTEM_SHORTCUT_SYSTEM_NAVIGATION";
- case SYSTEM_SHORTCUT_SLEEP:
- return "SYSTEM_SHORTCUT_SLEEP";
- case SYSTEM_SHORTCUT_WAKEUP:
- return "SYSTEM_SHORTCUT_WAKEUP";
- case SYSTEM_SHORTCUT_MEDIA_KEY:
- return "SYSTEM_SHORTCUT_MEDIA_KEY";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_GALLERY:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_GALLERY";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FILES:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FILES";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_WEATHER:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_WEATHER";
- case SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FITNESS:
- return "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FITNESS";
- case SYSTEM_SHORTCUT_LAUNCH_APPLICATION_BY_PACKAGE_NAME:
- return "SYSTEM_SHORTCUT_LAUNCH_APPLICATION_BY_PACKAGE_NAME";
- case SYSTEM_SHORTCUT_DESKTOP_MODE:
- return "SYSTEM_SHORTCUT_DESKTOP_MODE";
- case SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION:
- return "SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION";
- default: return Integer.toHexString(value);
- }
- }
-
- @DataClass.Generated.Member
- public KeyboardSystemShortcut(
- @NonNull int[] keycodes,
- int modifierState,
- @SystemShortcut int systemShortcut) {
- this.mKeycodes = keycodes;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mKeycodes);
- this.mModifierState = modifierState;
- this.mSystemShortcut = systemShortcut;
-
- if (!(mSystemShortcut == SYSTEM_SHORTCUT_UNSPECIFIED)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_HOME)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_RECENT_APPS)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_BACK)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_APP_SWITCH)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_ASSISTANT)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_TOGGLE_TASKBAR)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_TAKE_SCREENSHOT)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_BRIGHTNESS_UP)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_BRIGHTNESS_DOWN)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_VOLUME_UP)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_VOLUME_DOWN)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_VOLUME_MUTE)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_ALL_APPS)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_SEARCH)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LANGUAGE_SWITCH)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_SYSTEM_MUTE)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LOCK_SCREEN)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_OPEN_NOTES)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_TOGGLE_POWER)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_SYSTEM_NAVIGATION)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_SLEEP)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_WAKEUP)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_MEDIA_KEY)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_GALLERY)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FILES)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_WEATHER)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FITNESS)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_LAUNCH_APPLICATION_BY_PACKAGE_NAME)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_DESKTOP_MODE)
- && !(mSystemShortcut == SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION)) {
- throw new java.lang.IllegalArgumentException(
- "systemShortcut was " + mSystemShortcut + " but must be one of: "
- + "SYSTEM_SHORTCUT_UNSPECIFIED(" + SYSTEM_SHORTCUT_UNSPECIFIED + "), "
- + "SYSTEM_SHORTCUT_HOME(" + SYSTEM_SHORTCUT_HOME + "), "
- + "SYSTEM_SHORTCUT_RECENT_APPS(" + SYSTEM_SHORTCUT_RECENT_APPS + "), "
- + "SYSTEM_SHORTCUT_BACK(" + SYSTEM_SHORTCUT_BACK + "), "
- + "SYSTEM_SHORTCUT_APP_SWITCH(" + SYSTEM_SHORTCUT_APP_SWITCH + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_ASSISTANT(" + SYSTEM_SHORTCUT_LAUNCH_ASSISTANT + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT(" + SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS(" + SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS + "), "
- + "SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL(" + SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL + "), "
- + "SYSTEM_SHORTCUT_TOGGLE_TASKBAR(" + SYSTEM_SHORTCUT_TOGGLE_TASKBAR + "), "
- + "SYSTEM_SHORTCUT_TAKE_SCREENSHOT(" + SYSTEM_SHORTCUT_TAKE_SCREENSHOT + "), "
- + "SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER(" + SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER + "), "
- + "SYSTEM_SHORTCUT_BRIGHTNESS_UP(" + SYSTEM_SHORTCUT_BRIGHTNESS_UP + "), "
- + "SYSTEM_SHORTCUT_BRIGHTNESS_DOWN(" + SYSTEM_SHORTCUT_BRIGHTNESS_DOWN + "), "
- + "SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP(" + SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP + "), "
- + "SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN(" + SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN + "), "
- + "SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE(" + SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE + "), "
- + "SYSTEM_SHORTCUT_VOLUME_UP(" + SYSTEM_SHORTCUT_VOLUME_UP + "), "
- + "SYSTEM_SHORTCUT_VOLUME_DOWN(" + SYSTEM_SHORTCUT_VOLUME_DOWN + "), "
- + "SYSTEM_SHORTCUT_VOLUME_MUTE(" + SYSTEM_SHORTCUT_VOLUME_MUTE + "), "
- + "SYSTEM_SHORTCUT_ALL_APPS(" + SYSTEM_SHORTCUT_ALL_APPS + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_SEARCH(" + SYSTEM_SHORTCUT_LAUNCH_SEARCH + "), "
- + "SYSTEM_SHORTCUT_LANGUAGE_SWITCH(" + SYSTEM_SHORTCUT_LANGUAGE_SWITCH + "), "
- + "SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS(" + SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS + "), "
- + "SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK(" + SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK + "), "
- + "SYSTEM_SHORTCUT_SYSTEM_MUTE(" + SYSTEM_SHORTCUT_SYSTEM_MUTE + "), "
- + "SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION(" + SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION + "), "
- + "SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS(" + SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS + "), "
- + "SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT(" + SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT + "), "
- + "SYSTEM_SHORTCUT_LOCK_SCREEN(" + SYSTEM_SHORTCUT_LOCK_SCREEN + "), "
- + "SYSTEM_SHORTCUT_OPEN_NOTES(" + SYSTEM_SHORTCUT_OPEN_NOTES + "), "
- + "SYSTEM_SHORTCUT_TOGGLE_POWER(" + SYSTEM_SHORTCUT_TOGGLE_POWER + "), "
- + "SYSTEM_SHORTCUT_SYSTEM_NAVIGATION(" + SYSTEM_SHORTCUT_SYSTEM_NAVIGATION + "), "
- + "SYSTEM_SHORTCUT_SLEEP(" + SYSTEM_SHORTCUT_SLEEP + "), "
- + "SYSTEM_SHORTCUT_WAKEUP(" + SYSTEM_SHORTCUT_WAKEUP + "), "
- + "SYSTEM_SHORTCUT_MEDIA_KEY(" + SYSTEM_SHORTCUT_MEDIA_KEY + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_GALLERY(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_GALLERY + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FILES(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FILES + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_WEATHER(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_WEATHER + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FITNESS(" + SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FITNESS + "), "
- + "SYSTEM_SHORTCUT_LAUNCH_APPLICATION_BY_PACKAGE_NAME(" + SYSTEM_SHORTCUT_LAUNCH_APPLICATION_BY_PACKAGE_NAME + "), "
- + "SYSTEM_SHORTCUT_DESKTOP_MODE(" + SYSTEM_SHORTCUT_DESKTOP_MODE + "), "
- + "SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION(" + SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION + ")");
- }
-
-
- // onConstructed(); // You can define this method to get a callback
- }
-
- @DataClass.Generated.Member
- public @NonNull int[] getKeycodes() {
- return mKeycodes;
- }
-
- @DataClass.Generated.Member
- public int getModifierState() {
- return mModifierState;
- }
-
- @DataClass.Generated.Member
- public @SystemShortcut int getSystemShortcut() {
- return mSystemShortcut;
- }
-
- @Override
- @DataClass.Generated.Member
- public String toString() {
- // You can override field toString logic by defining methods like:
- // String fieldNameToString() { ... }
-
- return "KeyboardSystemShortcut { " +
- "keycodes = " + java.util.Arrays.toString(mKeycodes) + ", " +
- "modifierState = " + mModifierState + ", " +
- "systemShortcut = " + systemShortcutToString(mSystemShortcut) +
- " }";
- }
-
- @Override
- @DataClass.Generated.Member
- public boolean equals(@Nullable Object o) {
- // You can override field equality logic by defining either of the methods like:
- // boolean fieldNameEquals(KeyboardSystemShortcut other) { ... }
- // boolean fieldNameEquals(FieldType otherValue) { ... }
-
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- @SuppressWarnings("unchecked")
- KeyboardSystemShortcut that = (KeyboardSystemShortcut) o;
- //noinspection PointlessBooleanExpression
- return true
- && java.util.Arrays.equals(mKeycodes, that.mKeycodes)
- && mModifierState == that.mModifierState
- && mSystemShortcut == that.mSystemShortcut;
- }
-
- @Override
- @DataClass.Generated.Member
- public int hashCode() {
- // You can override field hashCode logic by defining methods like:
- // int fieldNameHashCode() { ... }
-
- int _hash = 1;
- _hash = 31 * _hash + java.util.Arrays.hashCode(mKeycodes);
- _hash = 31 * _hash + mModifierState;
- _hash = 31 * _hash + mSystemShortcut;
- return _hash;
- }
-
- @DataClass.Generated(
- time = 1722890917041L,
- codegenVersion = "1.0.23",
- sourceFile = "frameworks/base/core/java/android/hardware/input/KeyboardSystemShortcut.java",
- inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.NonNull int[] mKeycodes\nprivate final int mModifierState\nprivate final @android.hardware.input.KeyboardSystemShortcut.SystemShortcut int mSystemShortcut\npublic static final int SYSTEM_SHORTCUT_UNSPECIFIED\npublic static final int SYSTEM_SHORTCUT_HOME\npublic static final int SYSTEM_SHORTCUT_RECENT_APPS\npublic static final int SYSTEM_SHORTCUT_BACK\npublic static final int SYSTEM_SHORTCUT_APP_SWITCH\npublic static final int SYSTEM_SHORTCUT_LAUNCH_ASSISTANT\npublic static final int SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT\npublic static final int SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS\npublic static final int SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL\npublic static final int SYSTEM_SHORTCUT_TOGGLE_TASKBAR\npublic static final int SYSTEM_SHORTCUT_TAKE_SCREENSHOT\npublic static final int SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER\npublic static final int SYSTEM_SHORTCUT_BRIGHTNESS_UP\npublic static final int SYSTEM_SHORTCUT_BRIGHTNESS_DOWN\npublic static final int SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP\npublic static final int SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN\npublic static final int SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE\npublic static final int SYSTEM_SHORTCUT_VOLUME_UP\npublic static final int SYSTEM_SHORTCUT_VOLUME_DOWN\npublic static final int SYSTEM_SHORTCUT_VOLUME_MUTE\npublic static final int SYSTEM_SHORTCUT_ALL_APPS\npublic static final int SYSTEM_SHORTCUT_LAUNCH_SEARCH\npublic static final int SYSTEM_SHORTCUT_LANGUAGE_SWITCH\npublic static final int SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS\npublic static final int SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK\npublic static final int SYSTEM_SHORTCUT_SYSTEM_MUTE\npublic static final int SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION\npublic static final int SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS\npublic static final int SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT\npublic static final int SYSTEM_SHORTCUT_LOCK_SCREEN\npublic static final int SYSTEM_SHORTCUT_OPEN_NOTES\npublic static final int SYSTEM_SHORTCUT_TOGGLE_POWER\npublic static final int SYSTEM_SHORTCUT_SYSTEM_NAVIGATION\npublic static final int SYSTEM_SHORTCUT_SLEEP\npublic static final int SYSTEM_SHORTCUT_WAKEUP\npublic static final int SYSTEM_SHORTCUT_MEDIA_KEY\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_GALLERY\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FILES\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_WEATHER\npublic static final int SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FITNESS\npublic static final int SYSTEM_SHORTCUT_LAUNCH_APPLICATION_BY_PACKAGE_NAME\npublic static final int SYSTEM_SHORTCUT_DESKTOP_MODE\npublic static final int SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION\nclass KeyboardSystemShortcut extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true)")
- @Deprecated
- private void __metadata() {}
-
-
- //@formatter:on
- // End of generated code
-
-}
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 3fe063d..4c4aa6c 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -223,3 +223,14 @@
description: "Show access entry of location bypass permission in the Privacy Dashboard"
bug: "325536053"
}
+
+flag {
+ name: "dont_remove_existing_uid_states"
+ is_fixed_read_only: true
+ namespace: "permissions"
+ description: "Double check if the uid still exists before attempting to remove its appops state"
+ bug: "353474742"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig
index 5c5a2f6..1c3d738 100644
--- a/core/java/android/text/flags/flags.aconfig
+++ b/core/java/android/text/flags/flags.aconfig
@@ -276,4 +276,14 @@
metadata {
purpose: PURPOSE_BUGFIX
}
-}
\ No newline at end of file
+}
+
+flag {
+ name: "context_menu_hide_unavailable_items"
+ namespace: "text"
+ description: "Hide rather than disable unavailable Editor context menu items."
+ bug: "345709107"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 0cb96df..61ee13a 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -91,6 +91,14 @@
}
flag {
+ name: "transit_tracker_plumbing"
+ namespace: "windowing_frontend"
+ description: "Plumb and collect on transition tracking object instead of singleton"
+ bug: "325114242"
+ is_fixed_read_only: true
+}
+
+flag {
name: "transit_ready_tracking"
namespace: "windowing_frontend"
description: "Enable accurate transition readiness tracking"
diff --git a/core/jni/android_database_SQLiteRawStatement.cpp b/core/jni/android_database_SQLiteRawStatement.cpp
index 9614864..85a6bdf 100644
--- a/core/jni/android_database_SQLiteRawStatement.cpp
+++ b/core/jni/android_database_SQLiteRawStatement.cpp
@@ -72,14 +72,17 @@
// This throws a SQLiteBindOrColumnIndexOutOfRangeException if the column index is out
-// of bounds.
-static void throwIfInvalidColumn(JNIEnv *env, jlong stmtPtr, jint col) {
+// of bounds. It returns true if an exception was thrown.
+static bool throwIfInvalidColumn(JNIEnv *env, jlong stmtPtr, jint col) {
if (col < 0 || col >= sqlite3_data_count(stmt(stmtPtr))) {
int count = sqlite3_data_count(stmt(stmtPtr));
std::string message = android::base::StringPrintf(
"column index %d out of bounds [0,%d]", col, count - 1);
char const * errmsg = sqlite3_errstr(SQLITE_RANGE);
throw_sqlite3_exception(env, SQLITE_RANGE, errmsg, message.c_str());
+ return true;
+ } else {
+ return false;
}
}
@@ -216,12 +219,16 @@
static jint columnType(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
- throwIfInvalidColumn(env, stmtPtr, col);
+ if (throwIfInvalidColumn(env, stmtPtr, col)) {
+ return 0;
+ }
return sqlite3_column_type(stmt(stmtPtr), col);
}
static jstring columnName(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
- throwIfInvalidColumn(env, stmtPtr, col);
+ if (throwIfInvalidColumn(env, stmtPtr, col)) {
+ return nullptr;
+ }
const jchar* name = static_cast<const jchar*>(sqlite3_column_name16(stmt(stmtPtr), col));
if (name == nullptr) {
throw_sqlite3_exception(env, db(stmtPtr), "error fetching columnName()");
@@ -232,14 +239,18 @@
}
static jint columnBytes(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
- throwIfInvalidColumn(env, stmtPtr, col);
+ if (throwIfInvalidColumn(env, stmtPtr, col)) {
+ return 0;
+ }
int r = sqlite3_column_bytes16(stmt(stmtPtr), col);
throwIfError(env, stmtPtr);
return r;
}
static jbyteArray columnBlob(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
- throwIfInvalidColumn(env, stmtPtr, col);
+ if (throwIfInvalidColumn(env, stmtPtr, col)) {
+ return nullptr;
+ }
const void* blob = sqlite3_column_blob(stmt(stmtPtr), col);
if (blob == nullptr) {
if (throwIfError(env, stmtPtr)) {
@@ -262,7 +273,9 @@
static int columnBuffer(JNIEnv* env, jclass, jlong stmtPtr, jint col,
jbyteArray buffer, jint offset, jint length, jint srcOffset) {
- throwIfInvalidColumn(env, stmtPtr, col);
+ if (throwIfInvalidColumn(env, stmtPtr, col)) {
+ return 0;
+ }
const void* blob = sqlite3_column_blob(stmt(stmtPtr), col);
if (blob == nullptr) {
throwIfError(env, stmtPtr);
@@ -281,22 +294,30 @@
}
static jdouble columnDouble(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
- throwIfInvalidColumn(env, stmtPtr, col);
+ if (throwIfInvalidColumn(env, stmtPtr, col)) {
+ return 0;
+ }
return sqlite3_column_double(stmt(stmtPtr), col);
}
static jint columnInt(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
- throwIfInvalidColumn(env, stmtPtr, col);
+ if (throwIfInvalidColumn(env, stmtPtr, col)) {
+ return 0;
+ }
return sqlite3_column_int(stmt(stmtPtr), col);
}
static jlong columnLong(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
- throwIfInvalidColumn(env, stmtPtr, col);
+ if (throwIfInvalidColumn(env, stmtPtr, col)) {
+ return 0;
+ }
return sqlite3_column_int64(stmt(stmtPtr), col);
}
static jstring columnText(JNIEnv* env, jclass, jlong stmtPtr, jint col) {
- throwIfInvalidColumn(env, stmtPtr, col);
+ if (throwIfInvalidColumn(env, stmtPtr, col)) {
+ return nullptr;
+ }
const jchar* text = static_cast<const jchar*>(sqlite3_column_text16(stmt(stmtPtr), col));
if (text == nullptr) {
throwIfError(env, stmtPtr);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7aeabee..117041a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -8132,10 +8132,10 @@
<permission android:name="android.permission.MONITOR_STICKY_MODIFIER_STATE"
android:protectionLevel="signature" />
- <!-- Allows low-level access to monitor keyboard system shortcuts
+ <!-- Allows low-level access to manage key gestures.
<p>Not for use by third-party applications.
@hide -->
- <permission android:name="android.permission.MONITOR_KEYBOARD_SYSTEM_SHORTCUTS"
+ <permission android:name="android.permission.MANAGE_KEY_GESTURES"
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.HANDLE_QUERY_PACKAGE_RESTART" />
diff --git a/core/res/res/drawable/ic_zen_mode_icon_animal_paw.xml b/core/res/res/drawable/ic_zen_mode_icon_animal_paw.xml
new file mode 100644
index 0000000..31004ec
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_animal_paw.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M180,485Q138,485 109,456Q80,427 80,385Q80,343 109,314Q138,285 180,285Q222,285 251,314Q280,343 280,385Q280,427 251,456Q222,485 180,485ZM360,325Q318,325 289,296Q260,267 260,225Q260,183 289,154Q318,125 360,125Q402,125 431,154Q460,183 460,225Q460,267 431,296Q402,325 360,325ZM600,325Q558,325 529,296Q500,267 500,225Q500,183 529,154Q558,125 600,125Q642,125 671,154Q700,183 700,225Q700,267 671,296Q642,325 600,325ZM780,485Q738,485 709,456Q680,427 680,385Q680,343 709,314Q738,285 780,285Q822,285 851,314Q880,343 880,385Q880,427 851,456Q822,485 780,485ZM266,885Q221,885 190.5,850.5Q160,816 160,769Q160,717 195.5,678Q231,639 266,601Q295,570 316,533.5Q337,497 366,465Q388,439 417,422Q446,405 480,405Q514,405 543,421Q572,437 594,463Q622,495 643.5,532Q665,569 694,601Q729,639 764.5,678Q800,717 800,769Q800,816 769.5,850.5Q739,885 694,885Q640,885 587,876Q534,867 480,867Q426,867 373,876Q320,885 266,885Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_apartment_building.xml b/core/res/res/drawable/ic_zen_mode_icon_apartment_building.xml
new file mode 100644
index 0000000..30f01fa
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_apartment_building.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M120,840L120,280L280,280L280,120L680,120L680,440L840,440L840,840L520,840L520,680L440,680L440,840L120,840ZM200,760L280,760L280,680L200,680L200,760ZM200,600L280,600L280,520L200,520L200,600ZM200,440L280,440L280,360L200,360L200,440ZM360,600L440,600L440,520L360,520L360,600ZM360,440L440,440L440,360L360,360L360,440ZM360,280L440,280L440,200L360,200L360,280ZM520,600L600,600L600,520L520,520L520,600ZM520,440L600,440L600,360L520,360L520,440ZM520,280L600,280L600,200L520,200L520,280ZM680,760L760,760L760,680L680,680L680,760ZM680,600L760,600L760,520L680,520L680,600Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_book.xml b/core/res/res/drawable/ic_zen_mode_icon_book.xml
new file mode 100644
index 0000000..c30d222
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_book.xml
@@ -0,0 +1,26 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960"
+ android:autoMirrored="true">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M560,396L560,328Q593,314 627.5,307Q662,300 700,300Q726,300 751,304Q776,308 800,314L800,378Q776,369 751.5,364.5Q727,360 700,360Q662,360 627,369.5Q592,379 560,396ZM560,616L560,548Q593,534 627.5,527Q662,520 700,520Q726,520 751,524Q776,528 800,534L800,598Q776,589 751.5,584.5Q727,580 700,580Q662,580 627,589Q592,598 560,616ZM560,506L560,438Q593,424 627.5,417Q662,410 700,410Q726,410 751,414Q776,418 800,424L800,488Q776,479 751.5,474.5Q727,470 700,470Q662,470 627,479.5Q592,489 560,506ZM260,640Q307,640 351.5,650.5Q396,661 440,682L440,288Q399,264 353,252Q307,240 260,240Q224,240 188.5,247Q153,254 120,268Q120,268 120,268Q120,268 120,268L120,664Q120,664 120,664Q120,664 120,664Q155,652 189.5,646Q224,640 260,640ZM520,682Q564,661 608.5,650.5Q653,640 700,640Q736,640 770.5,646Q805,652 840,664Q840,664 840,664Q840,664 840,664L840,268Q840,268 840,268Q840,268 840,268Q807,254 771.5,247Q736,240 700,240Q653,240 607,252Q561,264 520,288L520,682ZM480,800Q432,762 376,741Q320,720 260,720Q218,720 177.5,731Q137,742 100,762Q79,773 59.5,761Q40,749 40,726L40,244Q40,233 45.5,223Q51,213 62,208Q108,184 158,172Q208,160 260,160Q318,160 373.5,175Q429,190 480,220Q531,190 586.5,175Q642,160 700,160Q752,160 802,172Q852,184 898,208Q909,213 914.5,223Q920,233 920,244L920,726Q920,749 900.5,761Q881,773 860,762Q823,742 782.5,731Q742,720 700,720Q640,720 584,741Q528,762 480,800ZM280,466Q280,466 280,466Q280,466 280,466L280,466Q280,466 280,466Q280,466 280,466Q280,466 280,466Q280,466 280,466Q280,466 280,466Q280,466 280,466L280,466Q280,466 280,466Q280,466 280,466Q280,466 280,466Q280,466 280,466Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_child.xml b/core/res/res/drawable/ic_zen_mode_icon_child.xml
new file mode 100644
index 0000000..d11772a
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_child.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M580,470Q559,470 544.5,455.5Q530,441 530,420Q530,399 544.5,384.5Q559,370 580,370Q601,370 615.5,384.5Q630,399 630,420Q630,441 615.5,455.5Q601,470 580,470ZM380,470Q359,470 344.5,455.5Q330,441 330,420Q330,399 344.5,384.5Q359,370 380,370Q401,370 415.5,384.5Q430,399 430,420Q430,441 415.5,455.5Q401,470 380,470ZM480,680Q420,680 371.5,647Q323,614 300,560L660,560Q637,614 588.5,647Q540,680 480,680ZM480,840Q405,840 339.5,811.5Q274,783 225.5,734.5Q177,686 148.5,620.5Q120,555 120,480Q120,405 148.5,339.5Q177,274 225.5,225.5Q274,177 339.5,148.5Q405,120 480,120Q555,120 620.5,148.5Q686,177 734.5,225.5Q783,274 811.5,339.5Q840,405 840,480Q840,555 811.5,620.5Q783,686 734.5,734.5Q686,783 620.5,811.5Q555,840 480,840ZM480,760Q596,760 678,678Q760,596 760,480Q760,364 678,282Q596,200 480,200Q474,200 468,200Q462,200 456,202Q450,208 448,215Q446,222 446,230Q446,251 460.5,265.5Q475,280 496,280Q505,280 512.5,277Q520,274 528,274Q540,274 548,283Q556,292 556,304Q556,327 534.5,333.5Q513,340 496,340Q451,340 418.5,307.5Q386,275 386,230Q386,227 386,224Q386,221 387,216Q304,246 252,317Q200,388 200,480Q200,596 282,678Q364,760 480,760ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_classical_building.xml b/core/res/res/drawable/ic_zen_mode_icon_classical_building.xml
new file mode 100644
index 0000000..2675126
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_classical_building.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M200,680L200,400L280,400L280,680L200,680ZM440,680L440,400L520,400L520,680L440,680ZM80,840L80,760L880,760L880,840L80,840ZM680,680L680,400L760,400L760,680L680,680ZM80,320L80,240L480,40L880,240L880,320L80,320ZM258,240L480,240L702,240L258,240ZM258,240L702,240L480,130L258,240Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_croissant.xml b/core/res/res/drawable/ic_zen_mode_icon_croissant.xml
new file mode 100644
index 0000000..199343d
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_croissant.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M804,678Q821,687 834,674Q847,661 838,644L780,536L738,644L804,678ZM604,640L652,640L748,402Q751,394 746.5,388.5Q742,383 736,380L656,348Q647,345 638.5,350Q630,355 628,364L604,640ZM308,640L356,640L332,364Q330,353 321.5,349Q313,345 304,348L224,380Q216,383 212.5,388.5Q209,394 212,402L308,640ZM156,678L222,644L180,536L122,644Q113,661 126,674Q139,687 156,678ZM436,640L524,640L554,302Q556,293 549.5,286.5Q543,280 534,280L426,280Q418,280 411.5,286.5Q405,293 406,302L436,640ZM138,760Q96,760 68,728.5Q40,697 40,654Q40,642 43.5,630.5Q47,619 52,608L140,440Q126,400 141,361Q156,322 194,306L274,274Q288,269 302,267Q316,265 330,268Q344,239 369,219.5Q394,200 426,200L534,200Q566,200 591,219.5Q616,239 630,268Q644,266 658,267.5Q672,269 686,274L766,306Q806,322 822,361Q838,400 820,438L908,606Q914,617 917,629Q920,641 920,654Q920,699 889.5,729.5Q859,760 814,760Q803,760 792,757.5Q781,755 770,750L708,720L250,720L194,750Q181,757 166.5,758.5Q152,760 138,760ZM480,480Q480,480 480,480Q480,480 480,480L480,480L480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_fork_and_knife.xml b/core/res/res/drawable/ic_zen_mode_icon_fork_and_knife.xml
new file mode 100644
index 0000000..1fa7379
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_fork_and_knife.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M280,880L280,514Q229,500 194.5,458Q160,416 160,360L160,80L240,80L240,360L280,360L280,80L360,80L360,360L400,360L400,80L480,80L480,360Q480,416 445.5,458Q411,500 360,514L360,880L280,880ZM680,880L680,560L560,560L560,280Q560,197 618.5,138.5Q677,80 760,80L760,880L680,880Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_group_of_people.xml b/core/res/res/drawable/ic_zen_mode_icon_group_of_people.xml
new file mode 100644
index 0000000..c6194d5
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_group_of_people.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M0,720L0,657Q0,614 44,587Q88,560 160,560Q173,560 185,560.5Q197,561 208,563Q194,584 187,607Q180,630 180,655L180,720L0,720ZM240,720L240,655Q240,623 257.5,596.5Q275,570 307,550Q339,530 383.5,520Q428,510 480,510Q533,510 577.5,520Q622,530 654,550Q686,570 703,596.5Q720,623 720,655L720,720L240,720ZM780,720L780,655Q780,629 773.5,606Q767,583 754,563Q765,561 776.5,560.5Q788,560 800,560Q872,560 916,586.5Q960,613 960,657L960,720L780,720ZM325,640L636,640L636,640Q626,620 580.5,605Q535,590 480,590Q425,590 379.5,605Q334,620 325,640ZM160,520Q127,520 103.5,496.5Q80,473 80,440Q80,406 103.5,383Q127,360 160,360Q194,360 217,383Q240,406 240,440Q240,473 217,496.5Q194,520 160,520ZM800,520Q767,520 743.5,496.5Q720,473 720,440Q720,406 743.5,383Q767,360 800,360Q834,360 857,383Q880,406 880,440Q880,473 857,496.5Q834,520 800,520ZM480,480Q430,480 395,445Q360,410 360,360Q360,309 395,274.5Q430,240 480,240Q531,240 565.5,274.5Q600,309 600,360Q600,410 565.5,445Q531,480 480,480ZM480,400Q497,400 508.5,388.5Q520,377 520,360Q520,343 508.5,331.5Q497,320 480,320Q463,320 451.5,331.5Q440,343 440,360Q440,377 451.5,388.5Q463,400 480,400ZM481,640L481,640Q481,640 481,640Q481,640 481,640Q481,640 481,640Q481,640 481,640L481,640ZM480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_headphones.xml b/core/res/res/drawable/ic_zen_mode_icon_headphones.xml
new file mode 100644
index 0000000..f0bc7a2
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_headphones.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M360,840L200,840Q167,840 143.5,816.5Q120,793 120,760L120,480Q120,405 148.5,339.5Q177,274 225.5,225.5Q274,177 339.5,148.5Q405,120 480,120Q555,120 620.5,148.5Q686,177 734.5,225.5Q783,274 811.5,339.5Q840,405 840,480L840,760Q840,793 816.5,816.5Q793,840 760,840L600,840L600,520L760,520L760,480Q760,363 678.5,281.5Q597,200 480,200Q363,200 281.5,281.5Q200,363 200,480L200,520L360,520L360,840ZM280,600L200,600L200,760Q200,760 200,760Q200,760 200,760L280,760L280,600ZM680,600L680,760L760,760Q760,760 760,760Q760,760 760,760L760,600L680,600ZM280,600L280,600L200,600Q200,600 200,600Q200,600 200,600L200,600L280,600ZM680,600L760,600L760,600Q760,600 760,600Q760,600 760,600L680,600Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_heart.xml b/core/res/res/drawable/ic_zen_mode_icon_heart.xml
new file mode 100644
index 0000000..c9b1577
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_heart.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M480,840L422,788Q321,697 255,631Q189,565 150,512.5Q111,460 95.5,416Q80,372 80,326Q80,232 143,169Q206,106 300,106Q352,106 399,128Q446,150 480,190Q514,150 561,128Q608,106 660,106Q754,106 817,169Q880,232 880,326Q880,372 864.5,416Q849,460 810,512.5Q771,565 705,631Q639,697 538,788L480,840ZM480,732Q576,646 638,584.5Q700,523 736,477.5Q772,432 786,396.5Q800,361 800,326Q800,266 760,226Q720,186 660,186Q613,186 573,212.5Q533,239 518,280L518,280L442,280L442,280Q427,239 387,212.5Q347,186 300,186Q240,186 200,226Q160,266 160,326Q160,361 174,396.5Q188,432 224,477.5Q260,523 322,584.5Q384,646 480,732ZM480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459L480,459L480,459L480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_house.xml b/core/res/res/drawable/ic_zen_mode_icon_house.xml
new file mode 100644
index 0000000..e25d194
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_house.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M160,840L160,465L88,520L40,456L160,364L160,240L240,240L240,303L480,120L920,456L872,519L800,465L800,840L160,840ZM240,760L440,760L440,600L520,600L520,760L720,760L720,404L480,221L240,404L240,760ZM160,200Q160,150 195,115Q230,80 280,80Q297,80 308.5,68.5Q320,57 320,40L400,40Q400,90 365,125Q330,160 280,160Q263,160 251.5,171.5Q240,183 240,200L160,200ZM240,760L440,760L440,760L520,760L520,760L720,760L720,760L480,760L240,760Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_lightbulb.xml b/core/res/res/drawable/ic_zen_mode_icon_lightbulb.xml
new file mode 100644
index 0000000..602e60d
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_lightbulb.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M480,880Q454,880 433,867.5Q412,855 400,834L400,834Q367,834 343.5,810.5Q320,787 320,754L320,612Q261,573 225.5,509Q190,445 190,370Q190,249 274.5,164.5Q359,80 480,80Q601,80 685.5,164.5Q770,249 770,370Q770,447 734.5,510Q699,573 640,612L640,754Q640,787 616.5,810.5Q593,834 560,834L560,834Q548,855 527,867.5Q506,880 480,880ZM400,754L560,754L560,718L400,718L400,754ZM400,678L560,678L560,640L400,640L400,678ZM392,560L450,560L450,452L362,364L404,322L480,398L556,322L598,364L510,452L510,560L568,560Q622,534 656,483.5Q690,433 690,370Q690,282 629,221Q568,160 480,160Q392,160 331,221Q270,282 270,370Q270,433 304,483.5Q338,534 392,560ZM480,398L480,398L480,398L480,398L480,398L480,398L480,398L480,398L480,398ZM480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360L480,360L480,360L480,360L480,360L480,360L480,360L480,360L480,360L480,360Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_palette.xml b/core/res/res/drawable/ic_zen_mode_icon_palette.xml
new file mode 100644
index 0000000..f31704d
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_palette.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M480,880Q398,880 325,848.5Q252,817 197.5,762.5Q143,708 111.5,635Q80,562 80,480Q80,397 112.5,324Q145,251 200.5,197Q256,143 330,111.5Q404,80 488,80Q568,80 639,107.5Q710,135 763.5,183.5Q817,232 848.5,298.5Q880,365 880,442Q880,557 810,618.5Q740,680 640,680L566,680Q557,680 553.5,685Q550,690 550,696Q550,708 565,730.5Q580,753 580,782Q580,832 552.5,856Q525,880 480,880ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480L480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480ZM260,520Q286,520 303,503Q320,486 320,460Q320,434 303,417Q286,400 260,400Q234,400 217,417Q200,434 200,460Q200,486 217,503Q234,520 260,520ZM380,360Q406,360 423,343Q440,326 440,300Q440,274 423,257Q406,240 380,240Q354,240 337,257Q320,274 320,300Q320,326 337,343Q354,360 380,360ZM580,360Q606,360 623,343Q640,326 640,300Q640,274 623,257Q606,240 580,240Q554,240 537,257Q520,274 520,300Q520,326 537,343Q554,360 580,360ZM700,520Q726,520 743,503Q760,486 760,460Q760,434 743,417Q726,400 700,400Q674,400 657,417Q640,434 640,460Q640,486 657,503Q674,520 700,520ZM480,800Q489,800 494.5,795Q500,790 500,782Q500,768 485,749Q470,730 470,692Q470,650 499,625Q528,600 570,600L640,600Q706,600 753,561.5Q800,523 800,442Q800,321 707.5,240.5Q615,160 488,160Q352,160 256,253Q160,346 160,480Q160,613 253.5,706.5Q347,800 480,800Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_rabbit.xml b/core/res/res/drawable/ic_zen_mode_icon_rabbit.xml
new file mode 100644
index 0000000..190d0cb
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_rabbit.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M380,880Q305,880 252.5,827.5Q200,775 200,700Q200,665 217,635.5Q234,606 280,560Q286,554 291.5,547.5Q297,541 306,530Q255,452 227.5,366.5Q200,281 200,200Q200,142 221,111Q242,80 280,80Q337,80 382,135Q427,190 450,236Q459,256 466.5,276.5Q474,297 480,319Q486,297 493.5,276.5Q501,256 511,236Q533,190 578,135Q623,80 680,80Q718,80 739,111Q760,142 760,200Q760,281 732.5,366.5Q705,452 654,530Q663,541 668.5,547.5Q674,554 680,560Q726,606 743,635.5Q760,665 760,700Q760,775 707.5,827.5Q655,880 580,880Q535,880 507.5,870Q480,860 480,860Q480,860 452.5,870Q425,880 380,880ZM380,800Q403,800 426,794.5Q449,789 469,778Q458,773 449,761Q440,749 440,740Q440,732 451.5,726Q463,720 480,720Q497,720 508.5,726Q520,732 520,740Q520,749 511,761Q502,773 491,778Q511,789 534,794.5Q557,800 580,800Q622,800 651,771Q680,742 680,700Q680,682 670,665Q660,648 640,631Q626,619 617,610Q608,601 588,576Q559,541 540,530.5Q521,520 480,520Q439,520 419.5,530.5Q400,541 372,576Q352,601 343,610Q334,619 320,631Q300,648 290,665Q280,682 280,700Q280,742 309,771Q338,800 380,800ZM420,670Q412,670 406,661Q400,652 400,640Q400,628 406,619Q412,610 420,610Q428,610 434,619Q440,628 440,640Q440,652 434,661Q428,670 420,670ZM540,670Q532,670 526,661Q520,652 520,640Q520,628 526,619Q532,610 540,610Q548,610 554,619Q560,628 560,640Q560,652 554,661Q548,670 540,670ZM363,471Q374,463 388,457Q402,451 419,446Q417,398 404.5,350.5Q392,303 373,264Q354,224 331,196.5Q308,169 285,161Q283,167 281.5,176.5Q280,186 280,200Q280,268 301.5,338Q323,408 363,471ZM597,471Q637,408 658.5,338Q680,268 680,200Q680,186 678.5,176.5Q677,167 675,161Q652,169 629,196.5Q606,224 587,264Q569,303 556.5,350.5Q544,398 541,446Q556,450 570,456.5Q584,463 597,471Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_running.xml b/core/res/res/drawable/ic_zen_mode_icon_running.xml
new file mode 100644
index 0000000..472b04e
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_running.xml
@@ -0,0 +1,26 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960"
+ android:autoMirrored="true">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M520,920L520,680L436,600L396,776L120,720L136,640L328,680L392,356L320,384L320,520L240,520L240,332L398,264Q433,249 449.5,244.5Q466,240 480,240Q501,240 519,251Q537,262 548,280L588,344Q614,386 658.5,413Q703,440 760,440L760,520Q694,520 636.5,492.5Q579,465 540,420L516,540L600,620L600,920L520,920ZM540,220Q507,220 483.5,196.5Q460,173 460,140Q460,107 483.5,83.5Q507,60 540,60Q573,60 596.5,83.5Q620,107 620,140Q620,173 596.5,196.5Q573,220 540,220Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_shopping_cart.xml b/core/res/res/drawable/ic_zen_mode_icon_shopping_cart.xml
new file mode 100644
index 0000000..92cec4d
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_shopping_cart.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M280,880Q247,880 223.5,856.5Q200,833 200,800Q200,767 223.5,743.5Q247,720 280,720Q313,720 336.5,743.5Q360,767 360,800Q360,833 336.5,856.5Q313,880 280,880ZM680,880Q647,880 623.5,856.5Q600,833 600,800Q600,767 623.5,743.5Q647,720 680,720Q713,720 736.5,743.5Q760,767 760,800Q760,833 736.5,856.5Q713,880 680,880ZM246,240L342,440L622,440Q622,440 622,440Q622,440 622,440L732,240Q732,240 732,240Q732,240 732,240L246,240ZM208,160L798,160Q821,160 833,180.5Q845,201 834,222L692,478Q681,498 662.5,509Q644,520 622,520L324,520L280,600Q280,600 280,600Q280,600 280,600L760,600L760,680L280,680Q235,680 212,640.5Q189,601 210,562L264,464L120,160L40,160L40,80L170,80L208,160ZM342,440L342,440L622,440Q622,440 622,440Q622,440 622,440L622,440L342,440Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_snowflake.xml b/core/res/res/drawable/ic_zen_mode_icon_snowflake.xml
new file mode 100644
index 0000000..1746e20
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_snowflake.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M440,880L440,714L310,842L254,786L440,600L440,520L360,520L174,706L118,650L246,520L80,520L80,440L246,440L118,310L174,254L360,440L440,440L440,360L254,174L310,118L440,246L440,80L520,80L520,246L650,118L706,174L520,360L520,440L600,440L786,254L842,310L714,440L880,440L880,520L714,520L842,650L786,706L600,520L520,520L520,600L706,786L650,842L520,714L520,880L440,880Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_speech_bubble.xml b/core/res/res/drawable/ic_zen_mode_icon_speech_bubble.xml
new file mode 100644
index 0000000..4be98ab
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_speech_bubble.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M80,880L80,160Q80,127 103.5,103.5Q127,80 160,80L800,80Q833,80 856.5,103.5Q880,127 880,160L880,640Q880,673 856.5,696.5Q833,720 800,720L240,720L80,880ZM206,640L800,640Q800,640 800,640Q800,640 800,640L800,160Q800,160 800,160Q800,160 800,160L160,160Q160,160 160,160Q160,160 160,160L160,685L206,640ZM160,640L160,640L160,160Q160,160 160,160Q160,160 160,160L160,160Q160,160 160,160Q160,160 160,160L160,640Q160,640 160,640Q160,640 160,640Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_train.xml b/core/res/res/drawable/ic_zen_mode_icon_train.xml
new file mode 100644
index 0000000..b6f3445
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_train.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M160,620L160,240Q160,187 187.5,155.5Q215,124 260,107.5Q305,91 362.5,85.5Q420,80 480,80Q546,80 604.5,85.5Q663,91 706.5,107.5Q750,124 775,155.5Q800,187 800,240L800,620Q800,679 759.5,719.5Q719,760 660,760L720,820L720,840L640,840L560,760L400,760L320,840L240,840L240,820L300,760Q241,760 200.5,719.5Q160,679 160,620ZM480,160Q374,160 325,172.5Q276,185 258,200L706,200Q691,183 641.5,171.5Q592,160 480,160ZM240,400L440,400L440,280L240,280L240,400ZM660,480L300,480Q274,480 257,480Q240,480 240,480L240,480L720,480L720,480Q720,480 703,480Q686,480 660,480ZM520,400L720,400L720,280L520,280L520,400ZM340,640Q366,640 383,623Q400,606 400,580Q400,554 383,537Q366,520 340,520Q314,520 297,537Q280,554 280,580Q280,606 297,623Q314,640 340,640ZM620,640Q646,640 663,623Q680,606 680,580Q680,554 663,537Q646,520 620,520Q594,520 577,537Q560,554 560,580Q560,606 577,623Q594,640 620,640ZM300,680L660,680Q686,680 703,663Q720,646 720,620L720,480L240,480L240,620Q240,646 257,663Q274,680 300,680ZM480,200Q592,200 641.5,200Q691,200 706,200L258,200Q276,200 325,200Q374,200 480,200Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_zen_mode_icon_tv.xml b/core/res/res/drawable/ic_zen_mode_icon_tv.xml
new file mode 100644
index 0000000..eaa920a
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_mode_icon_tv.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="960"
+ android:viewportWidth="960">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M320,840L320,760L160,760Q127,760 103.5,736.5Q80,713 80,680L80,200Q80,167 103.5,143.5Q127,120 160,120L800,120Q833,120 856.5,143.5Q880,167 880,200L880,680Q880,713 856.5,736.5Q833,760 800,760L640,760L640,840L320,840ZM160,680L800,680Q800,680 800,680Q800,680 800,680L800,200Q800,200 800,200Q800,200 800,200L160,200Q160,200 160,200Q160,200 160,200L160,680Q160,680 160,680Q160,680 160,680ZM160,680Q160,680 160,680Q160,680 160,680L160,200Q160,200 160,200Q160,200 160,200L160,200Q160,200 160,200Q160,200 160,200L160,680Q160,680 160,680Q160,680 160,680Z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 61c7a8c..383033d 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -237,6 +237,13 @@
<integer name="config_emergency_call_wait_for_connection_timeout_millis">20000</integer>
<java-symbol type="integer" name="config_emergency_call_wait_for_connection_timeout_millis" />
+ <!-- The time duration in millis after which Telephony will stop waiting for the OFF state
+ from cellular modem, consider the request to power off cellular modem as failed, and thus
+ treat the cellular modem state as ON.
+ -->
+ <integer name="config_satellite_wait_for_cellular_modem_off_timeout_millis">120000</integer>
+ <java-symbol type="integer" name="config_satellite_wait_for_cellular_modem_off_timeout_millis" />
+
<!-- Indicates the data limit in bytes that can be used for bootstrap sim until factory reset.
-1 means unlimited. -->
<integer name="config_esim_bootstrap_data_limit_bytes">-1</integer>
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
index 832ebe5..6dad3b7 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
@@ -999,4 +999,31 @@
mDatabase.endTransaction();
}
}
+
+ /**
+ * This test verifies that the JNI exception thrown because of a bad column is actually thrown
+ * and does not crash the VM.
+ */
+ @Test
+ public void testJniExceptions() {
+ // Create the t1 table.
+ mDatabase.beginTransaction();
+ try {
+ mDatabase.execSQL("CREATE TABLE t1 (i int, j int);");
+ mDatabase.setTransactionSuccessful();
+ } finally {
+ mDatabase.endTransaction();
+ }
+
+ mDatabase.beginTransactionReadOnly();
+ try (SQLiteRawStatement s = mDatabase.createRawStatement("SELECT * from t1")) {
+ s.step();
+ s.getColumnText(5); // out-of-range column
+ fail("JNI exception not thrown");
+ } catch (SQLiteBindOrColumnIndexOutOfRangeException e) {
+ // Passing case.
+ } finally {
+ mDatabase.endTransaction();
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 8627c0b..53ab2d5 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -539,20 +539,23 @@
<!-- The size of the icon shown in the resize veil. -->
<dimen name="desktop_mode_resize_veil_icon_size">96dp</dimen>
- <!-- The with of the border around the app task for edge resizing, when
+ <!-- The width of the border outside the app task eligible for edge resizing, when
enable_windowing_edge_drag_resize is enabled. -->
- <dimen name="desktop_mode_edge_handle">12dp</dimen>
+ <dimen name="freeform_edge_handle_outset">10dp</dimen>
+
+ <!-- The size of the border inside the app task eligible for edge resizing, when
+ enable_windowing_edge_drag_resize is enabled. -->
+ <dimen name="freeform_edge_handle_inset">2dp</dimen>
<!-- The original width of the border around the app task for edge resizing, when
enable_windowing_edge_drag_resize is disabled. -->
<dimen name="freeform_resize_handle">15dp</dimen>
<!-- The size of the corner region for drag resizing with touch, when a larger touch region is
- appropriate. Applied when enable_windowing_edge_drag_resize is enabled. -->
+ appropriate. -->
<dimen name="desktop_mode_corner_resize_large">48dp</dimen>
- <!-- The original size of the corner region for darg resizing, when
- enable_windowing_edge_drag_resize is disabled. -->
+ <!-- The size of the corner region for drag resizing with a cursor or a stylus. -->
<dimen name="freeform_resize_corner">44dp</dimen>
<!-- The thickness in dp for all desktop drag transition regions. -->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 401b78d..39260f6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -19,6 +19,7 @@
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getFineResizeCornerSize;
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getLargeResizeCornerSize;
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeEdgeHandleSize;
+import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeHandleEdgeInset;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
@@ -286,7 +287,8 @@
final Resources res = mResult.mRootView.getResources();
mDragResizeListener.setGeometry(new DragResizeWindowGeometry(0 /* taskCornerRadius */,
new Size(mResult.mWidth, mResult.mHeight), getResizeEdgeHandleSize(mContext, res),
- getFineResizeCornerSize(res), getLargeResizeCornerSize(res)), touchSlop);
+ getResizeHandleEdgeInset(res), getFineResizeCornerSize(res),
+ getLargeResizeCornerSize(res)), touchSlop);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 538d0fb..b5f5bb9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -31,6 +31,7 @@
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getFineResizeCornerSize;
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getLargeResizeCornerSize;
import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeEdgeHandleSize;
+import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.getResizeHandleEdgeInset;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -515,8 +516,8 @@
if (mDragResizeListener.setGeometry(
new DragResizeWindowGeometry(mRelayoutParams.mCornerRadius,
new Size(mResult.mWidth, mResult.mHeight),
- getResizeEdgeHandleSize(mContext, res), getFineResizeCornerSize(res),
- getLargeResizeCornerSize(res)), touchSlop)
+ getResizeEdgeHandleSize(mContext, res), getResizeHandleEdgeInset(res),
+ getFineResizeCornerSize(res), getLargeResizeCornerSize(res)), touchSlop)
|| !mTaskInfo.positionInParent.equals(mPositionInParent)) {
updateExclusionRegion();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
index 014d61d..fd7bed7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometry.java
@@ -44,27 +44,32 @@
final class DragResizeWindowGeometry {
private final int mTaskCornerRadius;
private final Size mTaskSize;
- // The size of the handle applied to the edges of the window, for the user to drag resize.
- private final int mResizeHandleThickness;
+ // The size of the handle outside the task window applied to the edges of the window, for the
+ // user to drag resize.
+ private final int mResizeHandleEdgeOutset;
+ // The size of the handle inside the task window applied to the edges of the window, for the
+ // user to drag resize.
+ private final int mResizeHandleEdgeInset;
// The task corners to permit drag resizing with a course input, such as touch.
-
private final @NonNull TaskCorners mLargeTaskCorners;
// The task corners to permit drag resizing with a fine input, such as stylus or cursor.
private final @NonNull TaskCorners mFineTaskCorners;
// The bounds for each edge drag region, which can resize the task in one direction.
- private final @NonNull TaskEdges mTaskEdges;
+ final @NonNull TaskEdges mTaskEdges;
DragResizeWindowGeometry(int taskCornerRadius, @NonNull Size taskSize,
- int resizeHandleThickness, int fineCornerSize, int largeCornerSize) {
+ int resizeHandleEdgeOutset, int resizeHandleEdgeInset, int fineCornerSize,
+ int largeCornerSize) {
mTaskCornerRadius = taskCornerRadius;
mTaskSize = taskSize;
- mResizeHandleThickness = resizeHandleThickness;
+ mResizeHandleEdgeOutset = resizeHandleEdgeOutset;
+ mResizeHandleEdgeInset = resizeHandleEdgeInset;
mLargeTaskCorners = new TaskCorners(mTaskSize, largeCornerSize);
mFineTaskCorners = new TaskCorners(mTaskSize, fineCornerSize);
// Save touch areas for each edge.
- mTaskEdges = new TaskEdges(mTaskSize, mResizeHandleThickness);
+ mTaskEdges = new TaskEdges(mTaskSize, mResizeHandleEdgeOutset, mResizeHandleEdgeInset);
}
/**
@@ -72,11 +77,18 @@
*/
static int getResizeEdgeHandleSize(@NonNull Context context, @NonNull Resources res) {
return EDGE_DRAG_RESIZE.isEnabled(context)
- ? res.getDimensionPixelSize(R.dimen.desktop_mode_edge_handle)
+ ? res.getDimensionPixelSize(R.dimen.freeform_edge_handle_outset)
: res.getDimensionPixelSize(R.dimen.freeform_resize_handle);
}
/**
+ * Returns the resource value to use for the edge resize handle inside the task bounds.
+ */
+ static int getResizeHandleEdgeInset(@NonNull Resources res) {
+ return res.getDimensionPixelSize(R.dimen.freeform_edge_handle_inset);
+ }
+
+ /**
* Returns the resource value to use for course input, such as touch, that benefits from a large
* square on each of the window's corners.
*/
@@ -95,7 +107,8 @@
/**
* Returns the size of the task this geometry is calculated for.
*/
- @NonNull Size getTaskSize() {
+ @NonNull
+ Size getTaskSize() {
// Safe to return directly since size is immutable.
return mTaskSize;
}
@@ -217,13 +230,15 @@
ctrlType |= CTRL_TYPE_BOTTOM;
}
// If the touch is within one of the four corners, check if it is within the bounds of the
- // // handle.
+ // handle.
if ((ctrlType & (CTRL_TYPE_LEFT | CTRL_TYPE_RIGHT)) != 0
&& (ctrlType & (CTRL_TYPE_TOP | CTRL_TYPE_BOTTOM)) != 0) {
return checkDistanceFromCenter(ctrlType, x, y);
}
- // Otherwise, we should make sure we don't resize tasks inside task bounds.
- return (x < 0 || y < 0 || x >= mTaskSize.getWidth() || y >= mTaskSize.getHeight())
+ // Allow a small resize handle inside the task bounds defined by the edge inset.
+ return (x <= mResizeHandleEdgeInset || y <= mResizeHandleEdgeInset
+ || x >= mTaskSize.getWidth() - mResizeHandleEdgeInset
+ || y >= mTaskSize.getHeight() - mResizeHandleEdgeInset)
? ctrlType : CTRL_TYPE_UNDEFINED;
}
@@ -237,7 +252,7 @@
final Point cornerRadiusCenter = calculateCenterForCornerRadius(ctrlType);
double distanceFromCenter = Math.hypot(x - cornerRadiusCenter.x, y - cornerRadiusCenter.y);
- if (distanceFromCenter < mTaskCornerRadius + mResizeHandleThickness
+ if (distanceFromCenter < mTaskCornerRadius + mResizeHandleEdgeOutset
&& distanceFromCenter >= mTaskCornerRadius) {
return ctrlType;
}
@@ -288,7 +303,8 @@
return this.mTaskCornerRadius == other.mTaskCornerRadius
&& this.mTaskSize.equals(other.mTaskSize)
- && this.mResizeHandleThickness == other.mResizeHandleThickness
+ && this.mResizeHandleEdgeOutset == other.mResizeHandleEdgeOutset
+ && this.mResizeHandleEdgeInset == other.mResizeHandleEdgeInset
&& this.mFineTaskCorners.equals(other.mFineTaskCorners)
&& this.mLargeTaskCorners.equals(other.mLargeTaskCorners)
&& this.mTaskEdges.equals(other.mTaskEdges);
@@ -299,7 +315,8 @@
return Objects.hash(
mTaskCornerRadius,
mTaskSize,
- mResizeHandleThickness,
+ mResizeHandleEdgeOutset,
+ mResizeHandleEdgeInset,
mFineTaskCorners,
mLargeTaskCorners,
mTaskEdges);
@@ -421,26 +438,27 @@
private final @NonNull Rect mBottomEdgeBounds;
private final @NonNull Region mRegion;
- private TaskEdges(@NonNull Size taskSize, int resizeHandleThickness) {
+ private TaskEdges(@NonNull Size taskSize, int resizeHandleThickness,
+ int resizeHandleEdgeInset) {
// Save touch areas for each edge.
mTopEdgeBounds = new Rect(
-resizeHandleThickness,
-resizeHandleThickness,
taskSize.getWidth() + resizeHandleThickness,
- 0);
+ resizeHandleThickness);
mLeftEdgeBounds = new Rect(
-resizeHandleThickness,
0,
- 0,
+ resizeHandleEdgeInset,
taskSize.getHeight());
mRightEdgeBounds = new Rect(
- taskSize.getWidth(),
+ taskSize.getWidth() - resizeHandleEdgeInset,
0,
taskSize.getWidth() + resizeHandleThickness,
taskSize.getHeight());
mBottomEdgeBounds = new Rect(
-resizeHandleThickness,
- taskSize.getHeight(),
+ taskSize.getHeight() - resizeHandleEdgeInset,
taskSize.getWidth() + resizeHandleThickness,
taskSize.getHeight() + resizeHandleThickness);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
index d8f395d..1691f07 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java
@@ -45,6 +45,9 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
+import java.util.List;
+
/**
* Tests for {@link DragResizeWindowGeometry}.
*
@@ -57,11 +60,12 @@
private static final Size TASK_SIZE = new Size(500, 1000);
private static final int TASK_CORNER_RADIUS = 10;
private static final int EDGE_RESIZE_THICKNESS = 12;
+ private static final int EDGE_RESIZE_HANDLE_INSET = 4;
private static final int FINE_CORNER_SIZE = EDGE_RESIZE_THICKNESS * 2 + 10;
private static final int LARGE_CORNER_SIZE = FINE_CORNER_SIZE + 10;
private static final DragResizeWindowGeometry GEOMETRY = new DragResizeWindowGeometry(
- TASK_CORNER_RADIUS, TASK_SIZE, EDGE_RESIZE_THICKNESS, FINE_CORNER_SIZE,
- LARGE_CORNER_SIZE);
+ TASK_CORNER_RADIUS, TASK_SIZE, EDGE_RESIZE_THICKNESS, EDGE_RESIZE_HANDLE_INSET,
+ FINE_CORNER_SIZE, LARGE_CORNER_SIZE);
// Points in the edge resize handle. Note that coordinates start from the top left.
private static final Point TOP_EDGE_POINT = new Point(TASK_SIZE.getWidth() / 2,
-EDGE_RESIZE_THICKNESS / 2);
@@ -71,6 +75,16 @@
TASK_SIZE.getWidth() + EDGE_RESIZE_THICKNESS / 2, TASK_SIZE.getHeight() / 2);
private static final Point BOTTOM_EDGE_POINT = new Point(TASK_SIZE.getWidth() / 2,
TASK_SIZE.getHeight() + EDGE_RESIZE_THICKNESS / 2);
+ // Points in the inset of the task bounds still within the edge resize handle.
+ // Note that coordinates start from the top left.
+ private static final Point TOP_INSET_POINT = new Point(TASK_SIZE.getWidth() / 2,
+ EDGE_RESIZE_HANDLE_INSET / 2);
+ private static final Point LEFT_INSET_POINT = new Point(EDGE_RESIZE_HANDLE_INSET / 2,
+ TASK_SIZE.getHeight() / 2);
+ private static final Point RIGHT_INSET_POINT = new Point(
+ TASK_SIZE.getWidth() - EDGE_RESIZE_HANDLE_INSET / 2, TASK_SIZE.getHeight() / 2);
+ private static final Point BOTTOM_INSET_POINT = new Point(TASK_SIZE.getWidth() / 2,
+ TASK_SIZE.getHeight() - EDGE_RESIZE_HANDLE_INSET / 2);
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -85,18 +99,23 @@
.addEqualityGroup(
GEOMETRY,
new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
- EDGE_RESIZE_THICKNESS, FINE_CORNER_SIZE, LARGE_CORNER_SIZE))
+ EDGE_RESIZE_THICKNESS, EDGE_RESIZE_HANDLE_INSET, FINE_CORNER_SIZE,
+ LARGE_CORNER_SIZE))
.addEqualityGroup(
new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
- EDGE_RESIZE_THICKNESS + 10, FINE_CORNER_SIZE, LARGE_CORNER_SIZE),
+ EDGE_RESIZE_THICKNESS + 10, EDGE_RESIZE_HANDLE_INSET,
+ FINE_CORNER_SIZE, LARGE_CORNER_SIZE),
new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
- EDGE_RESIZE_THICKNESS + 10, FINE_CORNER_SIZE, LARGE_CORNER_SIZE))
+ EDGE_RESIZE_THICKNESS + 10, EDGE_RESIZE_HANDLE_INSET,
+ FINE_CORNER_SIZE, LARGE_CORNER_SIZE))
.addEqualityGroup(
new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
- EDGE_RESIZE_THICKNESS + 10, FINE_CORNER_SIZE,
+ EDGE_RESIZE_THICKNESS + 10, EDGE_RESIZE_HANDLE_INSET,
+ FINE_CORNER_SIZE,
LARGE_CORNER_SIZE + 5),
new DragResizeWindowGeometry(TASK_CORNER_RADIUS, TASK_SIZE,
- EDGE_RESIZE_THICKNESS + 10, FINE_CORNER_SIZE,
+ EDGE_RESIZE_THICKNESS + 10, EDGE_RESIZE_HANDLE_INSET,
+ FINE_CORNER_SIZE,
LARGE_CORNER_SIZE + 5))
.testEquals();
}
@@ -127,7 +146,7 @@
assertThat(region.contains(point.x - EDGE_RESIZE_THICKNESS, point.y)).isTrue();
// Vertically along the edge is not contained.
assertThat(region.contains(point.x, point.y - EDGE_RESIZE_THICKNESS)).isFalse();
- assertThat(region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS)).isFalse();
+ assertThat(region.contains(point.x, point.y + EDGE_RESIZE_THICKNESS + 10)).isFalse();
}
private static void verifyVerticalEdge(@NonNull Region region, @NonNull Point point) {
@@ -188,18 +207,18 @@
}
private void validateCtrlTypeForEdges(boolean isTouchscreen, boolean isEdgeResizePermitted) {
- assertThat(GEOMETRY.calculateCtrlType(mContext, isTouchscreen, isEdgeResizePermitted,
- LEFT_EDGE_POINT.x, LEFT_EDGE_POINT.y)).isEqualTo(
- isEdgeResizePermitted ? CTRL_TYPE_LEFT : CTRL_TYPE_UNDEFINED);
- assertThat(GEOMETRY.calculateCtrlType(mContext, isTouchscreen, isEdgeResizePermitted,
- TOP_EDGE_POINT.x, TOP_EDGE_POINT.y)).isEqualTo(
- isEdgeResizePermitted ? CTRL_TYPE_TOP : CTRL_TYPE_UNDEFINED);
- assertThat(GEOMETRY.calculateCtrlType(mContext, isTouchscreen, isEdgeResizePermitted,
- RIGHT_EDGE_POINT.x, RIGHT_EDGE_POINT.y)).isEqualTo(
- isEdgeResizePermitted ? CTRL_TYPE_RIGHT : CTRL_TYPE_UNDEFINED);
- assertThat(GEOMETRY.calculateCtrlType(mContext, isTouchscreen, isEdgeResizePermitted,
- BOTTOM_EDGE_POINT.x, BOTTOM_EDGE_POINT.y)).isEqualTo(
- isEdgeResizePermitted ? CTRL_TYPE_BOTTOM : CTRL_TYPE_UNDEFINED);
+ List<Point> points = Arrays.asList(LEFT_EDGE_POINT, TOP_EDGE_POINT, RIGHT_EDGE_POINT,
+ BOTTOM_EDGE_POINT, LEFT_INSET_POINT, TOP_INSET_POINT, RIGHT_INSET_POINT,
+ BOTTOM_INSET_POINT);
+ List<Integer> expectedCtrlType = Arrays.asList(CTRL_TYPE_LEFT, CTRL_TYPE_TOP,
+ CTRL_TYPE_RIGHT, CTRL_TYPE_BOTTOM, CTRL_TYPE_LEFT, CTRL_TYPE_TOP, CTRL_TYPE_RIGHT,
+ CTRL_TYPE_BOTTOM);
+
+ for (int i = 0; i < points.size(); i++) {
+ assertThat(GEOMETRY.calculateCtrlType(mContext, isTouchscreen, isEdgeResizePermitted,
+ points.get(i).x, points.get(i).y)).isEqualTo(
+ isEdgeResizePermitted ? expectedCtrlType.get(i) : CTRL_TYPE_UNDEFINED);
+ }
}
@Test
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 3375e18c..ae63e19 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -57,6 +57,7 @@
@FlaggedApi("android.nfc.nfc_oem_extension") public final class NfcOemExtension {
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.List<java.lang.String> getActiveNfceeList();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState();
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index c5b82ed..6c0f933 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -113,4 +113,5 @@
void clearPreference();
void setScreenState();
void checkFirmware();
+ List<String> fetchActiveNfceeList();
}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 2ec819c..204ba9f 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -26,6 +26,8 @@
import android.os.RemoteException;
import android.util.Log;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.Executor;
/**
@@ -153,6 +155,19 @@
NfcAdapter.callService(() -> NfcAdapter.sService.checkFirmware());
}
+ /**
+ * Get the Active NFCEE (NFC Execution Environment) List
+ *
+ * @return List of activated secure elements on success
+ * which can contain "eSE" and "UICC", otherwise empty list.
+ */
+ @NonNull
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ public List<String> getActiveNfceeList() {
+ return NfcAdapter.callServiceReturn(() ->
+ NfcAdapter.sService.fetchActiveNfceeList(), new ArrayList<String>());
+ }
+
private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
@Override
public void onTagConnected(boolean connected, Tag tag) throws RemoteException {
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt
index ebba7f1..2f8105a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioSharingRepository.kt
@@ -63,7 +63,7 @@
/** Provides audio sharing functionality. */
interface AudioSharingRepository {
/** Whether the device is in audio sharing. */
- val inAudioSharing: Flow<Boolean>
+ val inAudioSharing: StateFlow<Boolean>
/** The primary headset groupId in audio sharing. */
val primaryGroupId: StateFlow<Int>
@@ -101,7 +101,7 @@
.flowOn(backgroundCoroutineContext)
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), false)
- override val inAudioSharing: Flow<Boolean> =
+ override val inAudioSharing: StateFlow<Boolean> =
isAudioSharingProfilesReady.flatMapLatest { ready ->
if (ready) {
btManager.profileManager.leAudioBroadcastProfile.onBroadcastStartedOrStopped
@@ -113,6 +113,7 @@
flowOf(false)
}
}
+ .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), false)
private val primaryChange: Flow<Unit> = callbackFlow {
val callback =
@@ -254,7 +255,7 @@
}
class AudioSharingRepositoryEmptyImpl : AudioSharingRepository {
- override val inAudioSharing: Flow<Boolean> = flowOf(false)
+ override val inAudioSharing: StateFlow<Boolean> = MutableStateFlow(false)
override val primaryGroupId: StateFlow<Int> =
MutableStateFlow(BluetoothCsipSetCoordinator.GROUP_ID_INVALID)
override val secondaryGroupId: StateFlow<Int> =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
index 409c551..5ec566b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModelTest.kt
@@ -28,6 +28,7 @@
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
+import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
@@ -49,6 +50,24 @@
val underTest = kosmos.primaryBouncerToLockscreenTransitionViewModel
@Test
+ fun lockscreenAlphaStartsFromViewStateAccessorAlpha() =
+ testScope.runTest {
+ val viewState = ViewStateAccessor(alpha = { 0.5f })
+ val alpha by collectLastValue(underTest.lockscreenAlpha(viewState))
+
+ keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED))
+
+ keyguardTransitionRepository.sendTransitionStep(step(0f))
+ assertThat(alpha).isEqualTo(0.5f)
+
+ keyguardTransitionRepository.sendTransitionStep(step(0.5f))
+ assertThat(alpha).isIn(Range.open(0.5f, 1f))
+
+ keyguardTransitionRepository.sendTransitionStep(step(1f))
+ assertThat(alpha).isEqualTo(1f)
+ }
+
+ @Test
fun deviceEntryParentViewAlpha() =
testScope.runTest {
val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index cd84abc..aee3ce0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -133,6 +133,7 @@
sceneInteractor = sceneInteractor,
falsingInteractor = kosmos.falsingInteractor,
powerInteractor = kosmos.powerInteractor,
+ motionEventHandlerReceiver = {},
)
.apply { setTransitionState(transitionState) }
}
@@ -199,6 +200,7 @@
shadeSceneContentViewModel.activateIn(testScope)
shadeSceneActionsViewModel.activateIn(testScope)
bouncerSceneContentViewModel.activateIn(testScope)
+ sceneContainerViewModel.activateIn(testScope)
assertWithMessage("Initial scene key mismatch!")
.that(sceneContainerViewModel.currentScene.value)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index ea95aab..f85823a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
package com.android.systemui.scene.ui.viewmodel
import android.view.MotionEvent
@@ -25,6 +27,7 @@
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.kosmos.testScope
+import com.android.systemui.lifecycle.activateIn
import com.android.systemui.power.data.repository.fakePowerRepository
import com.android.systemui.power.domain.interactor.powerInteractor
import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -37,6 +40,8 @@
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -57,6 +62,9 @@
private lateinit var underTest: SceneContainerViewModel
+ private lateinit var activationJob: Job
+ private var motionEventHandler: SceneContainerViewModel.MotionEventHandler? = null
+
@Before
fun setUp() {
underTest =
@@ -64,10 +72,28 @@
sceneInteractor = sceneInteractor,
falsingInteractor = kosmos.falsingInteractor,
powerInteractor = kosmos.powerInteractor,
+ motionEventHandlerReceiver = { motionEventHandler ->
+ this@SceneContainerViewModelTest.motionEventHandler = motionEventHandler
+ },
)
+ activationJob = Job()
+ underTest.activateIn(testScope, activationJob)
}
@Test
+ fun activate_setsMotionEventHandler() =
+ testScope.runTest { assertThat(motionEventHandler).isNotNull() }
+
+ @Test
+ fun deactivate_clearsMotionEventHandler() =
+ testScope.runTest {
+ activationJob.cancel()
+ runCurrent()
+
+ assertThat(motionEventHandler).isNull()
+ }
+
+ @Test
fun isVisible() =
testScope.runTest {
val isVisible by collectLastValue(underTest.isVisible)
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index 57fd9ea..d069c01 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -71,7 +71,7 @@
<string name="kg_prompt_after_dpm_lock" msgid="6002804765868345917">"لمزيد من الأمان، تم قفل الجهاز وفقًا لسياسة العمل."</string>
<string name="kg_prompt_after_user_lockdown_pin" msgid="5374732179740050373">"يجب إدخال رقم التعريف الشخصي بعد إلغاء الفتح الذكي."</string>
<string name="kg_prompt_after_user_lockdown_password" msgid="9097968458291129795">"يجب إدخال كلمة المرور بعد إلغاء الفتح الذكي."</string>
- <string name="kg_prompt_after_user_lockdown_pattern" msgid="215072203613597906">"يجب رسم النقش بعد إلغاء التأمين."</string>
+ <string name="kg_prompt_after_user_lockdown_pattern" msgid="215072203613597906">"يجب رسم النقش بعد إلغاء الفتح الذكي."</string>
<string name="kg_prompt_unattended_update" msgid="4366635751738712452">"سيتم تثبيت التحديث عندما لا يكون الجهاز قيد الاستخدام."</string>
<string name="kg_prompt_pin_auth_timeout" msgid="5868644725126275245">"يجب تعزيز الأمان. لم يُستخدَم رقم PIN لبعض الوقت."</string>
<string name="kg_prompt_password_auth_timeout" msgid="5809110458491920871">"يجب تعزيز الأمان. لم تستخدَم كلمة المرور لبعض الوقت."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index fd90d08..cf2057c 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -57,7 +57,7 @@
<string name="kg_wrong_pin" msgid="4160978845968732624">"Неверный PIN-код"</string>
<string name="kg_wrong_pin_try_again" msgid="3129729383303430190">"Неверный PIN-код."</string>
<string name="kg_wrong_input_try_fp_suggestion" msgid="3143861542242024833">"Повторите попытку или используйте отпечаток пальца."</string>
- <string name="kg_fp_not_recognized" msgid="5183108260932029241">"Отпечаток не распознан."</string>
+ <string name="kg_fp_not_recognized" msgid="5183108260932029241">"Отпечаток не распознан"</string>
<string name="bouncer_face_not_recognized" msgid="1666128054475597485">"Лицо не распознано."</string>
<string name="kg_bio_try_again_or_pin" msgid="4752168242723808390">"Повторите попытку или введите PIN-код."</string>
<string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"Повторите попытку или введите пароль."</string>
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt
index 7a05671..5f421fd 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt
@@ -21,10 +21,13 @@
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
+import androidx.core.view.doOnLayout
import com.android.app.tracing.coroutines.launch
import com.android.systemui.communal.domain.model.CommunalContentModel
import com.android.systemui.communal.util.WidgetViewFactory
import com.android.systemui.util.kotlin.DisposableHandles
+import kotlin.coroutines.resume
+import kotlin.coroutines.suspendCoroutine
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DisposableHandle
@@ -44,13 +47,8 @@
val loadingJob =
applicationScope.launch("$TAG#createWidgetView") {
val widget = factory.createWidget(context, model, size)
- // TODO(b/358662507): Remove this workaround
- (container.parent as? ViewGroup)?.let { parent ->
- val index = parent.indexOfChild(container)
- parent.removeView(container)
- parent.addView(container, index)
- }
- container.setView(widget)
+ waitForLayout(container)
+ container.post { container.setView(widget) }
}
disposables += DisposableHandle { loadingJob.cancel() }
@@ -58,6 +56,10 @@
return disposables
}
+
+ private suspend fun waitForLayout(container: FrameLayout) = suspendCoroutine { cont ->
+ container.doOnLayout { cont.resume(Unit) }
+ }
}
private fun ViewGroup.setView(view: View) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index 81b0064..49303e0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -91,11 +91,11 @@
* the z-order (which is not really above the system UI window, but rather - the lock-screen
* becomes invisible to reveal the "occluding activity").
*/
- val isKeyguardShowing: Flow<Boolean>
+ val isKeyguardShowing: StateFlow<Boolean>
/** Is an activity showing over the keyguard? */
@Deprecated("Use KeyguardTransitionInteractor + KeyguardState.OCCLUDED")
- val isKeyguardOccluded: Flow<Boolean>
+ val isKeyguardOccluded: StateFlow<Boolean>
/**
* Whether the device is locked or unlocked right now. This is true when keyguard has been
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
index 2a8bb47..13d54ba 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
@@ -36,8 +36,6 @@
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
@SysUISingleton
@@ -73,15 +71,11 @@
listenForTransitionToCamera(scope, keyguardInteractor)
}
- private val canDismissLockscreen: Flow<Boolean> =
- combine(
- keyguardInteractor.isKeyguardShowing,
- keyguardInteractor.isKeyguardDismissible,
- keyguardInteractor.biometricUnlockState,
- ) { isKeyguardShowing, isKeyguardDismissible, biometricUnlockState ->
- (isWakeAndUnlock(biometricUnlockState.mode) ||
- (!isKeyguardShowing && isKeyguardDismissible))
- }
+ private fun canDismissLockscreen(): Boolean {
+ return isWakeAndUnlock(keyguardInteractor.biometricUnlockState.value.mode) ||
+ (!keyguardInteractor.isKeyguardShowing.value &&
+ keyguardInteractor.isKeyguardDismissible.value)
+ }
/**
* Listen for the signal that we're waking up and figure what state we need to transition to.
@@ -96,22 +90,18 @@
.debounce(50L)
.sample(
startedKeyguardTransitionStep,
- keyguardInteractor.biometricUnlockState,
- keyguardInteractor.primaryBouncerShowing,
- keyguardInteractor.isKeyguardOccluded,
- canDismissLockscreen,
wakeToGoneInteractor.canWakeDirectlyToGone,
)
.collect {
(
_,
startedStep,
- biometricUnlockState,
- primaryBouncerShowing,
- isKeyguardOccludedLegacy,
- canDismissLockscreen,
canWakeDirectlyToGone,
) ->
+ val isKeyguardOccludedLegacy = keyguardInteractor.isKeyguardOccluded.value
+ val biometricUnlockMode = keyguardInteractor.biometricUnlockState.value.mode
+ val primaryBouncerShowing = keyguardInteractor.primaryBouncerShowing.value
+
if (!maybeHandleInsecurePowerGesture()) {
val shouldTransitionToLockscreen =
if (KeyguardWmStateRefactor.isEnabled) {
@@ -121,12 +111,10 @@
// completes.
!maybeStartTransitionToOccludedOrInsecureCamera { state, reason ->
startTransitionTo(state, ownerReason = reason)
- } &&
- !isWakeAndUnlock(biometricUnlockState.mode) &&
- !primaryBouncerShowing
+ } && !isWakeAndUnlock(biometricUnlockMode) && !primaryBouncerShowing
} else {
!isKeyguardOccludedLegacy &&
- !isWakeAndUnlock(biometricUnlockState.mode) &&
+ !isWakeAndUnlock(biometricUnlockMode) &&
!primaryBouncerShowing
}
@@ -136,7 +124,7 @@
!KeyguardWmStateRefactor.isEnabled && isKeyguardOccludedLegacy
val shouldTransitionToGone =
- (!KeyguardWmStateRefactor.isEnabled && canDismissLockscreen) ||
+ (!KeyguardWmStateRefactor.isEnabled && canDismissLockscreen()) ||
(KeyguardWmStateRefactor.isEnabled && canWakeDirectlyToGone)
if (shouldTransitionToGone) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index 61446c1..0c12f8c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -42,8 +42,6 @@
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch
@@ -83,13 +81,10 @@
listenForTransitionToCamera(scope, keyguardInteractor)
}
- private val canTransitionToGoneOnWake: Flow<Boolean> =
- combine(
- keyguardInteractor.isKeyguardShowing,
- keyguardInteractor.isKeyguardDismissible,
- ) { isKeyguardShowing, isKeyguardDismissible ->
- isKeyguardDismissible && !isKeyguardShowing
- }
+ private fun canDismissLockscreen(): Boolean {
+ return !keyguardInteractor.isKeyguardShowing.value &&
+ keyguardInteractor.isKeyguardDismissible.value
+ }
private fun listenForDozingToGoneViaBiometrics() {
if (KeyguardWmStateRefactor.isEnabled) {
@@ -135,27 +130,20 @@
.debounce(50L)
.filterRelevantKeyguardStateAnd { isAwake -> isAwake }
.sample(
- keyguardInteractor.isKeyguardOccluded,
communalInteractor.isCommunalAvailable,
communalSceneInteractor.isIdleOnCommunal,
- canTransitionToGoneOnWake,
- keyguardInteractor.primaryBouncerShowing,
)
- .collect {
- (
- _,
- occluded,
- isCommunalAvailable,
- isIdleOnCommunal,
- canTransitionToGoneOnWake,
- primaryBouncerShowing) ->
+ .collect { (_, isCommunalAvailable, isIdleOnCommunal) ->
+ val isKeyguardOccludedLegacy = keyguardInteractor.isKeyguardOccluded.value
+ val primaryBouncerShowing = keyguardInteractor.primaryBouncerShowing.value
+
if (!deviceEntryInteractor.isLockscreenEnabled()) {
if (SceneContainerFlag.isEnabled) {
// TODO(b/336576536): Check if adaptation for scene framework is needed
} else {
startTransitionTo(KeyguardState.GONE)
}
- } else if (canTransitionToGoneOnWake) {
+ } else if (canDismissLockscreen()) {
if (SceneContainerFlag.isEnabled) {
// TODO(b/336576536): Check if adaptation for scene framework is needed
} else {
@@ -167,7 +155,7 @@
} else {
startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
}
- } else if (occluded) {
+ } else if (isKeyguardOccludedLegacy) {
startTransitionTo(KeyguardState.OCCLUDED)
} else if (isIdleOnCommunal && !communalSceneKtfRefactor()) {
if (SceneContainerFlag.isEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index 17c1e82..7bf9c2f1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -32,7 +32,6 @@
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
@@ -208,15 +207,15 @@
scope.launch {
keyguardInteractor.isAbleToDream
- .sampleCombine(
- keyguardInteractor.isKeyguardShowing,
- keyguardInteractor.isKeyguardDismissible,
- )
- .filterRelevantKeyguardStateAnd {
- (isDreaming, isKeyguardShowing, isKeyguardDismissible) ->
- !isDreaming && isKeyguardDismissible && !isKeyguardShowing
+ .filterRelevantKeyguardStateAnd { isDreaming -> !isDreaming }
+ .collect {
+ if (
+ keyguardInteractor.isKeyguardDismissible.value &&
+ !keyguardInteractor.isKeyguardShowing.value
+ ) {
+ startTransitionTo(KeyguardState.GONE)
+ }
}
- .collect { startTransitionTo(KeyguardState.GONE) }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 0df989e..4cab2bb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -216,14 +216,14 @@
/** Whether the keyguard is showing or not. */
@Deprecated("Use KeyguardTransitionInteractor + KeyguardState")
- val isKeyguardShowing: Flow<Boolean> = repository.isKeyguardShowing
+ val isKeyguardShowing: StateFlow<Boolean> = repository.isKeyguardShowing
/** Whether the keyguard is dismissible or not. */
val isKeyguardDismissible: StateFlow<Boolean> = repository.isKeyguardDismissible
/** Whether the keyguard is occluded (covered by an activity). */
@Deprecated("Use KeyguardTransitionInteractor + KeyguardState.OCCLUDED")
- val isKeyguardOccluded: Flow<Boolean> = repository.isKeyguardOccluded
+ val isKeyguardOccluded: StateFlow<Boolean> = repository.isKeyguardOccluded
/** Whether the keyguard is going away. */
@Deprecated("Use KeyguardTransitionInteractor + KeyguardState.GONE")
@@ -253,7 +253,7 @@
val ambientIndicationVisible: Flow<Boolean> = repository.ambientIndicationVisible.asStateFlow()
/** Whether the primary bouncer is showing or not. */
- @JvmField val primaryBouncerShowing: Flow<Boolean> = bouncerRepository.primaryBouncerShow
+ @JvmField val primaryBouncerShowing: StateFlow<Boolean> = bouncerRepository.primaryBouncerShow
/** Whether the alternate bouncer is showing or not. */
val alternateBouncerShowing: Flow<Boolean> =
@@ -274,7 +274,7 @@
val statusBarState: Flow<StatusBarState> = repository.statusBarState
/** Observable for [BiometricUnlockModel] when biometrics are used to unlock the device. */
- val biometricUnlockState: Flow<BiometricUnlockModel> = repository.biometricUnlockState
+ val biometricUnlockState: StateFlow<BiometricUnlockModel> = repository.biometricUnlockState
/** Keyguard is present and is not occluded. */
val isKeyguardVisible: Flow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
index 15e6b1d..d119ed4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
@@ -92,8 +92,8 @@
val button = view as ImageView
val configurationBasedDimensions = MutableStateFlow(loadFromResources(view))
val disposableHandle =
- view.repeatWhenAttached(mainImmediateDispatcher) {
- repeatOnLifecycle(Lifecycle.State.STARTED) {
+ view.repeatWhenAttached {
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
launch("$TAG#viewModel") {
viewModel.collect { buttonModel ->
updateButton(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 050ef6f..06f77bf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -270,7 +270,7 @@
occludedToLockscreenTransitionViewModel.lockscreenAlpha,
primaryBouncerToAodTransitionViewModel.lockscreenAlpha,
primaryBouncerToGoneTransitionViewModel.lockscreenAlpha,
- primaryBouncerToLockscreenTransitionViewModel.lockscreenAlpha,
+ primaryBouncerToLockscreenTransitionViewModel.lockscreenAlpha(viewState),
)
.onStart { emit(1f) }
) { hideKeyguard, alpha ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
index 7511101..d29f512 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToLockscreenTransitionViewModel.kt
@@ -16,6 +16,7 @@
package com.android.systemui.keyguard.ui.viewmodel
+import android.util.MathUtils
import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor
@@ -58,7 +59,14 @@
onStep = { it }
)
- val lockscreenAlpha: Flow<Float> = shortcutsAlpha
+ fun lockscreenAlpha(viewState: ViewStateAccessor): Flow<Float> {
+ var currentAlpha = 0f
+ return transitionAnimation.sharedFlow(
+ duration = 250.milliseconds,
+ onStart = { currentAlpha = viewState.alpha() },
+ onStep = { MathUtils.lerp(currentAlpha, 1f, it) },
+ )
+ }
val deviceEntryBackgroundViewAlpha: Flow<Float> =
transitionAnimation.immediatelyTransitionTo(1f)
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
index f6924f2..8aa601f 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt
@@ -26,13 +26,12 @@
attrs,
) {
- private lateinit var viewModel: SceneContainerViewModel
-
+ private var motionEventHandler: SceneContainerViewModel.MotionEventHandler? = null
// TODO(b/298525212): remove once Compose exposes window inset bounds.
private val windowInsets: MutableStateFlow<WindowInsets?> = MutableStateFlow(null)
fun init(
- viewModel: SceneContainerViewModel,
+ viewModelFactory: SceneContainerViewModel.Factory,
containerConfig: SceneContainerConfig,
sharedNotificationContainer: SharedNotificationContainer,
scenes: Set<Scene>,
@@ -40,11 +39,13 @@
sceneDataSourceDelegator: SceneDataSourceDelegator,
alternateBouncerDependencies: AlternateBouncerDependencies,
) {
- this.viewModel = viewModel
setLayoutInsetsController(layoutInsetController)
SceneWindowRootViewBinder.bind(
view = this@SceneWindowRootView,
- viewModel = viewModel,
+ viewModelFactory = viewModelFactory,
+ motionEventHandlerReceiver = { motionEventHandler ->
+ this.motionEventHandler = motionEventHandler
+ },
windowInsets = windowInsets,
containerConfig = containerConfig,
sharedNotificationContainer = sharedNotificationContainer,
@@ -69,10 +70,10 @@
}
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
- viewModel.onMotionEvent(ev)
+ motionEventHandler?.onMotionEvent(ev)
return super.dispatchTouchEvent(ev).also {
TouchLogger.logDispatchTouch(TAG, ev, it)
- viewModel.onMotionEventComplete()
+ motionEventHandler?.onMotionEventComplete()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
index 73a8e4c..ad68f17 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootViewBinder.kt
@@ -29,8 +29,6 @@
import androidx.compose.ui.unit.dp
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.repeatOnLifecycle
import com.android.compose.animation.scene.SceneKey
import com.android.compose.theme.PlatformTheme
import com.android.internal.policy.ScreenDecorationsUtils
@@ -39,7 +37,9 @@
import com.android.systemui.common.ui.compose.windowinsets.ScreenDecorProvider
import com.android.systemui.keyguard.ui.composable.AlternateBouncer
import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerDependencies
+import com.android.systemui.lifecycle.WindowLifecycleState
import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.scene.shared.model.Scene
@@ -51,6 +51,7 @@
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
@@ -63,7 +64,8 @@
/** Binds between the view and view-model pertaining to a specific scene container. */
fun bind(
view: ViewGroup,
- viewModel: SceneContainerViewModel,
+ viewModelFactory: SceneContainerViewModel.Factory,
+ motionEventHandlerReceiver: (SceneContainerViewModel.MotionEventHandler?) -> Unit,
windowInsets: StateFlow<WindowInsets?>,
containerConfig: SceneContainerConfig,
sharedNotificationContainer: SharedNotificationContainer,
@@ -85,8 +87,11 @@
}
view.repeatWhenAttached {
- lifecycleScope.launch {
- repeatOnLifecycle(Lifecycle.State.CREATED) {
+ view.viewModel(
+ minWindowLifecycleState = WindowLifecycleState.ATTACHED,
+ factory = { viewModelFactory.create(motionEventHandlerReceiver) },
+ ) { viewModel ->
+ try {
view.setViewTreeOnBackPressedDispatcherOwner(
object : OnBackPressedDispatcherOwner {
override val onBackPressedDispatcher =
@@ -140,10 +145,11 @@
onVisibilityChangedInternal(isVisible)
}
}
+ awaitCancellation()
+ } finally {
+ // Here when destroyed.
+ view.removeAllViews()
}
-
- // Here when destroyed.
- view.removeAllViews()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
index a28222e..2d02f5a 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
@@ -23,25 +23,26 @@
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.classifier.Classifier
import com.android.systemui.classifier.domain.interactor.FalsingInteractor
-import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.lifecycle.SysUiViewModel
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.Scenes
-import javax.inject.Inject
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.map
/** Models UI state for the scene container. */
-@SysUISingleton
class SceneContainerViewModel
-@Inject
+@AssistedInject
constructor(
private val sceneInteractor: SceneInteractor,
private val falsingInteractor: FalsingInteractor,
private val powerInteractor: PowerInteractor,
-) {
+ @Assisted private val motionEventHandlerReceiver: (MotionEventHandler?) -> Unit,
+) : SysUiViewModel() {
/**
* Keys of all scenes in the container.
*
@@ -56,6 +57,29 @@
/** Whether the container is visible. */
val isVisible: StateFlow<Boolean> = sceneInteractor.isVisible
+ override suspend fun onActivated() {
+ try {
+ // Sends a MotionEventHandler to the owner of the view-model so they can report
+ // MotionEvents into the view-model.
+ motionEventHandlerReceiver(
+ object : MotionEventHandler {
+ override fun onMotionEvent(motionEvent: MotionEvent) {
+ this@SceneContainerViewModel.onMotionEvent(motionEvent)
+ }
+
+ override fun onMotionEventComplete() {
+ this@SceneContainerViewModel.onMotionEventComplete()
+ }
+ }
+ )
+ awaitCancellation()
+ } finally {
+ // Clears the previously-sent MotionEventHandler so the owner of the view-model releases
+ // their reference to it.
+ motionEventHandlerReceiver(null)
+ }
+ }
+
/**
* Binds the given flow so the system remembers it.
*
@@ -136,21 +160,22 @@
}
}
- private fun replaceSceneFamilies(
- destinationScenes: Map<UserAction, UserActionResult>,
- ): Flow<Map<UserAction, UserActionResult>> {
- return destinationScenes
- .mapValues { (_, actionResult) ->
- sceneInteractor.resolveSceneFamily(actionResult.toScene).map { scene ->
- actionResult.copy(toScene = scene)
- }
- }
- .combineValueFlows()
+ /** Defines interface for classes that can handle externally-reported [MotionEvent]s. */
+ interface MotionEventHandler {
+ /** Notifies that a [MotionEvent] has occurred. */
+ fun onMotionEvent(motionEvent: MotionEvent)
+
+ /**
+ * Notifies that the previous [MotionEvent] reported by [onMotionEvent] has finished
+ * processing.
+ */
+ fun onMotionEventComplete()
+ }
+
+ @AssistedFactory
+ interface Factory {
+ fun create(
+ motionEventHandlerReceiver: (MotionEventHandler?) -> Unit,
+ ): SceneContainerViewModel
}
}
-
-private fun <K, V> Map<K, Flow<V>>.combineValueFlows(): Flow<Map<K, V>> =
- combine(
- asIterable().map { (k, fv) -> fv.map { k to it } },
- transform = Array<Pair<K, V>>::toMap,
- )
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
index 21bbaa5..606fef0 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
@@ -79,7 +79,7 @@
@SysUISingleton
fun providesWindowRootView(
layoutInflater: LayoutInflater,
- viewModelProvider: Provider<SceneContainerViewModel>,
+ viewModelFactory: SceneContainerViewModel.Factory,
containerConfigProvider: Provider<SceneContainerConfig>,
scenesProvider: Provider<Set<@JvmSuppressWildcards Scene>>,
layoutInsetController: NotificationInsetsController,
@@ -91,7 +91,7 @@
val sceneWindowRootView =
layoutInflater.inflate(R.layout.scene_window_root, null) as SceneWindowRootView
sceneWindowRootView.init(
- viewModel = viewModelProvider.get(),
+ viewModelFactory = viewModelFactory,
containerConfig = containerConfigProvider.get(),
sharedNotificationContainer =
sceneWindowRootView.requireViewById(R.id.shared_notification_container),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 99f7a75..f63ee7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -511,7 +511,7 @@
occludedToAodTransitionViewModel.lockscreenAlpha,
occludedToGoneTransitionViewModel.notificationAlpha(viewState),
occludedToLockscreenTransitionViewModel.lockscreenAlpha,
- primaryBouncerToLockscreenTransitionViewModel.lockscreenAlpha,
+ primaryBouncerToLockscreenTransitionViewModel.lockscreenAlpha(viewState),
glanceableHubToLockscreenTransitionViewModel.keyguardAlpha,
lockscreenToGlanceableHubTransitionViewModel.keyguardAlpha,
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
index 9507077..7c0c5c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSettingsTest.java
@@ -22,6 +22,9 @@
import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
import static android.view.WindowInsets.Type.systemBars;
+import static com.android.internal.accessibility.common.MagnificationConstants.SCALE_MAX_VALUE;
+import static com.android.internal.accessibility.common.MagnificationConstants.SCALE_MIN_VALUE;
+
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
@@ -429,7 +432,7 @@
mSettingView = mWindowMagnificationSettings.getSettingView();
mZoomSeekbar = mSettingView.findViewById(R.id.magnifier_zoom_slider);
assertThat(mZoomSeekbar.getProgress()).isEqualTo(10);
- assertThat(mZoomSeekbar.getMax()).isEqualTo(70);
+ assertThat(mZoomSeekbar.getMax()).isEqualTo(getSeekBarMax());
}
@Test
@@ -473,29 +476,26 @@
@Test
public void seekbarProgress_maxMagnificationBefore_seekbarProgressIsMax() {
- mWindowMagnificationSettings.setMagnificationScale(8f);
+ mWindowMagnificationSettings.setMagnificationScale(SCALE_MAX_VALUE);
setupMagnificationCapabilityAndMode(
/* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
/* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
mWindowMagnificationSettings.showSettingPanel();
- // 8.0f is max magnification {@link MagnificationScaleProvider#MAX_SCALE}.
- // Max zoom seek bar is 70.
- assertThat(mZoomSeekbar.getProgress()).isEqualTo(70);
+ assertThat(mZoomSeekbar.getProgress()).isEqualTo(getSeekBarMax());
}
@Test
public void seekbarProgress_aboveMaxMagnificationBefore_seekbarProgressIsMax() {
- mWindowMagnificationSettings.setMagnificationScale(9f);
+ mWindowMagnificationSettings.setMagnificationScale(SCALE_MAX_VALUE + 1f);
setupMagnificationCapabilityAndMode(
/* capability= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
/* mode= */ ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
mWindowMagnificationSettings.showSettingPanel();
- // Max zoom seek bar is 70.
- assertThat(mZoomSeekbar.getProgress()).isEqualTo(70);
+ assertThat(mZoomSeekbar.getProgress()).isEqualTo(getSeekBarMax());
}
@Test
@@ -589,4 +589,11 @@
anyInt(),
eq(UserHandle.USER_CURRENT))).thenReturn(mode);
}
+
+ private int getSeekBarMax() {
+ // Calculates the maximum index (or positions) the seekbar can have.
+ // This is achieved by multiplying the range of possible scales with the magnitude of
+ // change per each movement on the seekbar.
+ return (int) ((SCALE_MAX_VALUE - SCALE_MIN_VALUE) * mZoomSeekbar.getChangeMagnitude());
+ }
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 4571c19..54a6c0c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -60,13 +60,13 @@
override val bottomAreaAlpha: StateFlow<Float> = _bottomAreaAlpha
private val _isKeyguardShowing = MutableStateFlow(false)
- override val isKeyguardShowing: Flow<Boolean> = _isKeyguardShowing
+ override val isKeyguardShowing: StateFlow<Boolean> = _isKeyguardShowing
private val _isKeyguardUnlocked = MutableStateFlow(false)
override val isKeyguardDismissible: StateFlow<Boolean> = _isKeyguardUnlocked.asStateFlow()
private val _isKeyguardOccluded = MutableStateFlow(false)
- override val isKeyguardOccluded: Flow<Boolean> = _isKeyguardOccluded
+ override val isKeyguardOccluded: StateFlow<Boolean> = _isKeyguardOccluded
private val _isDozing = MutableStateFlow(false)
override val isDozing: StateFlow<Boolean> = _isDozing
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt
index 0a617d1..a4719e5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioSharingRepository.kt
@@ -18,7 +18,6 @@
import com.android.settingslib.volume.data.repository.AudioSharingRepository
import com.android.settingslib.volume.data.repository.GroupIdToVolumes
-import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -30,7 +29,7 @@
MutableStateFlow(TEST_GROUP_ID_INVALID)
private val mutableVolumeMap: MutableStateFlow<GroupIdToVolumes> = MutableStateFlow(emptyMap())
- override val inAudioSharing: Flow<Boolean> = mutableInAudioSharing
+ override val inAudioSharing: StateFlow<Boolean> = mutableInAudioSharing
override val primaryGroupId: StateFlow<Int> = mutablePrimaryGroupId
override val secondaryGroupId: StateFlow<Int> = mutableSecondaryGroupId
override val volumeMap: StateFlow<GroupIdToVolumes> = mutableVolumeMap
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index f61bd60..154b52b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1413,6 +1413,22 @@
}
public void uidRemoved(int uid) {
+ if (Flags.dontRemoveExistingUidStates()) {
+ // b/358365471 If apps sharing UID are installed on multiple users and only one of
+ // them is installed for a single user while keeping the others we observe this
+ // subroutine get invoked incorrectly since the UID still exists.
+ final long token = Binder.clearCallingIdentity();
+ try {
+ String uidName = getPackageManagerInternal().getNameForUid(uid);
+ if (uidName != null) {
+ Slog.e(TAG, "Tried to remove existing UID. uid: " + uid + " name: " + uidName);
+ return;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
synchronized (this) {
if (mUidStates.indexOfKey(uid) >= 0) {
mUidStates.get(uid).clear();
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index 0bd22f3..f0da67b 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -77,13 +77,15 @@
private final int mBiometricStrengthRequested;
private final BiometricCameraManager mBiometricCameraManager;
private final boolean mOnlyMandatoryBiometricsRequested;
+ private final boolean mIsMandatoryBiometricsAuthentication;
private PreAuthInfo(boolean biometricRequested, int biometricStrengthRequested,
boolean credentialRequested, List<BiometricSensor> eligibleSensors,
List<Pair<BiometricSensor, Integer>> ineligibleSensors, boolean credentialAvailable,
PromptInfo promptInfo, int userId, Context context,
BiometricCameraManager biometricCameraManager,
- boolean isOnlyMandatoryBiometricsRequested) {
+ boolean isOnlyMandatoryBiometricsRequested,
+ boolean isMandatoryBiometricsAuthentication) {
mBiometricRequested = biometricRequested;
mBiometricStrengthRequested = biometricStrengthRequested;
mBiometricCameraManager = biometricCameraManager;
@@ -97,6 +99,7 @@
this.userId = userId;
this.context = context;
this.mOnlyMandatoryBiometricsRequested = isOnlyMandatoryBiometricsRequested;
+ this.mIsMandatoryBiometricsAuthentication = isMandatoryBiometricsAuthentication;
}
static PreAuthInfo create(ITrustManager trustManager,
@@ -110,10 +113,12 @@
final boolean isOnlyMandatoryBiometricsRequested = promptInfo.getAuthenticators()
== BiometricManager.Authenticators.MANDATORY_BIOMETRICS;
+ boolean isMandatoryBiometricsAuthentication = false;
if (dropCredentialFallback(promptInfo.getAuthenticators(),
settingObserver.getMandatoryBiometricsEnabledAndRequirementsSatisfiedForUser(
userId), trustManager)) {
+ isMandatoryBiometricsAuthentication = true;
promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
promptInfo.setNegativeButtonText(context.getString(R.string.cancel));
}
@@ -166,7 +171,8 @@
return new PreAuthInfo(biometricRequested, requestedStrength, credentialRequested,
eligibleSensors, ineligibleSensors, credentialAvailable, promptInfo, userId,
- context, biometricCameraManager, isOnlyMandatoryBiometricsRequested);
+ context, biometricCameraManager, isOnlyMandatoryBiometricsRequested,
+ isMandatoryBiometricsAuthentication);
}
private static boolean dropCredentialFallback(int authenticators,
@@ -387,25 +393,6 @@
status = CREDENTIAL_NOT_ENROLLED;
}
}
- } else if (Flags.mandatoryBiometrics() && mOnlyMandatoryBiometricsRequested) {
- if (!eligibleSensors.isEmpty()) {
- for (BiometricSensor sensor : eligibleSensors) {
- modality |= sensor.modality;
- }
-
- if (modality == TYPE_FACE && cameraPrivacyEnabled) {
- // If the only modality requested is face, credential is unavailable,
- // and the face sensor privacy is enabled then return
- // BIOMETRIC_SENSOR_PRIVACY_ENABLED.
- //
- // Note: This sensor will not be eligible for calls to authenticate.
- status = BIOMETRIC_SENSOR_PRIVACY_ENABLED;
- } else {
- status = AUTHENTICATOR_OK;
- }
- } else {
- status = MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR;
- }
} else if (mBiometricRequested) {
if (!eligibleSensors.isEmpty()) {
for (BiometricSensor sensor : eligibleSensors) {
@@ -434,6 +421,9 @@
} else if (credentialRequested) {
modality |= TYPE_CREDENTIAL;
status = credentialAvailable ? AUTHENTICATOR_OK : CREDENTIAL_NOT_ENROLLED;
+ } else if (Flags.mandatoryBiometrics() && mOnlyMandatoryBiometricsRequested
+ && !mIsMandatoryBiometricsAuthentication) {
+ status = MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR;
} else {
// This should not be possible via the public API surface and is here mainly for
// "correctness". An exception should have been thrown before getting here.
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index fb8a81b..8711214 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -35,6 +35,7 @@
import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_NO_HARDWARE;
import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_SENSOR_PRIVACY_ENABLED;
import static com.android.server.biometrics.PreAuthInfo.CREDENTIAL_NOT_ENROLLED;
+import static com.android.server.biometrics.PreAuthInfo.MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -48,6 +49,7 @@
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricPrompt.AuthenticationResultType;
+import android.hardware.biometrics.Flags;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorProperties;
@@ -309,11 +311,16 @@
break;
case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT:
case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT:
- biometricManagerCode = BiometricManager.BIOMETRIC_SUCCESS;
+ biometricManagerCode = Flags.mandatoryBiometrics()
+ ? BiometricManager.BIOMETRIC_ERROR_LOCKOUT
+ : BiometricManager.BIOMETRIC_SUCCESS;
break;
case BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED:
biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
break;
+ case BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE:
+ biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
+ break;
default:
Slog.e(BiometricService.TAG, "Unhandled result code: " + biometricConstantsCode);
biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
@@ -375,6 +382,8 @@
return BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
case BIOMETRIC_SENSOR_PRIVACY_ENABLED:
return BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED;
+ case MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR:
+ return BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE;
case BIOMETRIC_DISABLED_BY_DEVICE_POLICY:
case BIOMETRIC_HARDWARE_NOT_DETECTED:
case BIOMETRIC_NOT_ENABLED_FOR_APPS:
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 38e6d82..1094bee 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -1002,9 +1002,9 @@
/**
* Checks if the process can cancel a device state request. If the calling process ID is not
- * both the top app and foregrounded nor does the process ID and userID match the IDs that made
- * the device state request, then check if this process holds the CONTROL_DEVICE_STATE
- * permission.
+ * both the top app and foregrounded, verify that the calling process is in the foreground and
+ * that it matches the process ID and user ID that made the device state request. If neither are
+ * true, then check if this process holds the CONTROL_DEVICE_STATE permission.
*
* @param callingPid Process ID that is requesting this state change
* @param callingUid UID that is requesting this state change
@@ -1018,8 +1018,8 @@
if (Flags.deviceStateRequesterCancelState()) {
synchronized (mLock) {
isAllowedToControlState =
- isAllowedToControlState || doCallingIdsMatchOverrideRequestIdsLocked(
- callingPid, callingUid);
+ isTopApp || (isForegroundApp && doCallingIdsMatchOverrideRequestIdsLocked(
+ callingPid, callingUid));
}
}
diff --git a/services/core/java/com/android/server/input/InputManagerInternal.java b/services/core/java/com/android/server/input/InputManagerInternal.java
index 819b9a1..73f18d1 100644
--- a/services/core/java/com/android/server/input/InputManagerInternal.java
+++ b/services/core/java/com/android/server/input/InputManagerInternal.java
@@ -21,7 +21,7 @@
import android.annotation.UserIdInt;
import android.graphics.PointF;
import android.hardware.display.DisplayViewport;
-import android.hardware.input.KeyboardSystemShortcut;
+import android.hardware.input.KeyGestureEvent;
import android.os.IBinder;
import android.view.InputChannel;
import android.view.inputmethod.InputMethodSubtype;
@@ -230,18 +230,14 @@
public abstract int getLastUsedInputDeviceId();
/**
- * Notify Keyboard system shortcut was triggered by the user and handled by the framework.
+ * Notify key gesture was completed by the user.
*
- * NOTE: This is just to notify that a system shortcut was triggered. No further action is
- * required to execute the said shortcut. This callback is meant for purposes of providing user
- * hints or logging, etc.
- *
- * @param deviceId the device ID of the keyboard using which the shortcut was triggered
- * @param keycodes the keys pressed for triggering the shortcut
- * @param modifierState the modifier state of the key event that triggered the shortcut
- * @param shortcut the shortcut that was triggered
+ * @param deviceId the device ID of the keyboard using which the event was completed
+ * @param keycodes the keys pressed for the event
+ * @param modifierState the modifier state
+ * @param event the gesture event that was completed
*
*/
- public abstract void notifyKeyboardShortcutTriggered(int deviceId, int[] keycodes,
- int modifierState, @KeyboardSystemShortcut.SystemShortcut int shortcut);
+ public abstract void notifyKeyGestureCompleted(int deviceId, int[] keycodes, int modifierState,
+ @KeyGestureEvent.KeyGestureType int event);
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index a69c7ef..a8fc862 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -48,18 +48,18 @@
import android.hardware.input.IInputDevicesChangedListener;
import android.hardware.input.IInputManager;
import android.hardware.input.IInputSensorEventListener;
+import android.hardware.input.IKeyGestureEventListener;
import android.hardware.input.IKeyboardBacklightListener;
-import android.hardware.input.IKeyboardSystemShortcutListener;
import android.hardware.input.IStickyModifierStateListener;
import android.hardware.input.ITabletModeChangedListener;
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.hardware.input.InputSensorInfo;
import android.hardware.input.InputSettings;
+import android.hardware.input.KeyGestureEvent;
import android.hardware.input.KeyGlyphMap;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.KeyboardLayoutSelectionResult;
-import android.hardware.input.KeyboardSystemShortcut;
import android.hardware.input.TouchCalibration;
import android.hardware.lights.Light;
import android.hardware.lights.LightState;
@@ -162,7 +162,7 @@
private static final int MSG_DELIVER_INPUT_DEVICES_CHANGED = 1;
private static final int MSG_RELOAD_DEVICE_ALIASES = 2;
private static final int MSG_DELIVER_TABLET_MODE_CHANGED = 3;
- private static final int MSG_KEYBOARD_SYSTEM_SHORTCUT_TRIGGERED = 4;
+ private static final int MSG_KEY_GESTURE_COMPLETED = 4;
private static final int DEFAULT_VIBRATION_MAGNITUDE = 192;
private static final AdditionalDisplayInputProperties
@@ -314,9 +314,7 @@
// Manages Sticky modifier state
private final StickyModifierStateController mStickyModifierStateController;
-
- // Manages keyboard system shortcut callbacks
- private final KeyboardShortcutCallbackHandler mKeyboardShortcutCallbackHandler;
+ private final KeyGestureController mKeyGestureController;
// Manages Keyboard microphone mute led
private final KeyboardLedController mKeyboardLedController;
@@ -476,7 +474,7 @@
injector.getLooper(), injector.getUEventManager())
: new KeyboardBacklightControllerInterface() {};
mStickyModifierStateController = new StickyModifierStateController();
- mKeyboardShortcutCallbackHandler = new KeyboardShortcutCallbackHandler();
+ mKeyGestureController = new KeyGestureController();
mKeyboardLedController = new KeyboardLedController(mContext, injector.getLooper(),
mNative);
mKeyRemapper = new KeyRemapper(mContext, mNative, mDataStore, injector.getLooper());
@@ -2723,33 +2721,32 @@
}
@Override
- @EnforcePermission(Manifest.permission.MONITOR_KEYBOARD_SYSTEM_SHORTCUTS)
- public void registerKeyboardSystemShortcutListener(
- @NonNull IKeyboardSystemShortcutListener listener) {
- super.registerKeyboardSystemShortcutListener_enforcePermission();
+ @EnforcePermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ public void registerKeyGestureEventListener(
+ @NonNull IKeyGestureEventListener listener) {
+ super.registerKeyGestureEventListener_enforcePermission();
Objects.requireNonNull(listener);
- mKeyboardShortcutCallbackHandler.registerKeyboardSystemShortcutListener(listener,
+ mKeyGestureController.registerKeyGestureEventListener(listener,
Binder.getCallingPid());
}
@Override
- @EnforcePermission(Manifest.permission.MONITOR_KEYBOARD_SYSTEM_SHORTCUTS)
- public void unregisterKeyboardSystemShortcutListener(
- @NonNull IKeyboardSystemShortcutListener listener) {
- super.unregisterKeyboardSystemShortcutListener_enforcePermission();
+ @EnforcePermission(Manifest.permission.MANAGE_KEY_GESTURES)
+ public void unregisterKeyGestureEventListener(
+ @NonNull IKeyGestureEventListener listener) {
+ super.unregisterKeyGestureEventListener_enforcePermission();
Objects.requireNonNull(listener);
- mKeyboardShortcutCallbackHandler.unregisterKeyboardSystemShortcutListener(listener,
+ mKeyGestureController.unregisterKeyGestureEventListener(listener,
Binder.getCallingPid());
}
- private void handleKeyboardSystemShortcutTriggered(int deviceId,
- KeyboardSystemShortcut shortcut) {
- InputDevice device = getInputDevice(deviceId);
- if (device == null || device.isVirtual() || !device.isFullKeyboard()) {
+ private void handleKeyGestureCompleted(KeyGestureEvent event) {
+ InputDevice device = getInputDevice(event.getDeviceId());
+ if (device == null || device.isVirtual()) {
return;
}
- KeyboardMetricsCollector.logKeyboardSystemsEventReportedAtom(device, shortcut);
- mKeyboardShortcutCallbackHandler.onKeyboardSystemShortcutTriggered(deviceId, shortcut);
+ KeyboardMetricsCollector.logKeyboardSystemsEventReportedAtom(device, event);
+ mKeyGestureController.onKeyGestureEvent(event);
}
/**
@@ -2920,10 +2917,9 @@
boolean inTabletMode = (boolean) args.arg1;
deliverTabletModeChanged(whenNanos, inTabletMode);
break;
- case MSG_KEYBOARD_SYSTEM_SHORTCUT_TRIGGERED:
- int deviceId = msg.arg1;
- KeyboardSystemShortcut shortcut = (KeyboardSystemShortcut) msg.obj;
- handleKeyboardSystemShortcutTriggered(deviceId, shortcut);
+ case MSG_KEY_GESTURE_COMPLETED:
+ KeyGestureEvent event = (KeyGestureEvent) msg.obj;
+ handleKeyGestureCompleted(event);
}
}
}
@@ -3251,10 +3247,11 @@
}
@Override
- public void notifyKeyboardShortcutTriggered(int deviceId, int[] keycodes, int modifierState,
- @KeyboardSystemShortcut.SystemShortcut int shortcut) {
- mHandler.obtainMessage(MSG_KEYBOARD_SYSTEM_SHORTCUT_TRIGGERED, deviceId, 0,
- new KeyboardSystemShortcut(keycodes, modifierState, shortcut)).sendToTarget();
+ public void notifyKeyGestureCompleted(int deviceId, int[] keycodes, int modifierState,
+ @KeyGestureEvent.KeyGestureType int gestureType) {
+ mHandler.obtainMessage(MSG_KEY_GESTURE_COMPLETED,
+ new KeyGestureEvent(deviceId, keycodes, modifierState,
+ gestureType)).sendToTarget();
}
}
diff --git a/services/core/java/com/android/server/input/KeyGestureController.java b/services/core/java/com/android/server/input/KeyGestureController.java
new file mode 100644
index 0000000..674d3c4
--- /dev/null
+++ b/services/core/java/com/android/server/input/KeyGestureController.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.input;
+
+import android.annotation.BinderThread;
+import android.hardware.input.IKeyGestureEventListener;
+import android.hardware.input.KeyGestureEvent;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * A thread-safe component of {@link InputManagerService} responsible for managing callbacks when a
+ * key gesture event occurs.
+ */
+final class KeyGestureController {
+
+ private static final String TAG = "KeyGestureController";
+
+ // To enable these logs, run:
+ // 'adb shell setprop log.tag.KeyGestureController DEBUG' (requires restart)
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ // List of currently registered key gesture event listeners keyed by process pid
+ @GuardedBy("mKeyGestureEventListenerRecords")
+ private final SparseArray<KeyGestureEventListenerRecord>
+ mKeyGestureEventListenerRecords = new SparseArray<>();
+
+ public void onKeyGestureEvent(KeyGestureEvent event) {
+ if (DEBUG) {
+ Slog.d(TAG, "Key gesture event occurred, event = " + event);
+ }
+
+ synchronized (mKeyGestureEventListenerRecords) {
+ for (int i = 0; i < mKeyGestureEventListenerRecords.size(); i++) {
+ mKeyGestureEventListenerRecords.valueAt(i).onKeyGestureEvent(event);
+ }
+ }
+ }
+
+ /** Register the key gesture event listener for a process. */
+ @BinderThread
+ public void registerKeyGestureEventListener(IKeyGestureEventListener listener,
+ int pid) {
+ synchronized (mKeyGestureEventListenerRecords) {
+ if (mKeyGestureEventListenerRecords.get(pid) != null) {
+ throw new IllegalStateException("The calling process has already registered "
+ + "a KeyGestureEventListener.");
+ }
+ KeyGestureEventListenerRecord record = new KeyGestureEventListenerRecord(
+ pid, listener);
+ try {
+ listener.asBinder().linkToDeath(record, 0);
+ } catch (RemoteException ex) {
+ throw new RuntimeException(ex);
+ }
+ mKeyGestureEventListenerRecords.put(pid, record);
+ }
+ }
+
+ /** Unregister the key gesture event listener for a process. */
+ @BinderThread
+ public void unregisterKeyGestureEventListener(IKeyGestureEventListener listener,
+ int pid) {
+ synchronized (mKeyGestureEventListenerRecords) {
+ KeyGestureEventListenerRecord record =
+ mKeyGestureEventListenerRecords.get(pid);
+ if (record == null) {
+ throw new IllegalStateException("The calling process has no registered "
+ + "KeyGestureEventListener.");
+ }
+ if (record.mListener.asBinder() != listener.asBinder()) {
+ throw new IllegalStateException("The calling process has a different registered "
+ + "KeyGestureEventListener.");
+ }
+ record.mListener.asBinder().unlinkToDeath(record, 0);
+ mKeyGestureEventListenerRecords.remove(pid);
+ }
+ }
+
+ private void onKeyGestureEventListenerDied(int pid) {
+ synchronized (mKeyGestureEventListenerRecords) {
+ mKeyGestureEventListenerRecords.remove(pid);
+ }
+ }
+
+ // A record of a registered key gesture event listener from one process.
+ private class KeyGestureEventListenerRecord implements IBinder.DeathRecipient {
+ public final int mPid;
+ public final IKeyGestureEventListener mListener;
+
+ KeyGestureEventListenerRecord(int pid, IKeyGestureEventListener listener) {
+ mPid = pid;
+ mListener = listener;
+ }
+
+ @Override
+ public void binderDied() {
+ if (DEBUG) {
+ Slog.d(TAG, "Key gesture event listener for pid " + mPid + " died.");
+ }
+ onKeyGestureEventListenerDied(mPid);
+ }
+
+ public void onKeyGestureEvent(KeyGestureEvent event) {
+ try {
+ mListener.onKeyGestureEvent(event.getDeviceId(), event.getKeycodes(),
+ event.getModifierState(), event.getKeyGestureType());
+ } catch (RemoteException ex) {
+ Slog.w(TAG, "Failed to notify process " + mPid
+ + " that key gesture event occurred, assuming it died.", ex);
+ binderDied();
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
index 3d2f951..1daf4db 100644
--- a/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
+++ b/services/core/java/com/android/server/input/KeyboardMetricsCollector.java
@@ -24,9 +24,9 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.hardware.input.KeyGestureEvent;
import android.hardware.input.KeyboardLayout;
import android.hardware.input.KeyboardLayoutSelectionResult.LayoutSelectionCriteria;
-import android.hardware.input.KeyboardSystemShortcut;
import android.icu.util.ULocale;
import android.text.TextUtils;
import android.util.Log;
@@ -66,14 +66,17 @@
* defined in "stats/atoms/input/input_extension_atoms.proto"
*/
public static void logKeyboardSystemsEventReportedAtom(@NonNull InputDevice inputDevice,
- @NonNull KeyboardSystemShortcut keyboardSystemShortcut) {
+ @NonNull KeyGestureEvent keyGestureEvent) {
+ if (inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
+ return;
+ }
FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
inputDevice.getVendorId(), inputDevice.getProductId(),
- keyboardSystemShortcut.getSystemShortcut(), keyboardSystemShortcut.getKeycodes(),
- keyboardSystemShortcut.getModifierState(), inputDevice.getDeviceBus());
+ keyGestureEvent.getKeyGestureType(), keyGestureEvent.getKeycodes(),
+ keyGestureEvent.getModifierState(), inputDevice.getDeviceBus());
if (DEBUG) {
- Slog.d(TAG, "Logging Keyboard system event: " + keyboardSystemShortcut);
+ Slog.d(TAG, "Logging Keyboard system event: " + keyGestureEvent);
}
}
diff --git a/services/core/java/com/android/server/input/KeyboardShortcutCallbackHandler.java b/services/core/java/com/android/server/input/KeyboardShortcutCallbackHandler.java
deleted file mode 100644
index 092058e..0000000
--- a/services/core/java/com/android/server/input/KeyboardShortcutCallbackHandler.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.input;
-
-import android.annotation.BinderThread;
-import android.hardware.input.IKeyboardSystemShortcutListener;
-import android.hardware.input.KeyboardSystemShortcut;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-
-/**
- * A thread-safe component of {@link InputManagerService} responsible for managing callbacks when a
- * keyboard shortcut is triggered.
- */
-final class KeyboardShortcutCallbackHandler {
-
- private static final String TAG = "KeyboardShortcut";
-
- // To enable these logs, run:
- // 'adb shell setprop log.tag.KeyboardShortcutCallbackHandler DEBUG' (requires restart)
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
- // List of currently registered keyboard system shortcut listeners keyed by process pid
- @GuardedBy("mKeyboardSystemShortcutListenerRecords")
- private final SparseArray<KeyboardSystemShortcutListenerRecord>
- mKeyboardSystemShortcutListenerRecords = new SparseArray<>();
-
- public void onKeyboardSystemShortcutTriggered(int deviceId,
- KeyboardSystemShortcut systemShortcut) {
- if (DEBUG) {
- Slog.d(TAG, "Keyboard system shortcut triggered, deviceId = " + deviceId
- + ", systemShortcut = " + systemShortcut);
- }
-
- synchronized (mKeyboardSystemShortcutListenerRecords) {
- for (int i = 0; i < mKeyboardSystemShortcutListenerRecords.size(); i++) {
- mKeyboardSystemShortcutListenerRecords.valueAt(i).onKeyboardSystemShortcutTriggered(
- deviceId, systemShortcut);
- }
- }
- }
-
- /** Register the keyboard system shortcut listener for a process. */
- @BinderThread
- public void registerKeyboardSystemShortcutListener(IKeyboardSystemShortcutListener listener,
- int pid) {
- synchronized (mKeyboardSystemShortcutListenerRecords) {
- if (mKeyboardSystemShortcutListenerRecords.get(pid) != null) {
- throw new IllegalStateException("The calling process has already registered "
- + "a KeyboardSystemShortcutListener.");
- }
- KeyboardSystemShortcutListenerRecord record = new KeyboardSystemShortcutListenerRecord(
- pid, listener);
- try {
- listener.asBinder().linkToDeath(record, 0);
- } catch (RemoteException ex) {
- throw new RuntimeException(ex);
- }
- mKeyboardSystemShortcutListenerRecords.put(pid, record);
- }
- }
-
- /** Unregister the keyboard system shortcut listener for a process. */
- @BinderThread
- public void unregisterKeyboardSystemShortcutListener(IKeyboardSystemShortcutListener listener,
- int pid) {
- synchronized (mKeyboardSystemShortcutListenerRecords) {
- KeyboardSystemShortcutListenerRecord record =
- mKeyboardSystemShortcutListenerRecords.get(pid);
- if (record == null) {
- throw new IllegalStateException("The calling process has no registered "
- + "KeyboardSystemShortcutListener.");
- }
- if (record.mListener.asBinder() != listener.asBinder()) {
- throw new IllegalStateException("The calling process has a different registered "
- + "KeyboardSystemShortcutListener.");
- }
- record.mListener.asBinder().unlinkToDeath(record, 0);
- mKeyboardSystemShortcutListenerRecords.remove(pid);
- }
- }
-
- private void onKeyboardSystemShortcutListenerDied(int pid) {
- synchronized (mKeyboardSystemShortcutListenerRecords) {
- mKeyboardSystemShortcutListenerRecords.remove(pid);
- }
- }
-
- // A record of a registered keyboard system shortcut listener from one process.
- private class KeyboardSystemShortcutListenerRecord implements IBinder.DeathRecipient {
- public final int mPid;
- public final IKeyboardSystemShortcutListener mListener;
-
- KeyboardSystemShortcutListenerRecord(int pid, IKeyboardSystemShortcutListener listener) {
- mPid = pid;
- mListener = listener;
- }
-
- @Override
- public void binderDied() {
- if (DEBUG) {
- Slog.d(TAG, "Keyboard system shortcut listener for pid " + mPid + " died.");
- }
- onKeyboardSystemShortcutListenerDied(mPid);
- }
-
- public void onKeyboardSystemShortcutTriggered(int deviceId, KeyboardSystemShortcut data) {
- try {
- mListener.onKeyboardSystemShortcutTriggered(deviceId, data.getKeycodes(),
- data.getModifierState(), data.getSystemShortcut());
- } catch (RemoteException ex) {
- Slog.w(TAG, "Failed to notify process " + mPid
- + " that keyboard system shortcut was triggered, assuming it died.", ex);
- binderDied();
- }
- }
- }
-}
diff --git a/services/core/java/com/android/server/policy/ModifierShortcutManager.java b/services/core/java/com/android/server/policy/ModifierShortcutManager.java
index 5a45186..7ed8972 100644
--- a/services/core/java/com/android/server/policy/ModifierShortcutManager.java
+++ b/services/core/java/com/android/server/policy/ModifierShortcutManager.java
@@ -29,8 +29,7 @@
import android.content.pm.PackageManager;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Icon;
-import android.hardware.input.InputManager;
-import android.hardware.input.KeyboardSystemShortcut;
+import android.hardware.input.KeyGestureEvent;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -476,7 +475,7 @@
+ "keyCode=" + KeyEvent.keyCodeToString(keyCode) + ","
+ " category=" + category + " role=" + role);
}
- notifyKeyboardShortcutTriggered(keyEvent, getSystemShortcutFromIntent(intent));
+ notifyKeyGestureCompleted(keyEvent, getKeyGestureTypeFromIntent(intent));
return true;
} else {
return false;
@@ -497,19 +496,19 @@
+ "the activity to which it is registered was not found: "
+ "META+ or SEARCH" + KeyEvent.keyCodeToString(keyCode));
}
- notifyKeyboardShortcutTriggered(keyEvent, getSystemShortcutFromIntent(shortcutIntent));
+ notifyKeyGestureCompleted(keyEvent, getKeyGestureTypeFromIntent(shortcutIntent));
return true;
}
return false;
}
- private void notifyKeyboardShortcutTriggered(KeyEvent event,
- @KeyboardSystemShortcut.SystemShortcut int systemShortcut) {
- if (systemShortcut == KeyboardSystemShortcut.SYSTEM_SHORTCUT_UNSPECIFIED) {
+ private void notifyKeyGestureCompleted(KeyEvent event,
+ @KeyGestureEvent.KeyGestureType int gestureType) {
+ if (gestureType == KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED) {
return;
}
- mInputManagerInternal.notifyKeyboardShortcutTriggered(event.getDeviceId(),
- new int[]{event.getKeyCode()}, event.getMetaState(), systemShortcut);
+ mInputManagerInternal.notifyKeyGestureCompleted(event.getDeviceId(),
+ new int[]{event.getKeyCode()}, event.getMetaState(), gestureType);
}
/**
@@ -710,21 +709,21 @@
/**
- * Find Keyboard shortcut event corresponding to intent filter category. Returns
- * {@code SYSTEM_SHORTCUT_UNSPECIFIED if no matching event found}
+ * Find Key gesture type corresponding to intent filter category. Returns
+ * {@code KEY_GESTURE_TYPE_UNSPECIFIED if no matching event found}
*/
- @KeyboardSystemShortcut.SystemShortcut
- private static int getSystemShortcutFromIntent(Intent intent) {
+ @KeyGestureEvent.KeyGestureType
+ private static int getKeyGestureTypeFromIntent(Intent intent) {
Intent selectorIntent = intent.getSelector();
if (selectorIntent != null) {
Set<String> selectorCategories = selectorIntent.getCategories();
if (selectorCategories != null && !selectorCategories.isEmpty()) {
for (String intentCategory : selectorCategories) {
- int systemShortcut = getEventFromSelectorCategory(intentCategory);
- if (systemShortcut == KeyboardSystemShortcut.SYSTEM_SHORTCUT_UNSPECIFIED) {
+ int keyGestureType = getKeyGestureTypeFromSelectorCategory(intentCategory);
+ if (keyGestureType == KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED) {
continue;
}
- return systemShortcut;
+ return keyGestureType;
}
}
}
@@ -733,69 +732,68 @@
// so check for that.
String role = intent.getStringExtra(ModifierShortcutManager.EXTRA_ROLE);
if (!TextUtils.isEmpty(role)) {
- return getLogEventFromRole(role);
+ return getKeyGestureTypeFromRole(role);
}
Set<String> intentCategories = intent.getCategories();
if (intentCategories == null || intentCategories.isEmpty()
|| !intentCategories.contains(Intent.CATEGORY_LAUNCHER)) {
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_UNSPECIFIED;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED;
}
if (intent.getComponent() == null) {
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_UNSPECIFIED;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED;
}
// TODO(b/280423320): Add new field package name associated in the
// KeyboardShortcutEvent atom and log it accordingly.
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_APPLICATION_BY_PACKAGE_NAME;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME;
}
- @KeyboardSystemShortcut.SystemShortcut
- private static int getEventFromSelectorCategory(String category) {
+ @KeyGestureEvent.KeyGestureType
+ private static int getKeyGestureTypeFromSelectorCategory(String category) {
switch (category) {
case Intent.CATEGORY_APP_BROWSER:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER;
case Intent.CATEGORY_APP_EMAIL:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL;
case Intent.CATEGORY_APP_CONTACTS:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS;
case Intent.CATEGORY_APP_CALENDAR:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR;
case Intent.CATEGORY_APP_CALCULATOR:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR;
case Intent.CATEGORY_APP_MUSIC:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC;
case Intent.CATEGORY_APP_MAPS:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS;
case Intent.CATEGORY_APP_MESSAGING:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING;
case Intent.CATEGORY_APP_GALLERY:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_GALLERY;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_GALLERY;
case Intent.CATEGORY_APP_FILES:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FILES;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES;
case Intent.CATEGORY_APP_WEATHER:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_WEATHER;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER;
case Intent.CATEGORY_APP_FITNESS:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_FITNESS;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS;
default:
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_UNSPECIFIED;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED;
}
}
/**
- * Find KeyboardLogEvent corresponding to the provide system role name.
- * Returns {@code null} if no matching event found.
+ * Find KeyGestureType corresponding to the provide system role name.
+ * Returns {@code KEY_GESTURE_TYPE_UNSPECIFIED} if no matching event found.
*/
- @KeyboardSystemShortcut.SystemShortcut
- private static int getLogEventFromRole(String role) {
+ @KeyGestureEvent.KeyGestureType
+ private static int getKeyGestureTypeFromRole(String role) {
if (RoleManager.ROLE_BROWSER.equals(role)) {
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER;
} else if (RoleManager.ROLE_SMS.equals(role)) {
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING;
+ return KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING;
} else {
- Log.w(TAG, "Keyboard shortcut to launch "
- + role + " not supported for logging");
- return KeyboardSystemShortcut.SYSTEM_SHORTCUT_UNSPECIFIED;
+ Log.w(TAG, "Keyboard gesture event to launch " + role + " not supported for logging");
+ return KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED;
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 720c1c2..aa56e8d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -139,7 +139,7 @@
import android.hardware.hdmi.HdmiPlaybackClient;
import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
import android.hardware.input.InputManager;
-import android.hardware.input.KeyboardSystemShortcut;
+import android.hardware.input.KeyGestureEvent;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
import android.media.AudioSystem;
@@ -1819,7 +1819,7 @@
}
private void handleShortPressOnHome(KeyEvent event) {
- notifyKeyboardShortcutTriggered(event, KeyboardSystemShortcut.SYSTEM_SHORTCUT_HOME);
+ notifyKeyGestureCompleted(event, KeyGestureEvent.KEY_GESTURE_TYPE_HOME);
// Turn on the connected TV and switch HDMI input if we're a HDMI playback device.
final HdmiControl hdmiControl = getHdmiControl();
@@ -2053,8 +2053,8 @@
}
switch (mDoubleTapOnHomeBehavior) {
case DOUBLE_TAP_HOME_RECENT_SYSTEM_UI:
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_APP_SWITCH);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH);
mHomeConsumed = true;
toggleRecentApps();
break;
@@ -2082,23 +2082,23 @@
case LONG_PRESS_HOME_ALL_APPS:
if (mHasFeatureLeanback) {
launchAllAppsAction();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ALL_APPS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
} else {
launchAllAppsViaA11y();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS);
}
break;
case LONG_PRESS_HOME_ASSIST:
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_ASSISTANT);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT);
launchAssistAction(null, event.getDeviceId(), event.getEventTime(),
AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
break;
case LONG_PRESS_HOME_NOTIFICATION_PANEL:
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
toggleNotificationPanel();
break;
default:
@@ -3285,29 +3285,29 @@
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
};
- private void notifyKeyboardShortcutTriggeredOnActionUp(KeyEvent event,
- @KeyboardSystemShortcut.SystemShortcut int systemShortcut) {
+ private void notifyKeyGestureCompletedOnActionUp(KeyEvent event,
+ @KeyGestureEvent.KeyGestureType int gestureType) {
if (event.getAction() != KeyEvent.ACTION_UP) {
return;
}
- notifyKeyboardShortcutTriggered(event, systemShortcut);
+ notifyKeyGestureCompleted(event, gestureType);
}
- private void notifyKeyboardShortcutTriggeredOnActionDown(KeyEvent event,
- @KeyboardSystemShortcut.SystemShortcut int systemShortcut) {
+ private void notifyKeyGestureCompletedOnActionDown(KeyEvent event,
+ @KeyGestureEvent.KeyGestureType int gestureType) {
if (event.getAction() != KeyEvent.ACTION_DOWN) {
return;
}
- notifyKeyboardShortcutTriggered(event, systemShortcut);
+ notifyKeyGestureCompleted(event, gestureType);
}
- private void notifyKeyboardShortcutTriggered(KeyEvent event,
- @KeyboardSystemShortcut.SystemShortcut int systemShortcut) {
- if (systemShortcut == KeyboardSystemShortcut.SYSTEM_SHORTCUT_UNSPECIFIED) {
+ private void notifyKeyGestureCompleted(KeyEvent event,
+ @KeyGestureEvent.KeyGestureType int gestureType) {
+ if (gestureType == KeyGestureEvent.KEY_GESTURE_TYPE_UNSPECIFIED) {
return;
}
- mInputManagerInternal.notifyKeyboardShortcutTriggered(event.getDeviceId(),
- new int[]{event.getKeyCode()}, event.getMetaState(), systemShortcut);
+ mInputManagerInternal.notifyKeyGestureCompleted(event.getDeviceId(),
+ new int[]{event.getKeyCode()}, event.getMetaState(), gestureType);
}
@Override
@@ -3417,8 +3417,8 @@
case KeyEvent.KEYCODE_RECENT_APPS:
if (firstDown) {
showRecentApps(false /* triggeredFromAltTab */);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_RECENT_APPS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS);
}
return true;
case KeyEvent.KEYCODE_APP_SWITCH:
@@ -3427,8 +3427,8 @@
preloadRecentApps();
} else if (!down) {
toggleRecentApps();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_APP_SWITCH);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH);
}
}
return true;
@@ -3437,8 +3437,8 @@
launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD,
deviceId, event.getEventTime(),
AssistUtils.INVOCATION_TYPE_UNKNOWN);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_ASSISTANT);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT);
return true;
}
break;
@@ -3451,16 +3451,16 @@
case KeyEvent.KEYCODE_I:
if (firstDown && event.isMetaPressed()) {
showSystemSettings();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS);
return true;
}
break;
case KeyEvent.KEYCODE_L:
if (firstDown && event.isMetaPressed()) {
lockNow(null /* options */);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LOCK_SCREEN);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN);
return true;
}
break;
@@ -3468,12 +3468,12 @@
if (firstDown && event.isMetaPressed()) {
if (event.isCtrlPressed()) {
sendSystemKeyToStatusBarAsync(event);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_OPEN_NOTES);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_NOTES);
} else {
toggleNotificationPanel();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
}
return true;
}
@@ -3481,8 +3481,8 @@
case KeyEvent.KEYCODE_S:
if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) {
interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TAKE_SCREENSHOT);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT);
return true;
}
break;
@@ -3495,16 +3495,16 @@
} catch (RemoteException e) {
Slog.d(TAG, "Error taking bugreport", e);
}
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT);
return true;
}
}
// fall through
case KeyEvent.KEYCODE_ESCAPE:
if (firstDown && event.isMetaPressed()) {
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_BACK);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_BACK);
injectBackGesture(event.getDownTime());
return true;
}
@@ -3513,8 +3513,8 @@
StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
if (statusbar != null) {
statusbar.moveFocusedTaskToFullscreen(getTargetDisplayIdForKeyEvent(event));
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION);
return true;
}
}
@@ -3524,8 +3524,8 @@
StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
if (statusbar != null) {
statusbar.moveFocusedTaskToDesktop(getTargetDisplayIdForKeyEvent(event));
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_DESKTOP_MODE);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_DESKTOP_MODE);
return true;
}
}
@@ -3535,15 +3535,15 @@
if (event.isCtrlPressed()) {
moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyEvent(event),
true /* leftOrTop */);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION);
} else if (event.isAltPressed()) {
setSplitscreenFocus(true /* leftOrTop */);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS);
} else {
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_BACK);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_BACK);
injectBackGesture(event.getDownTime());
}
return true;
@@ -3554,13 +3554,13 @@
if (event.isCtrlPressed()) {
moveFocusedTaskToStageSplit(getTargetDisplayIdForKeyEvent(event),
false /* leftOrTop */);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION);
return true;
} else if (event.isAltPressed()) {
setSplitscreenFocus(false /* leftOrTop */);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_CHANGE_SPLITSCREEN_FOCUS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_CHANGE_SPLITSCREEN_FOCUS);
return true;
}
}
@@ -3568,8 +3568,8 @@
case KeyEvent.KEYCODE_SLASH:
if (firstDown && event.isMetaPressed() && !keyguardOn) {
toggleKeyboardShortcutsMenu(event.getDeviceId());
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER);
return true;
}
break;
@@ -3622,31 +3622,31 @@
intent.putExtra(EXTRA_FROM_BRIGHTNESS_KEY, true);
startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
- int systemShortcut = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN
- ? KeyboardSystemShortcut.SYSTEM_SHORTCUT_BRIGHTNESS_DOWN
- : KeyboardSystemShortcut.SYSTEM_SHORTCUT_BRIGHTNESS_UP;
- notifyKeyboardShortcutTriggered(event, systemShortcut);
+ int gestureType = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN
+ ? KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_DOWN
+ : KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP;
+ notifyKeyGestureCompleted(event, gestureType);
}
return true;
case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_DOWN:
if (down) {
mInputManagerInternal.decrementKeyboardBacklight(event.getDeviceId());
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN);
}
return true;
case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_UP:
if (down) {
mInputManagerInternal.incrementKeyboardBacklight(event.getDeviceId());
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP);
}
return true;
case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE:
// TODO: Add logic
if (!down) {
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE);
}
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
@@ -3673,8 +3673,8 @@
if (firstDown && !keyguardOn && isUserSetupComplete()) {
if (event.isMetaPressed()) {
showRecentApps(false);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_RECENT_APPS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS);
return true;
} else if (mRecentAppsHeldModifiers == 0) {
final int shiftlessModifiers =
@@ -3683,8 +3683,8 @@
shiftlessModifiers, KeyEvent.META_ALT_ON)) {
mRecentAppsHeldModifiers = shiftlessModifiers;
showRecentApps(true);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_RECENT_APPS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS);
return true;
}
}
@@ -3697,20 +3697,20 @@
Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
msg.setAsynchronous(true);
msg.sendToTarget();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ALL_APPS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS);
} else {
launchAllAppsViaA11y();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS);
}
}
return true;
case KeyEvent.KEYCODE_NOTIFICATION:
if (!down) {
toggleNotificationPanel();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
}
return true;
case KeyEvent.KEYCODE_SEARCH:
@@ -3718,8 +3718,8 @@
switch (mSearchKeyBehavior) {
case SEARCH_KEY_BEHAVIOR_TARGET_ACTIVITY: {
launchTargetSearchActivity();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_SEARCH);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH);
return true;
}
case SEARCH_KEY_BEHAVIOR_DEFAULT_SEARCH:
@@ -3732,8 +3732,8 @@
if (firstDown) {
int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
sendSwitchKeyboardLayout(event, focusedToken, direction);
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LANGUAGE_SWITCH);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LANGUAGE_SWITCH);
return true;
}
break;
@@ -3752,13 +3752,13 @@
if (mPendingCapsLockToggle) {
mInputManagerInternal.toggleCapsLock(event.getDeviceId());
mPendingCapsLockToggle = false;
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK);
} else if (mPendingMetaAction) {
if (!canceled) {
launchAllAppsViaA11y();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS);
}
mPendingMetaAction = false;
}
@@ -3786,16 +3786,16 @@
if (mPendingCapsLockToggle) {
mInputManagerInternal.toggleCapsLock(event.getDeviceId());
mPendingCapsLockToggle = false;
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK);
return true;
}
}
break;
case KeyEvent.KEYCODE_CAPS_LOCK:
if (!down) {
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK);
}
break;
case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY:
@@ -3809,12 +3809,12 @@
if (firstDown) {
if (mSettingsKeyBehavior == SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL) {
toggleNotificationPanel();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
} else if (mSettingsKeyBehavior == SETTINGS_KEY_BEHAVIOR_SETTINGS_ACTIVITY) {
showSystemSettings();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS);
}
}
return true;
@@ -4760,8 +4760,8 @@
// Handle special keys.
switch (keyCode) {
case KeyEvent.KEYCODE_BACK: {
- notifyKeyboardShortcutTriggeredOnActionUp(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_BACK);
+ notifyKeyGestureCompletedOnActionUp(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_BACK);
if (down) {
// There may have other embedded activities on the same Task. Try to move the
// focus before processing the back event.
@@ -4782,12 +4782,12 @@
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
- int systemShortcut = keyCode == KEYCODE_VOLUME_DOWN
- ? KeyboardSystemShortcut.SYSTEM_SHORTCUT_VOLUME_DOWN
+ int gestureType = keyCode == KEYCODE_VOLUME_DOWN
+ ? KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_DOWN
: keyCode == KEYCODE_VOLUME_UP
- ? KeyboardSystemShortcut.SYSTEM_SHORTCUT_VOLUME_UP
- : KeyboardSystemShortcut.SYSTEM_SHORTCUT_VOLUME_MUTE;
- notifyKeyboardShortcutTriggeredOnActionDown(event, systemShortcut);
+ ? KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_UP
+ : KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_MUTE;
+ notifyKeyGestureCompletedOnActionDown(event, gestureType);
if (down) {
sendSystemKeyToStatusBarAsync(event);
@@ -4888,8 +4888,8 @@
}
case KeyEvent.KEYCODE_TV_POWER: {
- notifyKeyboardShortcutTriggeredOnActionUp(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_POWER);
+ notifyKeyGestureCompletedOnActionUp(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_POWER);
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down && hdmiControlManager != null) {
@@ -4899,8 +4899,8 @@
}
case KeyEvent.KEYCODE_POWER: {
- notifyKeyboardShortcutTriggeredOnActionUp(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_POWER);
+ notifyKeyGestureCompletedOnActionUp(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_POWER);
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0,
@@ -4923,16 +4923,16 @@
case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT:
// fall through
case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT: {
- notifyKeyboardShortcutTriggeredOnActionUp(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SYSTEM_NAVIGATION);
+ notifyKeyGestureCompletedOnActionUp(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_NAVIGATION);
result &= ~ACTION_PASS_TO_USER;
interceptSystemNavigationKey(event);
break;
}
case KeyEvent.KEYCODE_SLEEP: {
- notifyKeyboardShortcutTriggeredOnActionUp(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SLEEP);
+ notifyKeyGestureCompletedOnActionUp(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SLEEP);
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false;
if (!mPowerManager.isInteractive()) {
@@ -4948,8 +4948,8 @@
}
case KeyEvent.KEYCODE_SOFT_SLEEP: {
- notifyKeyboardShortcutTriggeredOnActionUp(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SLEEP);
+ notifyKeyGestureCompletedOnActionUp(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SLEEP);
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false;
if (!down) {
@@ -4960,8 +4960,8 @@
}
case KeyEvent.KEYCODE_WAKEUP: {
- notifyKeyboardShortcutTriggeredOnActionUp(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_WAKEUP);
+ notifyKeyGestureCompletedOnActionUp(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_WAKEUP);
result &= ~ACTION_PASS_TO_USER;
isWakeKey = true;
break;
@@ -4970,8 +4970,8 @@
case KeyEvent.KEYCODE_MUTE:
result &= ~ACTION_PASS_TO_USER;
if (down && event.getRepeatCount() == 0) {
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SYSTEM_MUTE);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_MUTE);
toggleMicrophoneMuteFromKey();
}
break;
@@ -4986,8 +4986,8 @@
case KeyEvent.KEYCODE_MEDIA_RECORD:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
- notifyKeyboardShortcutTriggeredOnActionUp(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_MEDIA_KEY);
+ notifyKeyGestureCompletedOnActionUp(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_MEDIA_KEY);
if (MediaSessionLegacyHelper.getHelper(mContext).isGlobalPriorityActive()) {
// If the global session is active pass all media keys to it
// instead of the active window.
@@ -5032,8 +5032,8 @@
0 /* unused */, event.getEventTime() /* eventTime */);
msg.setAsynchronous(true);
msg.sendToTarget();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_ASSISTANT);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT);
}
result &= ~ACTION_PASS_TO_USER;
break;
@@ -5044,8 +5044,8 @@
Message msg = mHandler.obtainMessage(MSG_LAUNCH_VOICE_ASSIST_WITH_WAKE_LOCK);
msg.setAsynchronous(true);
msg.sendToTarget();
- notifyKeyboardShortcutTriggered(event,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT);
+ notifyKeyGestureCompleted(event,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT);
}
result &= ~ACTION_PASS_TO_USER;
break;
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 2c73412..fbf09fe 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1617,8 +1617,7 @@
// causing the notifying, or the recents/home window is removed, then we won't need the
// delayed notification anymore.
void onWMTransition(@TransitionType int type, @TransitionFlags int flags) {
- if (Flags.delayNotificationToMagnificationWhenRecentsWindowToFrontTransition()
- && type == WindowManager.TRANSIT_TO_FRONT
+ if (type == WindowManager.TRANSIT_TO_FRONT
&& (flags & TRANSIT_FLAG_IS_RECENTS) != 0) {
// Delay the recents to front transition notification then send after if needed.
mHasDelayedNotificationForRecentsToFrontTransition = true;
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index a4222ff..d2961bc 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -79,6 +79,7 @@
import android.os.RemoteException;
import android.os.UserManager;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -1488,15 +1489,30 @@
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
public void testCanAuthenticate_whenLockoutTimed() throws Exception {
testCanAuthenticate_whenLockedOut(LockoutTracker.LOCKOUT_TIMED);
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
public void testCanAuthenticate_whenLockoutPermanent() throws Exception {
testCanAuthenticate_whenLockedOut(LockoutTracker.LOCKOUT_PERMANENT);
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void testCanAuthenticate_whenLockoutTimed_returnsLockoutError() throws Exception {
+ testCanAuthenticate_whenLockedOut_returnLockoutError(LockoutTracker.LOCKOUT_TIMED);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void testCanAuthenticate_whenLockoutPermanent_returnsLockoutError() throws Exception {
+ testCanAuthenticate_whenLockedOut_returnLockoutError(LockoutTracker.LOCKOUT_PERMANENT);
+ }
+
+ @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
private void testCanAuthenticate_whenLockedOut(@LockoutTracker.LockoutMode int lockoutMode)
throws Exception {
// When only biometric is requested, and sensor is strong enough
@@ -1510,6 +1526,21 @@
invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
}
+ @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ private void testCanAuthenticate_whenLockedOut_returnLockoutError(
+ @LockoutTracker.LockoutMode int lockoutMode)
+ throws Exception {
+ // When only biometric is requested, and sensor is strong enough
+ setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+
+ when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
+ .thenReturn(lockoutMode);
+
+ // Lockout is not considered an error for BiometricManager#canAuthenticate
+ assertEquals(BiometricManager.BIOMETRIC_ERROR_LOCKOUT,
+ invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
+ }
+
@Test
@RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
public void testCanAuthenticate_whenMandatoryBiometricsRequested()
@@ -1529,7 +1560,7 @@
when(mTrustManager.isInSignificantPlace()).thenReturn(true);
- assertEquals(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+ assertEquals(BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE,
invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS));
}
@@ -1572,7 +1603,7 @@
setupAuthForOnly(TYPE_CREDENTIAL, Authenticators.DEVICE_CREDENTIAL);
- assertEquals(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+ assertEquals(BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE,
invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS));
when(mTrustManager.isInSignificantPlace()).thenReturn(true);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
index 240da9f..4c3a233 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
@@ -231,7 +231,7 @@
@Test
@RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
- public void testMandatoryBiometricsStatus_whenRequirementsNotSatisfiedAndSensorAvailable()
+ public void testMandatoryBiometricsAndStrongBiometricsStatus_whenRequirementsNotSatisfied()
throws Exception {
when(mTrustManager.isInSignificantPlace()).thenReturn(true);
@@ -246,6 +246,24 @@
assertThat(preAuthInfo.eligibleSensors).hasSize(1);
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void testMandatoryBiometricsStatus_whenRequirementsNotSatisfiedAndSensorAvailable()
+ throws Exception {
+ when(mTrustManager.isInSignificantPlace()).thenReturn(true);
+
+ final BiometricSensor sensor = getFaceSensor();
+ final PromptInfo promptInfo = new PromptInfo();
+ promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS);
+ final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
+ mSettingObserver, List.of(sensor), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
+ false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
+
+ assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo(
+ BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE);
+ assertThat(preAuthInfo.eligibleSensors).hasSize(0);
+ }
+
private BiometricSensor getFingerprintSensor() {
BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FINGERPRINT,
TYPE_FINGERPRINT, BiometricManager.Authenticators.BIOMETRIC_STRONG,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java b/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java
index cb75e1a..14cb22d 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java
@@ -26,16 +26,25 @@
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
+import android.hardware.biometrics.Flags;
import android.hardware.biometrics.PromptInfo;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import androidx.test.filters.SmallTest;
+import org.junit.Rule;
import org.junit.Test;
@Presubmit
@SmallTest
public class UtilsTest {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
@Test
public void testCombineAuthenticatorBundles_withKeyDeviceCredential_andKeyAuthenticators() {
@@ -215,7 +224,8 @@
}
@Test
- public void testBiometricConstantsConversion() {
+ @RequiresFlagsDisabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void testBiometricConstantsConversionLegacy() {
final int[][] testCases = {
{BiometricConstants.BIOMETRIC_SUCCESS,
BiometricManager.BIOMETRIC_SUCCESS},
@@ -240,6 +250,34 @@
}
@Test
+ @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+ public void testBiometricConstantsConversion() {
+ final int[][] testCases = {
+ {BiometricConstants.BIOMETRIC_SUCCESS,
+ BiometricManager.BIOMETRIC_SUCCESS},
+ {BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS,
+ BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED},
+ {BiometricConstants.BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL,
+ BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED},
+ {BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+ BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE},
+ {BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT,
+ BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE},
+ {BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
+ BiometricManager.BIOMETRIC_ERROR_LOCKOUT},
+ {BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT,
+ BiometricManager.BIOMETRIC_ERROR_LOCKOUT},
+ {BiometricConstants.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE,
+ BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE}
+ };
+
+ for (int i = 0; i < testCases.length; i++) {
+ assertEquals(testCases[i][1],
+ Utils.biometricConstantsToBiometricManager(testCases[i][0]));
+ }
+ }
+
+ @Test
public void testGetAuthenticationTypeForResult_getsCorrectType() {
assertEquals(Utils.getAuthenticationTypeForResult(
BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED),
diff --git a/services/tests/wmtests/src/com/android/server/policy/KeyboardSystemShortcutTests.java b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
similarity index 69%
rename from services/tests/wmtests/src/com/android/server/policy/KeyboardSystemShortcutTests.java
rename to services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
index e26f3e0..8f3adba 100644
--- a/services/tests/wmtests/src/com/android/server/policy/KeyboardSystemShortcutTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/KeyGestureEventTests.java
@@ -22,7 +22,7 @@
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_NOTIFICATION_PANEL;
import static com.android.server.policy.PhoneWindowManager.SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL;
-import android.hardware.input.KeyboardSystemShortcut;
+import android.hardware.input.KeyGestureEvent;
import android.platform.test.annotations.Presubmit;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
@@ -44,7 +44,7 @@
@Presubmit
@MediumTest
@RunWith(JUnitParamsRunner.class)
-public class KeyboardSystemShortcutTests extends ShortcutKeyTestBase {
+public class KeyGestureEventTests extends ShortcutKeyTestBase {
@Rule
public final CheckFlagsRule mCheckFlagsRule =
@@ -56,315 +56,313 @@
private static final int ALT_ON = MODIFIER.get(KeyEvent.KEYCODE_ALT_LEFT);
private static final int CTRL_KEY = KeyEvent.KEYCODE_CTRL_LEFT;
private static final int CTRL_ON = MODIFIER.get(KeyEvent.KEYCODE_CTRL_LEFT);
- private static final int SHIFT_KEY = KeyEvent.KEYCODE_SHIFT_LEFT;
- private static final int SHIFT_ON = MODIFIER.get(KeyEvent.KEYCODE_SHIFT_LEFT);
@Keep
private static Object[][] shortcutTestArguments() {
- // testName, testKeys, expectedSystemShortcut, expectedKey, expectedModifierState
+ // testName, testKeys, expectedKeyGestureType, expectedKey, expectedModifierState
return new Object[][]{
{"Meta + H -> Open Home", new int[]{META_KEY, KeyEvent.KEYCODE_H},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_HOME, KeyEvent.KEYCODE_H, META_ON},
+ KeyGestureEvent.KEY_GESTURE_TYPE_HOME, KeyEvent.KEYCODE_H, META_ON},
{"Meta + Enter -> Open Home", new int[]{META_KEY, KeyEvent.KEYCODE_ENTER},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_HOME, KeyEvent.KEYCODE_ENTER,
+ KeyGestureEvent.KEY_GESTURE_TYPE_HOME, KeyEvent.KEYCODE_ENTER,
META_ON},
{"HOME key -> Open Home", new int[]{KeyEvent.KEYCODE_HOME},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_HOME,
+ KeyGestureEvent.KEY_GESTURE_TYPE_HOME,
KeyEvent.KEYCODE_HOME, 0},
{"RECENT_APPS key -> Open Overview", new int[]{KeyEvent.KEYCODE_RECENT_APPS},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_RECENT_APPS,
+ KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS,
KeyEvent.KEYCODE_RECENT_APPS, 0},
{"Meta + Tab -> Open Overview", new int[]{META_KEY, KeyEvent.KEYCODE_TAB},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_RECENT_APPS, KeyEvent.KEYCODE_TAB,
+ KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS, KeyEvent.KEYCODE_TAB,
META_ON},
{"Alt + Tab -> Open Overview", new int[]{ALT_KEY, KeyEvent.KEYCODE_TAB},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_RECENT_APPS, KeyEvent.KEYCODE_TAB,
+ KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS, KeyEvent.KEYCODE_TAB,
ALT_ON},
{"BACK key -> Go back", new int[]{KeyEvent.KEYCODE_BACK},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_BACK,
+ KeyGestureEvent.KEY_GESTURE_TYPE_BACK,
KeyEvent.KEYCODE_BACK, 0},
{"Meta + Escape -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_ESCAPE},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_BACK, KeyEvent.KEYCODE_ESCAPE,
+ KeyGestureEvent.KEY_GESTURE_TYPE_BACK, KeyEvent.KEYCODE_ESCAPE,
META_ON},
{"Meta + Left arrow -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_DPAD_LEFT},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_BACK, KeyEvent.KEYCODE_DPAD_LEFT,
+ KeyGestureEvent.KEY_GESTURE_TYPE_BACK, KeyEvent.KEYCODE_DPAD_LEFT,
META_ON},
{"Meta + Del -> Go back", new int[]{META_KEY, KeyEvent.KEYCODE_DEL},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_BACK, KeyEvent.KEYCODE_DEL, META_ON},
+ KeyGestureEvent.KEY_GESTURE_TYPE_BACK, KeyEvent.KEYCODE_DEL, META_ON},
{"APP_SWITCH key -> Open App switcher", new int[]{KeyEvent.KEYCODE_APP_SWITCH},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_APP_SWITCH,
+ KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH,
KeyEvent.KEYCODE_APP_SWITCH, 0},
{"ASSIST key -> Launch assistant", new int[]{KeyEvent.KEYCODE_ASSIST},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_ASSISTANT,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT,
KeyEvent.KEYCODE_ASSIST, 0},
{"Meta + A -> Launch assistant", new int[]{META_KEY, KeyEvent.KEYCODE_A},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_ASSISTANT, KeyEvent.KEYCODE_A,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT, KeyEvent.KEYCODE_A,
META_ON},
{"VOICE_ASSIST key -> Launch Voice Assistant",
new int[]{KeyEvent.KEYCODE_VOICE_ASSIST},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_VOICE_ASSISTANT,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_VOICE_ASSISTANT,
KeyEvent.KEYCODE_VOICE_ASSIST, 0},
{"Meta + I -> Launch System Settings", new int[]{META_KEY, KeyEvent.KEYCODE_I},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_SYSTEM_SETTINGS,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS,
KeyEvent.KEYCODE_I, META_ON},
{"Meta + N -> Toggle Notification panel", new int[]{META_KEY, KeyEvent.KEYCODE_N},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
KeyEvent.KEYCODE_N, META_ON},
{"NOTIFICATION key -> Toggle Notification Panel",
new int[]{KeyEvent.KEYCODE_NOTIFICATION},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
KeyEvent.KEYCODE_NOTIFICATION,
0},
{"Meta + Ctrl + S -> Take Screenshot",
new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_S},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TAKE_SCREENSHOT, KeyEvent.KEYCODE_S,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT, KeyEvent.KEYCODE_S,
META_ON | CTRL_ON},
{"Meta + / -> Open Shortcut Helper", new int[]{META_KEY, KeyEvent.KEYCODE_SLASH},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_OPEN_SHORTCUT_HELPER,
+ KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_SHORTCUT_HELPER,
KeyEvent.KEYCODE_SLASH, META_ON},
{"BRIGHTNESS_UP key -> Increase Brightness",
new int[]{KeyEvent.KEYCODE_BRIGHTNESS_UP},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_BRIGHTNESS_UP,
+ KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_UP,
KeyEvent.KEYCODE_BRIGHTNESS_UP, 0},
{"BRIGHTNESS_DOWN key -> Decrease Brightness",
new int[]{KeyEvent.KEYCODE_BRIGHTNESS_DOWN},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_BRIGHTNESS_DOWN,
+ KeyGestureEvent.KEY_GESTURE_TYPE_BRIGHTNESS_DOWN,
KeyEvent.KEYCODE_BRIGHTNESS_DOWN, 0},
{"KEYBOARD_BACKLIGHT_UP key -> Increase Keyboard Backlight",
new int[]{KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_UP},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_UP,
+ KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_UP,
KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_UP, 0},
{"KEYBOARD_BACKLIGHT_DOWN key -> Decrease Keyboard Backlight",
new int[]{KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_DOWN},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_DOWN,
+ KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_DOWN,
KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_DOWN, 0},
{"KEYBOARD_BACKLIGHT_TOGGLE key -> Toggle Keyboard Backlight",
new int[]{KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_KEYBOARD_BACKLIGHT_TOGGLE,
+ KeyGestureEvent.KEY_GESTURE_TYPE_KEYBOARD_BACKLIGHT_TOGGLE,
KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE, 0},
{"VOLUME_UP key -> Increase Volume", new int[]{KeyEvent.KEYCODE_VOLUME_UP},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_VOLUME_UP,
+ KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_UP,
KeyEvent.KEYCODE_VOLUME_UP, 0},
{"VOLUME_DOWN key -> Decrease Volume", new int[]{KeyEvent.KEYCODE_VOLUME_DOWN},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_VOLUME_DOWN,
+ KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_DOWN,
KeyEvent.KEYCODE_VOLUME_DOWN, 0},
{"VOLUME_MUTE key -> Mute Volume", new int[]{KeyEvent.KEYCODE_VOLUME_MUTE},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_VOLUME_MUTE,
+ KeyGestureEvent.KEY_GESTURE_TYPE_VOLUME_MUTE,
KeyEvent.KEYCODE_VOLUME_MUTE, 0},
{"ALL_APPS key -> Open App Drawer in Accessibility mode",
new int[]{KeyEvent.KEYCODE_ALL_APPS},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS,
KeyEvent.KEYCODE_ALL_APPS, 0},
{"SEARCH key -> Launch Search Activity", new int[]{KeyEvent.KEYCODE_SEARCH},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_SEARCH,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SEARCH,
KeyEvent.KEYCODE_SEARCH, 0},
{"LANGUAGE_SWITCH key -> Switch Keyboard Language",
new int[]{KeyEvent.KEYCODE_LANGUAGE_SWITCH},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LANGUAGE_SWITCH,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LANGUAGE_SWITCH,
KeyEvent.KEYCODE_LANGUAGE_SWITCH, 0},
{"META key -> Open App Drawer in Accessibility mode", new int[]{META_KEY},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS, META_KEY,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS, META_KEY,
META_ON},
{"Meta + Alt -> Toggle CapsLock", new int[]{META_KEY, ALT_KEY},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK, ALT_KEY,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK, ALT_KEY,
META_ON | ALT_ON},
{"Alt + Meta -> Toggle CapsLock", new int[]{ALT_KEY, META_KEY},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK, META_KEY,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK, META_KEY,
META_ON | ALT_ON},
{"CAPS_LOCK key -> Toggle CapsLock", new int[]{KeyEvent.KEYCODE_CAPS_LOCK},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_CAPS_LOCK,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_CAPS_LOCK,
KeyEvent.KEYCODE_CAPS_LOCK, 0},
{"MUTE key -> Mute System Microphone", new int[]{KeyEvent.KEYCODE_MUTE},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SYSTEM_MUTE, KeyEvent.KEYCODE_MUTE,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_MUTE, KeyEvent.KEYCODE_MUTE,
0},
{"Meta + Ctrl + DPAD_UP -> Split screen navigation",
new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_DPAD_UP},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_MULTI_WINDOW_NAVIGATION,
+ KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION,
KeyEvent.KEYCODE_DPAD_UP,
META_ON | CTRL_ON},
{"Meta + Ctrl + DPAD_LEFT -> Split screen navigation",
new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_DPAD_LEFT},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION,
KeyEvent.KEYCODE_DPAD_LEFT,
META_ON | CTRL_ON},
{"Meta + Ctrl + DPAD_RIGHT -> Split screen navigation",
new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_DPAD_RIGHT},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SPLIT_SCREEN_NAVIGATION,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SPLIT_SCREEN_NAVIGATION,
KeyEvent.KEYCODE_DPAD_RIGHT,
META_ON | CTRL_ON},
{"Meta + L -> Lock Homescreen", new int[]{META_KEY, KeyEvent.KEYCODE_L},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LOCK_SCREEN, KeyEvent.KEYCODE_L,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN, KeyEvent.KEYCODE_L,
META_ON},
{"Meta + Ctrl + N -> Open Notes", new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_N},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_OPEN_NOTES, KeyEvent.KEYCODE_N,
+ KeyGestureEvent.KEY_GESTURE_TYPE_OPEN_NOTES, KeyEvent.KEYCODE_N,
META_ON | CTRL_ON},
{"POWER key -> Toggle Power", new int[]{KeyEvent.KEYCODE_POWER},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_POWER, KeyEvent.KEYCODE_POWER,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_POWER, KeyEvent.KEYCODE_POWER,
0},
{"TV_POWER key -> Toggle Power", new int[]{KeyEvent.KEYCODE_TV_POWER},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_POWER,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_POWER,
KeyEvent.KEYCODE_TV_POWER, 0},
{"SYSTEM_NAVIGATION_DOWN key -> System Navigation",
new int[]{KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SYSTEM_NAVIGATION,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_NAVIGATION,
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN,
0},
{"SYSTEM_NAVIGATION_UP key -> System Navigation",
new int[]{KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SYSTEM_NAVIGATION,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_NAVIGATION,
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP,
0},
{"SYSTEM_NAVIGATION_LEFT key -> System Navigation",
new int[]{KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SYSTEM_NAVIGATION,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_NAVIGATION,
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT,
0},
{"SYSTEM_NAVIGATION_RIGHT key -> System Navigation",
new int[]{KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SYSTEM_NAVIGATION,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SYSTEM_NAVIGATION,
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT, 0},
{"SLEEP key -> System Sleep", new int[]{KeyEvent.KEYCODE_SLEEP},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SLEEP, KeyEvent.KEYCODE_SLEEP, 0},
+ KeyGestureEvent.KEY_GESTURE_TYPE_SLEEP, KeyEvent.KEYCODE_SLEEP, 0},
{"SOFT_SLEEP key -> System Sleep", new int[]{KeyEvent.KEYCODE_SOFT_SLEEP},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_SLEEP, KeyEvent.KEYCODE_SOFT_SLEEP,
+ KeyGestureEvent.KEY_GESTURE_TYPE_SLEEP, KeyEvent.KEYCODE_SOFT_SLEEP,
0},
{"WAKEUP key -> System Wakeup", new int[]{KeyEvent.KEYCODE_WAKEUP},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_WAKEUP, KeyEvent.KEYCODE_WAKEUP, 0},
+ KeyGestureEvent.KEY_GESTURE_TYPE_WAKEUP, KeyEvent.KEYCODE_WAKEUP, 0},
{"MEDIA_PLAY key -> Media Control", new int[]{KeyEvent.KEYCODE_MEDIA_PLAY},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_MEDIA_KEY,
+ KeyGestureEvent.KEY_GESTURE_TYPE_MEDIA_KEY,
KeyEvent.KEYCODE_MEDIA_PLAY, 0},
{"MEDIA_PAUSE key -> Media Control", new int[]{KeyEvent.KEYCODE_MEDIA_PAUSE},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_MEDIA_KEY,
+ KeyGestureEvent.KEY_GESTURE_TYPE_MEDIA_KEY,
KeyEvent.KEYCODE_MEDIA_PAUSE, 0},
{"MEDIA_PLAY_PAUSE key -> Media Control",
new int[]{KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_MEDIA_KEY,
+ KeyGestureEvent.KEY_GESTURE_TYPE_MEDIA_KEY,
KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0},
{"Meta + B -> Launch Default Browser", new int[]{META_KEY, KeyEvent.KEYCODE_B},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER,
KeyEvent.KEYCODE_B, META_ON},
{"EXPLORER key -> Launch Default Browser", new int[]{KeyEvent.KEYCODE_EXPLORER},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_BROWSER,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER,
KeyEvent.KEYCODE_EXPLORER, 0},
{"Meta + C -> Launch Default Contacts", new int[]{META_KEY, KeyEvent.KEYCODE_C},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS,
KeyEvent.KEYCODE_C, META_ON},
{"CONTACTS key -> Launch Default Contacts", new int[]{KeyEvent.KEYCODE_CONTACTS},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CONTACTS,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS,
KeyEvent.KEYCODE_CONTACTS, 0},
{"Meta + E -> Launch Default Email", new int[]{META_KEY, KeyEvent.KEYCODE_E},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL,
KeyEvent.KEYCODE_E, META_ON},
{"ENVELOPE key -> Launch Default Email", new int[]{KeyEvent.KEYCODE_ENVELOPE},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_EMAIL,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL,
KeyEvent.KEYCODE_ENVELOPE, 0},
{"Meta + K -> Launch Default Calendar", new int[]{META_KEY, KeyEvent.KEYCODE_K},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR,
KeyEvent.KEYCODE_K, META_ON},
{"CALENDAR key -> Launch Default Calendar", new int[]{KeyEvent.KEYCODE_CALENDAR},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALENDAR,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALENDAR,
KeyEvent.KEYCODE_CALENDAR, 0},
{"Meta + P -> Launch Default Music", new int[]{META_KEY, KeyEvent.KEYCODE_P},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC,
KeyEvent.KEYCODE_P, META_ON},
{"MUSIC key -> Launch Default Music", new int[]{KeyEvent.KEYCODE_MUSIC},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MUSIC,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MUSIC,
KeyEvent.KEYCODE_MUSIC, 0},
{"Meta + U -> Launch Default Calculator", new int[]{META_KEY, KeyEvent.KEYCODE_U},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR,
KeyEvent.KEYCODE_U, META_ON},
{"CALCULATOR key -> Launch Default Calculator",
new int[]{KeyEvent.KEYCODE_CALCULATOR},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_CALCULATOR,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CALCULATOR,
KeyEvent.KEYCODE_CALCULATOR, 0},
{"Meta + M -> Launch Default Maps", new int[]{META_KEY, KeyEvent.KEYCODE_M},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MAPS,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MAPS,
KeyEvent.KEYCODE_M, META_ON},
{"Meta + S -> Launch Default Messaging App",
new int[]{META_KEY, KeyEvent.KEYCODE_S},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_DEFAULT_MESSAGING,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_DEFAULT_MESSAGING,
KeyEvent.KEYCODE_S, META_ON},
{"Meta + Ctrl + DPAD_DOWN -> Enter desktop mode",
new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_DPAD_DOWN},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_DESKTOP_MODE,
+ KeyGestureEvent.KEY_GESTURE_TYPE_DESKTOP_MODE,
KeyEvent.KEYCODE_DPAD_DOWN,
META_ON | CTRL_ON}};
}
@Keep
private static Object[][] longPressOnHomeTestArguments() {
- // testName, testKeys, longPressOnHomeBehavior, expectedSystemShortcut, expectedKey,
+ // testName, testKeys, longPressOnHomeBehavior, expectedKeyGestureType, expectedKey,
// expectedModifierState
return new Object[][]{
{"Long press HOME key -> Toggle Notification panel",
new int[]{KeyEvent.KEYCODE_HOME}, LONG_PRESS_HOME_NOTIFICATION_PANEL,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
KeyEvent.KEYCODE_HOME, 0},
{"Long press META + ENTER -> Toggle Notification panel",
new int[]{META_KEY, KeyEvent.KEYCODE_ENTER},
LONG_PRESS_HOME_NOTIFICATION_PANEL,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
KeyEvent.KEYCODE_ENTER,
META_ON},
{"Long press META + H -> Toggle Notification panel",
new int[]{META_KEY, KeyEvent.KEYCODE_H}, LONG_PRESS_HOME_NOTIFICATION_PANEL,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
KeyEvent.KEYCODE_H, META_ON},
{"Long press HOME key -> Launch assistant",
new int[]{KeyEvent.KEYCODE_HOME}, LONG_PRESS_HOME_ASSIST,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_ASSISTANT,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT,
KeyEvent.KEYCODE_HOME, 0},
{"Long press META + ENTER -> Launch assistant",
new int[]{META_KEY, KeyEvent.KEYCODE_ENTER}, LONG_PRESS_HOME_ASSIST,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_ASSISTANT,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT,
KeyEvent.KEYCODE_ENTER, META_ON},
{"Long press META + H -> Launch assistant",
new int[]{META_KEY, KeyEvent.KEYCODE_H}, LONG_PRESS_HOME_ASSIST,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_LAUNCH_ASSISTANT, KeyEvent.KEYCODE_H,
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_ASSISTANT, KeyEvent.KEYCODE_H,
META_ON},
{"Long press HOME key -> Open App Drawer in Accessibility mode",
new int[]{KeyEvent.KEYCODE_HOME}, LONG_PRESS_HOME_ALL_APPS,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS,
KeyEvent.KEYCODE_HOME, 0},
{"Long press META + ENTER -> Open App Drawer in Accessibility mode",
new int[]{META_KEY, KeyEvent.KEYCODE_ENTER}, LONG_PRESS_HOME_ALL_APPS,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS,
KeyEvent.KEYCODE_ENTER, META_ON},
{"Long press META + H -> Open App Drawer in Accessibility mode",
new int[]{META_KEY, KeyEvent.KEYCODE_H},
LONG_PRESS_HOME_ALL_APPS,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_ACCESSIBILITY_ALL_APPS,
+ KeyGestureEvent.KEY_GESTURE_TYPE_ACCESSIBILITY_ALL_APPS,
KeyEvent.KEYCODE_H, META_ON}};
}
@Keep
private static Object[][] doubleTapOnHomeTestArguments() {
- // testName, testKeys, doubleTapOnHomeBehavior, expectedSystemShortcut, expectedKey,
+ // testName, testKeys, doubleTapOnHomeBehavior, expectedKeyGestureType, expectedKey,
// expectedModifierState
return new Object[][]{
{"Double tap HOME -> Open App switcher",
new int[]{KeyEvent.KEYCODE_HOME}, DOUBLE_TAP_HOME_RECENT_SYSTEM_UI,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_APP_SWITCH, KeyEvent.KEYCODE_HOME,
+ KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH, KeyEvent.KEYCODE_HOME,
0},
{"Double tap META + ENTER -> Open App switcher",
new int[]{META_KEY, KeyEvent.KEYCODE_ENTER},
DOUBLE_TAP_HOME_RECENT_SYSTEM_UI,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_APP_SWITCH,
+ KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH,
KeyEvent.KEYCODE_ENTER, META_ON},
{"Double tap META + H -> Open App switcher",
new int[]{META_KEY, KeyEvent.KEYCODE_H}, DOUBLE_TAP_HOME_RECENT_SYSTEM_UI,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_APP_SWITCH, KeyEvent.KEYCODE_H,
+ KeyGestureEvent.KEY_GESTURE_TYPE_APP_SWITCH, KeyEvent.KEYCODE_H,
META_ON}};
}
@Keep
private static Object[][] settingsKeyTestArguments() {
- // testName, testKeys, settingsKeyBehavior, expectedSystemShortcut, expectedKey,
+ // testName, testKeys, settingsKeyBehavior, expectedKeyGestureType, expectedKey,
// expectedModifierState
return new Object[][]{
{"SETTINGS key -> Toggle Notification panel", new int[]{KeyEvent.KEYCODE_SETTINGS},
SETTINGS_KEY_BEHAVIOR_NOTIFICATION_PANEL,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TOGGLE_NOTIFICATION_PANEL,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
KeyEvent.KEYCODE_SETTINGS, 0}};
}
@@ -387,21 +385,21 @@
@Test
@Parameters(method = "shortcutTestArguments")
public void testShortcut(String testName, int[] testKeys,
- @KeyboardSystemShortcut.SystemShortcut int expectedSystemShortcut, int expectedKey,
+ @KeyGestureEvent.KeyGestureType int expectedKeyGestureType, int expectedKey,
int expectedModifierState) {
- testShortcutInternal(testName, testKeys, expectedSystemShortcut, expectedKey,
+ testShortcutInternal(testName, testKeys, expectedKeyGestureType, expectedKey,
expectedModifierState);
}
@Test
@Parameters(method = "longPressOnHomeTestArguments")
public void testLongPressOnHome(String testName, int[] testKeys, int longPressOnHomeBehavior,
- @KeyboardSystemShortcut.SystemShortcut int expectedSystemShortcut, int expectedKey,
+ @KeyGestureEvent.KeyGestureType int expectedKeyGestureType, int expectedKey,
int expectedModifierState) {
mPhoneWindowManager.overrideLongPressOnHomeBehavior(longPressOnHomeBehavior);
sendLongPressKeyCombination(testKeys);
- mPhoneWindowManager.assertKeyboardShortcutTriggered(
- new int[]{expectedKey}, expectedModifierState, expectedSystemShortcut,
+ mPhoneWindowManager.assertKeyGestureCompleted(
+ new int[]{expectedKey}, expectedModifierState, expectedKeyGestureType,
"Failed while executing " + testName);
}
@@ -409,23 +407,23 @@
@Parameters(method = "doubleTapOnHomeTestArguments")
public void testDoubleTapOnHomeBehavior(String testName, int[] testKeys,
int doubleTapOnHomeBehavior,
- @KeyboardSystemShortcut.SystemShortcut int expectedSystemShortcut, int expectedKey,
+ @KeyGestureEvent.KeyGestureType int expectedKeyGestureType, int expectedKey,
int expectedModifierState) {
mPhoneWindowManager.overriderDoubleTapOnHomeBehavior(doubleTapOnHomeBehavior);
sendKeyCombination(testKeys, 0 /* duration */);
sendKeyCombination(testKeys, 0 /* duration */);
- mPhoneWindowManager.assertKeyboardShortcutTriggered(
- new int[]{expectedKey}, expectedModifierState, expectedSystemShortcut,
+ mPhoneWindowManager.assertKeyGestureCompleted(
+ new int[]{expectedKey}, expectedModifierState, expectedKeyGestureType,
"Failed while executing " + testName);
}
@Test
@Parameters(method = "settingsKeyTestArguments")
public void testSettingsKey(String testName, int[] testKeys, int settingsKeyBehavior,
- @KeyboardSystemShortcut.SystemShortcut int expectedSystemShortcut, int expectedKey,
+ @KeyGestureEvent.KeyGestureType int expectedKeyGestureType, int expectedKey,
int expectedModifierState) {
mPhoneWindowManager.overrideSettingsKeyBehavior(settingsKeyBehavior);
- testShortcutInternal(testName, testKeys, expectedSystemShortcut, expectedKey,
+ testShortcutInternal(testName, testKeys, expectedKeyGestureType, expectedKey,
expectedModifierState);
}
@@ -434,16 +432,16 @@
public void testBugreportShortcutPress() {
testShortcutInternal("Meta + Ctrl + Del -> Trigger bug report",
new int[]{META_KEY, CTRL_KEY, KeyEvent.KEYCODE_DEL},
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_TRIGGER_BUG_REPORT, KeyEvent.KEYCODE_DEL,
+ KeyGestureEvent.KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT, KeyEvent.KEYCODE_DEL,
META_ON | CTRL_ON);
}
private void testShortcutInternal(String testName, int[] testKeys,
- @KeyboardSystemShortcut.SystemShortcut int expectedSystemShortcut, int expectedKey,
+ @KeyGestureEvent.KeyGestureType int expectedKeyGestureType, int expectedKey,
int expectedModifierState) {
sendKeyCombination(testKeys, 0 /* duration */);
- mPhoneWindowManager.assertKeyboardShortcutTriggered(
- new int[]{expectedKey}, expectedModifierState, expectedSystemShortcut,
+ mPhoneWindowManager.assertKeyGestureCompleted(
+ new int[]{expectedKey}, expectedModifierState, expectedKeyGestureType,
"Failed while executing " + testName);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index f9b5c2a..43b065d 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -70,7 +70,6 @@
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.input.InputManager;
-import android.hardware.input.KeyboardSystemShortcut;
import android.media.AudioManagerInternal;
import android.os.Handler;
import android.os.HandlerThread;
@@ -804,11 +803,11 @@
Assert.assertEquals(targetActivity, intentCaptor.getValue().getComponent());
}
- void assertKeyboardShortcutTriggered(int[] keycodes, int modifierState, int systemShortcut,
+ void assertKeyGestureCompleted(int[] keycodes, int modifierState, int gestureType,
String errorMsg) {
mTestLooper.dispatchAll();
- verify(mInputManagerInternal, description(errorMsg)).notifyKeyboardShortcutTriggered(
- anyInt(), eq(keycodes), eq(modifierState), eq(systemShortcut));
+ verify(mInputManagerInternal, description(errorMsg)).notifyKeyGestureCompleted(
+ anyInt(), eq(keycodes), eq(modifierState), eq(gestureType));
}
void assertSwitchToTask(int persistentId) throws RemoteException {
diff --git a/tests/Input/src/android/hardware/input/KeyGestureEventListenerTest.kt b/tests/Input/src/android/hardware/input/KeyGestureEventListenerTest.kt
new file mode 100644
index 0000000..14aac66
--- /dev/null
+++ b/tests/Input/src/android/hardware/input/KeyGestureEventListenerTest.kt
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.os.Handler
+import android.os.HandlerExecutor
+import android.os.test.TestLooper
+import android.platform.test.annotations.Presubmit
+import android.platform.test.flag.junit.SetFlagsRule
+import android.view.KeyEvent
+import androidx.test.core.app.ApplicationProvider
+import com.android.server.testutils.any
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.`when`
+import org.mockito.junit.MockitoJUnitRunner
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
+import kotlin.test.fail
+
+/**
+ * Tests for [InputManager.KeyGestureEventListener].
+ *
+ * Build/Install/Run:
+ * atest InputTests:KeyGestureEventListenerTest
+ */
+@Presubmit
+@RunWith(MockitoJUnitRunner::class)
+class KeyGestureEventListenerTest {
+
+ companion object {
+ const val DEVICE_ID = 1
+ val HOME_GESTURE_EVENT = KeyGestureEvent(
+ DEVICE_ID,
+ intArrayOf(KeyEvent.KEYCODE_H),
+ KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON,
+ KeyGestureEvent.KEY_GESTURE_TYPE_HOME
+ )
+ }
+
+ @get:Rule
+ val rule = SetFlagsRule()
+
+ private val testLooper = TestLooper()
+ private val executor = HandlerExecutor(Handler(testLooper.looper))
+ private var registeredListener: IKeyGestureEventListener? = null
+ private lateinit var context: Context
+ private lateinit var inputManager: InputManager
+ private lateinit var inputManagerGlobalSession: InputManagerGlobal.TestSession
+
+ @Mock
+ private lateinit var iInputManagerMock: IInputManager
+
+ @Before
+ fun setUp() {
+ context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
+ inputManagerGlobalSession = InputManagerGlobal.createTestSession(iInputManagerMock)
+ inputManager = InputManager(context)
+ `when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
+ .thenReturn(inputManager)
+
+ // Handle key gesture event listener registration.
+ doAnswer {
+ val listener = it.getArgument(0) as IKeyGestureEventListener
+ if (registeredListener != null &&
+ registeredListener!!.asBinder() != listener.asBinder()) {
+ // There can only be one registered key gesture event listener per process.
+ fail("Trying to register a new listener when one already exists")
+ }
+ registeredListener = listener
+ null
+ }.`when`(iInputManagerMock).registerKeyGestureEventListener(any())
+
+ // Handle key gesture event listener being unregistered.
+ doAnswer {
+ val listener = it.getArgument(0) as IKeyGestureEventListener
+ if (registeredListener == null ||
+ registeredListener!!.asBinder() != listener.asBinder()) {
+ fail("Trying to unregister a listener that is not registered")
+ }
+ registeredListener = null
+ null
+ }.`when`(iInputManagerMock).unregisterKeyGestureEventListener(any())
+ }
+
+ @After
+ fun tearDown() {
+ if (this::inputManagerGlobalSession.isInitialized) {
+ inputManagerGlobalSession.close()
+ }
+ }
+
+ private fun notifyKeyGestureEvent(event: KeyGestureEvent) {
+ registeredListener!!.onKeyGestureEvent(
+ event.deviceId,
+ event.keycodes,
+ event.modifierState,
+ event.keyGestureType
+ )
+ }
+
+ @Test
+ fun testListenerHasCorrectGestureNotified() {
+ var callbackCount = 0
+
+ // Add a key gesture event listener
+ inputManager.registerKeyGestureEventListener(executor) {
+ event: KeyGestureEvent ->
+ assertEquals(HOME_GESTURE_EVENT, event)
+ callbackCount++
+ }
+
+ // Notifying key gesture event will notify the listener.
+ notifyKeyGestureEvent(HOME_GESTURE_EVENT)
+ testLooper.dispatchNext()
+ assertEquals(1, callbackCount)
+ }
+
+ @Test
+ fun testAddingListenersRegistersInternalCallbackListener() {
+ // Set up two callbacks.
+ val callback1 = InputManager.KeyGestureEventListener { _ -> }
+ val callback2 = InputManager.KeyGestureEventListener { _ -> }
+
+ assertNull(registeredListener)
+
+ // Adding the listener should register the callback with InputManagerService.
+ inputManager.registerKeyGestureEventListener(executor, callback1)
+ assertNotNull(registeredListener)
+
+ // Adding another listener should not register new internal listener.
+ val currListener = registeredListener
+ inputManager.registerKeyGestureEventListener(executor, callback2)
+ assertEquals(currListener, registeredListener)
+ }
+
+ @Test
+ fun testRemovingListenersUnregistersInternalCallbackListener() {
+ // Set up two callbacks.
+ val callback1 = InputManager.KeyGestureEventListener { _ -> }
+ val callback2 = InputManager.KeyGestureEventListener { _ -> }
+
+ inputManager.registerKeyGestureEventListener(executor, callback1)
+ inputManager.registerKeyGestureEventListener(executor, callback2)
+
+ // Only removing all listeners should remove the internal callback
+ inputManager.unregisterKeyGestureEventListener(callback1)
+ assertNotNull(registeredListener)
+ inputManager.unregisterKeyGestureEventListener(callback2)
+ assertNull(registeredListener)
+ }
+
+ @Test
+ fun testMultipleListeners() {
+ // Set up two callbacks.
+ var callbackCount1 = 0
+ var callbackCount2 = 0
+ val callback1 = InputManager.KeyGestureEventListener { _ -> callbackCount1++ }
+ val callback2 = InputManager.KeyGestureEventListener { _ -> callbackCount2++ }
+
+ // Add both key gesture event listeners
+ inputManager.registerKeyGestureEventListener(executor, callback1)
+ inputManager.registerKeyGestureEventListener(executor, callback2)
+
+ // Notifying key gesture event, should notify both the callbacks.
+ notifyKeyGestureEvent(HOME_GESTURE_EVENT)
+ testLooper.dispatchAll()
+ assertEquals(1, callbackCount1)
+ assertEquals(1, callbackCount2)
+
+ inputManager.unregisterKeyGestureEventListener(callback2)
+ // Notifying key gesture event, should still trigger callback1 but not
+ // callback2.
+ notifyKeyGestureEvent(HOME_GESTURE_EVENT)
+ testLooper.dispatchAll()
+ assertEquals(2, callbackCount1)
+ assertEquals(1, callbackCount2)
+ }
+}
diff --git a/tests/Input/src/android/hardware/input/KeyboardSystemShortcutListenerTest.kt b/tests/Input/src/android/hardware/input/KeyboardSystemShortcutListenerTest.kt
deleted file mode 100644
index 24d7291..0000000
--- a/tests/Input/src/android/hardware/input/KeyboardSystemShortcutListenerTest.kt
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.input
-
-import android.content.Context
-import android.content.ContextWrapper
-import android.os.Handler
-import android.os.HandlerExecutor
-import android.os.test.TestLooper
-import android.platform.test.annotations.Presubmit
-import android.platform.test.flag.junit.SetFlagsRule
-import android.view.KeyEvent
-import androidx.test.core.app.ApplicationProvider
-import com.android.server.testutils.any
-import org.junit.After
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.Mockito.doAnswer
-import org.mockito.Mockito.`when`
-import org.mockito.junit.MockitoJUnitRunner
-import kotlin.test.assertEquals
-import kotlin.test.assertNotNull
-import kotlin.test.assertNull
-import kotlin.test.fail
-
-/**
- * Tests for [InputManager.KeyboardSystemShortcutListener].
- *
- * Build/Install/Run:
- * atest InputTests:KeyboardSystemShortcutListenerTest
- */
-@Presubmit
-@RunWith(MockitoJUnitRunner::class)
-class KeyboardSystemShortcutListenerTest {
-
- companion object {
- const val DEVICE_ID = 1
- val HOME_SHORTCUT = KeyboardSystemShortcut(
- intArrayOf(KeyEvent.KEYCODE_H),
- KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_HOME
- )
- }
-
- @get:Rule
- val rule = SetFlagsRule()
-
- private val testLooper = TestLooper()
- private val executor = HandlerExecutor(Handler(testLooper.looper))
- private var registeredListener: IKeyboardSystemShortcutListener? = null
- private lateinit var context: Context
- private lateinit var inputManager: InputManager
- private lateinit var inputManagerGlobalSession: InputManagerGlobal.TestSession
-
- @Mock
- private lateinit var iInputManagerMock: IInputManager
-
- @Before
- fun setUp() {
- context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
- inputManagerGlobalSession = InputManagerGlobal.createTestSession(iInputManagerMock)
- inputManager = InputManager(context)
- `when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
- .thenReturn(inputManager)
-
- // Handle keyboard system shortcut listener registration.
- doAnswer {
- val listener = it.getArgument(0) as IKeyboardSystemShortcutListener
- if (registeredListener != null &&
- registeredListener!!.asBinder() != listener.asBinder()) {
- // There can only be one registered keyboard system shortcut listener per process.
- fail("Trying to register a new listener when one already exists")
- }
- registeredListener = listener
- null
- }.`when`(iInputManagerMock).registerKeyboardSystemShortcutListener(any())
-
- // Handle keyboard system shortcut listener being unregistered.
- doAnswer {
- val listener = it.getArgument(0) as IKeyboardSystemShortcutListener
- if (registeredListener == null ||
- registeredListener!!.asBinder() != listener.asBinder()) {
- fail("Trying to unregister a listener that is not registered")
- }
- registeredListener = null
- null
- }.`when`(iInputManagerMock).unregisterKeyboardSystemShortcutListener(any())
- }
-
- @After
- fun tearDown() {
- if (this::inputManagerGlobalSession.isInitialized) {
- inputManagerGlobalSession.close()
- }
- }
-
- private fun notifyKeyboardSystemShortcutTriggered(id: Int, shortcut: KeyboardSystemShortcut) {
- registeredListener!!.onKeyboardSystemShortcutTriggered(
- id,
- shortcut.keycodes,
- shortcut.modifierState,
- shortcut.systemShortcut
- )
- }
-
- @Test
- fun testListenerHasCorrectSystemShortcutNotified() {
- var callbackCount = 0
-
- // Add a keyboard system shortcut listener
- inputManager.registerKeyboardSystemShortcutListener(executor) {
- deviceId: Int, systemShortcut: KeyboardSystemShortcut ->
- assertEquals(DEVICE_ID, deviceId)
- assertEquals(HOME_SHORTCUT, systemShortcut)
- callbackCount++
- }
-
- // Notifying keyboard system shortcut triggered will notify the listener.
- notifyKeyboardSystemShortcutTriggered(DEVICE_ID, HOME_SHORTCUT)
- testLooper.dispatchNext()
- assertEquals(1, callbackCount)
- }
-
- @Test
- fun testAddingListenersRegistersInternalCallbackListener() {
- // Set up two callbacks.
- val callback1 = InputManager.KeyboardSystemShortcutListener {_, _ -> }
- val callback2 = InputManager.KeyboardSystemShortcutListener {_, _ -> }
-
- assertNull(registeredListener)
-
- // Adding the listener should register the callback with InputManagerService.
- inputManager.registerKeyboardSystemShortcutListener(executor, callback1)
- assertNotNull(registeredListener)
-
- // Adding another listener should not register new internal listener.
- val currListener = registeredListener
- inputManager.registerKeyboardSystemShortcutListener(executor, callback2)
- assertEquals(currListener, registeredListener)
- }
-
- @Test
- fun testRemovingListenersUnregistersInternalCallbackListener() {
- // Set up two callbacks.
- val callback1 = InputManager.KeyboardSystemShortcutListener {_, _ -> }
- val callback2 = InputManager.KeyboardSystemShortcutListener {_, _ -> }
-
- inputManager.registerKeyboardSystemShortcutListener(executor, callback1)
- inputManager.registerKeyboardSystemShortcutListener(executor, callback2)
-
- // Only removing all listeners should remove the internal callback
- inputManager.unregisterKeyboardSystemShortcutListener(callback1)
- assertNotNull(registeredListener)
- inputManager.unregisterKeyboardSystemShortcutListener(callback2)
- assertNull(registeredListener)
- }
-
- @Test
- fun testMultipleListeners() {
- // Set up two callbacks.
- var callbackCount1 = 0
- var callbackCount2 = 0
- val callback1 = InputManager.KeyboardSystemShortcutListener { _, _ -> callbackCount1++ }
- val callback2 = InputManager.KeyboardSystemShortcutListener { _, _ -> callbackCount2++ }
-
- // Add both keyboard system shortcut listeners
- inputManager.registerKeyboardSystemShortcutListener(executor, callback1)
- inputManager.registerKeyboardSystemShortcutListener(executor, callback2)
-
- // Notifying keyboard system shortcut triggered, should notify both the callbacks.
- notifyKeyboardSystemShortcutTriggered(DEVICE_ID, HOME_SHORTCUT)
- testLooper.dispatchAll()
- assertEquals(1, callbackCount1)
- assertEquals(1, callbackCount2)
-
- inputManager.unregisterKeyboardSystemShortcutListener(callback2)
- // Notifying keyboard system shortcut triggered, should still trigger callback1 but not
- // callback2.
- notifyKeyboardSystemShortcutTriggered(DEVICE_ID, HOME_SHORTCUT)
- testLooper.dispatchAll()
- assertEquals(2, callbackCount1)
- assertEquals(1, callbackCount2)
- }
-}
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
new file mode 100644
index 0000000..3f611e0
--- /dev/null
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.input
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.hardware.input.IKeyGestureEventListener
+import android.hardware.input.KeyGestureEvent
+import android.platform.test.annotations.Presubmit
+import android.view.KeyEvent
+import androidx.test.core.app.ApplicationProvider
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.mockito.Mockito
+import org.mockito.junit.MockitoJUnit
+
+/**
+ * Tests for {@link KeyGestureController}.
+ *
+ * Build/Install/Run:
+ * atest InputTests:KeyGestureControllerTests
+ */
+@Presubmit
+class KeyGestureControllerTests {
+
+ companion object {
+ val DEVICE_ID = 1
+ val HOME_GESTURE_EVENT = KeyGestureEvent(
+ DEVICE_ID,
+ intArrayOf(KeyEvent.KEYCODE_H),
+ KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON,
+ KeyGestureEvent.KEY_GESTURE_TYPE_HOME
+ )
+ }
+
+ @get:Rule
+ val rule = MockitoJUnit.rule()!!
+
+ private lateinit var keyGestureController: KeyGestureController
+ private lateinit var context: Context
+ private var lastEvent: KeyGestureEvent? = null
+
+ @Before
+ fun setup() {
+ context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
+ keyGestureController = KeyGestureController()
+ }
+
+ @Test
+ fun testKeyGestureEvent_registerUnregisterListener() {
+ val listener = KeyGestureEventListener()
+
+ // Register key gesture event listener
+ keyGestureController.registerKeyGestureEventListener(listener, 0)
+ keyGestureController.onKeyGestureEvent(HOME_GESTURE_EVENT)
+ assertEquals(
+ "Listener should get callback on key gesture event",
+ HOME_GESTURE_EVENT,
+ lastEvent!!
+ )
+
+ // Unregister listener
+ lastEvent = null
+ keyGestureController.unregisterKeyGestureEventListener(listener, 0)
+ keyGestureController.onKeyGestureEvent(HOME_GESTURE_EVENT)
+ assertNull("Listener should not get callback after being unregistered", lastEvent)
+ }
+
+ inner class KeyGestureEventListener : IKeyGestureEventListener.Stub() {
+ override fun onKeyGestureEvent(
+ deviceId: Int,
+ keycodes: IntArray,
+ modifierState: Int,
+ gestureType: Int
+ ) {
+ lastEvent = KeyGestureEvent(deviceId, keycodes, modifierState, gestureType)
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/Input/src/com/android/server/input/KeyboardShortcutCallbackHandlerTests.kt b/tests/Input/src/com/android/server/input/KeyboardShortcutCallbackHandlerTests.kt
deleted file mode 100644
index 5a40a1c..0000000
--- a/tests/Input/src/com/android/server/input/KeyboardShortcutCallbackHandlerTests.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.input
-
-import android.content.Context
-import android.content.ContextWrapper
-import android.hardware.input.IKeyboardSystemShortcutListener
-import android.hardware.input.KeyboardSystemShortcut
-import android.platform.test.annotations.Presubmit
-import android.view.KeyEvent
-import androidx.test.core.app.ApplicationProvider
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertNull
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.mockito.Mockito
-import org.mockito.junit.MockitoJUnit
-
-/**
- * Tests for {@link KeyboardShortcutCallbackHandler}.
- *
- * Build/Install/Run:
- * atest InputTests:KeyboardShortcutCallbackHandlerTests
- */
-@Presubmit
-class KeyboardShortcutCallbackHandlerTests {
-
- companion object {
- val DEVICE_ID = 1
- val HOME_SHORTCUT = KeyboardSystemShortcut(
- intArrayOf(KeyEvent.KEYCODE_H),
- KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON,
- KeyboardSystemShortcut.SYSTEM_SHORTCUT_HOME
- )
- }
-
- @get:Rule
- val rule = MockitoJUnit.rule()!!
-
- private lateinit var keyboardShortcutCallbackHandler: KeyboardShortcutCallbackHandler
- private lateinit var context: Context
- private var lastShortcut: KeyboardSystemShortcut? = null
-
- @Before
- fun setup() {
- context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
- keyboardShortcutCallbackHandler = KeyboardShortcutCallbackHandler()
- }
-
- @Test
- fun testKeyboardSystemShortcutTriggered_registerUnregisterListener() {
- val listener = KeyboardSystemShortcutListener()
-
- // Register keyboard system shortcut listener
- keyboardShortcutCallbackHandler.registerKeyboardSystemShortcutListener(listener, 0)
- keyboardShortcutCallbackHandler.onKeyboardSystemShortcutTriggered(DEVICE_ID, HOME_SHORTCUT)
- assertEquals(
- "Listener should get callback on keyboard system shortcut triggered",
- HOME_SHORTCUT,
- lastShortcut!!
- )
-
- // Unregister listener
- lastShortcut = null
- keyboardShortcutCallbackHandler.unregisterKeyboardSystemShortcutListener(listener, 0)
- keyboardShortcutCallbackHandler.onKeyboardSystemShortcutTriggered(DEVICE_ID, HOME_SHORTCUT)
- assertNull("Listener should not get callback after being unregistered", lastShortcut)
- }
-
- inner class KeyboardSystemShortcutListener : IKeyboardSystemShortcutListener.Stub() {
- override fun onKeyboardSystemShortcutTriggered(
- deviceId: Int,
- keycodes: IntArray,
- modifierState: Int,
- shortcut: Int
- ) {
- assertEquals(DEVICE_ID, deviceId)
- lastShortcut = KeyboardSystemShortcut(keycodes, modifierState, shortcut)
- }
- }
-}
\ No newline at end of file