Loading core/java/android/hardware/input/AidlKeyGestureEvent.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -26,4 +26,10 @@ parcelable AidlKeyGestureEvent { int action; int displayId; int flags; // App launch parameters: only set when gestureType = KEY_GESTURE_TYPE_LAUNCH_APPLICATION String appLaunchCategory; String appLaunchRole; String appLaunchPackageName; String appLaunchClassName; } core/java/android/hardware/input/AppLaunchData.java 0 → 100644 +176 −0 Original line number Diff line number Diff line /* * 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.NonNull; import android.annotation.Nullable; import android.text.TextUtils; import java.util.Objects; /** * Provides data for launching an application. * * @hide */ public interface AppLaunchData { /** Creates AppLaunchData for the provided category */ @NonNull static AppLaunchData createLaunchDataForCategory(@NonNull String category) { return new CategoryData(category); } /** Creates AppLaunchData for the provided role */ @NonNull static AppLaunchData createLaunchDataForRole(@NonNull String role) { return new RoleData(role); } /** Creates AppLaunchData for the target package name and class name */ @NonNull static AppLaunchData createLaunchDataForComponent(@NonNull String packageName, @NonNull String className) { return new ComponentData(packageName, className); } @Nullable static AppLaunchData createLaunchData(@Nullable String category, @Nullable String role, @Nullable String packageName, @Nullable String className) { if (!TextUtils.isEmpty(category)) { return new CategoryData(category); } if (!TextUtils.isEmpty(role)) { return new RoleData(role); } if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) { return new ComponentData(packageName, className); } return null; } /** Intent category based app launch data */ class CategoryData implements AppLaunchData { @NonNull private final String mCategory; public CategoryData(@NonNull String category) { mCategory = category; } @NonNull public String getCategory() { return mCategory; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof CategoryData that)) return false; return Objects.equals(mCategory, that.mCategory); } @Override public int hashCode() { return Objects.hash(mCategory); } @Override public String toString() { return "CategoryData{" + "mCategory='" + mCategory + '\'' + '}'; } } /** Role based app launch data */ class RoleData implements AppLaunchData { @NonNull private final String mRole; public RoleData(@NonNull String role) { mRole = role; } @NonNull public String getRole() { return mRole; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof RoleData roleData)) return false; return Objects.equals(mRole, roleData.mRole); } @Override public int hashCode() { return Objects.hash(mRole); } @Override public String toString() { return "RoleData{" + "mRole='" + mRole + '\'' + '}'; } } /** Target application launch data */ class ComponentData implements AppLaunchData { @NonNull private final String mPackageName; @NonNull private final String mClassName; public ComponentData(@NonNull String packageName, @NonNull String className) { mPackageName = packageName; mClassName = className; } @NonNull public String getPackageName() { return mPackageName; } @NonNull public String getClassName() { return mClassName; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ComponentData that)) return false; return Objects.equals(mPackageName, that.mPackageName) && Objects.equals( mClassName, that.mClassName); } @Override public int hashCode() { return Objects.hash(mPackageName, mClassName); } @Override public String toString() { return "ComponentData{" + "mPackageName='" + mPackageName + '\'' + ", mClassName='" + mClassName + '\'' + '}'; } } } core/java/android/hardware/input/KeyGestureEvent.java +141 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package android.hardware.input; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.role.RoleManager; import android.content.Intent; import android.view.Display; import android.view.KeyCharacterMap; Loading @@ -26,6 +28,7 @@ import com.android.internal.util.FrameworkStatsLog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** * Provides information about the keyboard gesture event being triggered by an external keyboard. Loading @@ -37,6 +40,9 @@ public final class KeyGestureEvent { @NonNull private AidlKeyGestureEvent mKeyGestureEvent; private static final int LOG_EVENT_UNSPECIFIED = FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED; public static final int KEY_GESTURE_TYPE_UNSPECIFIED = 0; public static final int KEY_GESTURE_TYPE_HOME = 1; public static final int KEY_GESTURE_TYPE_RECENT_APPS = 2; Loading Loading @@ -76,6 +82,8 @@ public final class KeyGestureEvent { public static final int KEY_GESTURE_TYPE_SLEEP = 36; public static final int KEY_GESTURE_TYPE_WAKEUP = 37; public static final int KEY_GESTURE_TYPE_MEDIA_KEY = 38; // TODO(b/280423320): Remove "LAUNCH_DEFAULT_..." gestures and rely on launch intent to find // the correct logging event. public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER = 39; public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL = 40; public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS = 41; Loading @@ -88,7 +96,7 @@ public final class KeyGestureEvent { public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES = 48; public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER = 49; public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS = 50; public static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME = 51; public static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION = 51; public static final int KEY_GESTURE_TYPE_DESKTOP_MODE = 52; public static final int KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION = 53; public static final int KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER = 54; Loading Loading @@ -166,7 +174,7 @@ public final class KeyGestureEvent { 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_LAUNCH_APPLICATION, KEY_GESTURE_TYPE_DESKTOP_MODE, KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION, KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER, Loading Loading @@ -210,6 +218,8 @@ public final class KeyGestureEvent { private int mAction = KeyGestureEvent.ACTION_GESTURE_COMPLETE; private int mDisplayId = Display.DEFAULT_DISPLAY; private int mFlags = 0; @Nullable private AppLaunchData mAppLaunchData = null; /** * @see KeyGestureEvent#getDeviceId() Loading Loading @@ -267,6 +277,14 @@ public final class KeyGestureEvent { return this; } /** * @see KeyGestureEvent#getAppLaunchData() */ public Builder setAppLaunchData(@NonNull AppLaunchData appLaunchData) { mAppLaunchData = appLaunchData; return this; } /** * Build {@link KeyGestureEvent} */ Loading @@ -279,6 +297,21 @@ public final class KeyGestureEvent { event.action = mAction; event.displayId = mDisplayId; event.flags = mFlags; if (mAppLaunchData != null) { if (mAppLaunchData instanceof AppLaunchData.CategoryData) { event.appLaunchCategory = ((AppLaunchData.CategoryData) mAppLaunchData).getCategory(); } else if (mAppLaunchData instanceof AppLaunchData.RoleData) { event.appLaunchRole = ((AppLaunchData.RoleData) mAppLaunchData).getRole(); } else if (mAppLaunchData instanceof AppLaunchData.ComponentData) { event.appLaunchPackageName = ((AppLaunchData.ComponentData) mAppLaunchData).getPackageName(); event.appLaunchClassName = ((AppLaunchData.ComponentData) mAppLaunchData).getClassName(); } else { throw new IllegalArgumentException("AppLaunchData type is invalid!"); } } return new KeyGestureEvent(event); } } Loading Loading @@ -315,6 +348,27 @@ public final class KeyGestureEvent { return (mKeyGestureEvent.flags & FLAG_CANCELLED) != 0; } public int getLogEvent() { if (getKeyGestureType() == KEY_GESTURE_TYPE_LAUNCH_APPLICATION) { return getLogEventFromLaunchAppData(getAppLaunchData()); } return keyGestureTypeToLogEvent(getKeyGestureType()); } /** * @return Launch app data associated with the event, only if key gesture type is * {@code KEY_GESTURE_TYPE_LAUNCH_APPLICATION} */ @Nullable public AppLaunchData getAppLaunchData() { if (mKeyGestureEvent.gestureType != KEY_GESTURE_TYPE_LAUNCH_APPLICATION) { return null; } return AppLaunchData.createLaunchData(mKeyGestureEvent.appLaunchCategory, mKeyGestureEvent.appLaunchRole, mKeyGestureEvent.appLaunchPackageName, mKeyGestureEvent.appLaunchClassName); } @Override public String toString() { return "KeyGestureEvent { " Loading @@ -324,7 +378,8 @@ public final class KeyGestureEvent { + "keyGestureType = " + keyGestureTypeToString(mKeyGestureEvent.gestureType) + ", " + "action = " + mKeyGestureEvent.action + ", " + "displayId = " + mKeyGestureEvent.displayId + ", " + "flags = " + mKeyGestureEvent.flags + "flags = " + mKeyGestureEvent.flags + ", " + "appLaunchData = " + getAppLaunchData() + " }"; } Loading @@ -339,7 +394,11 @@ public final class KeyGestureEvent { && mKeyGestureEvent.gestureType == that.mKeyGestureEvent.gestureType && mKeyGestureEvent.action == that.mKeyGestureEvent.action && mKeyGestureEvent.displayId == that.mKeyGestureEvent.displayId && mKeyGestureEvent.flags == that.mKeyGestureEvent.flags; && mKeyGestureEvent.flags == that.mKeyGestureEvent.flags && Objects.equals(mKeyGestureEvent.appLaunchCategory, that.mKeyGestureEvent.appLaunchCategory) && Objects.equals(mKeyGestureEvent.appLaunchRole, that.mKeyGestureEvent.appLaunchRole) && Objects.equals(mKeyGestureEvent.appLaunchPackageName, that.mKeyGestureEvent.appLaunchPackageName) && Objects.equals(mKeyGestureEvent.appLaunchClassName, that.mKeyGestureEvent.appLaunchClassName); } @Override Loading @@ -352,13 +411,21 @@ public final class KeyGestureEvent { _hash = 31 * _hash + mKeyGestureEvent.action; _hash = 31 * _hash + mKeyGestureEvent.displayId; _hash = 31 * _hash + mKeyGestureEvent.flags; _hash = 31 * _hash + (mKeyGestureEvent.appLaunchCategory != null ? mKeyGestureEvent.appLaunchCategory.hashCode() : 0); _hash = 31 * _hash + (mKeyGestureEvent.appLaunchRole != null ? mKeyGestureEvent.appLaunchRole.hashCode() : 0); _hash = 31 * _hash + (mKeyGestureEvent.appLaunchPackageName != null ? mKeyGestureEvent.appLaunchPackageName.hashCode() : 0); _hash = 31 * _hash + (mKeyGestureEvent.appLaunchClassName != null ? mKeyGestureEvent.appLaunchClassName.hashCode() : 0); return _hash; } /** * Convert KeyGestureEvent type to corresponding log event got KeyboardSystemsEvent */ public static int keyGestureTypeToLogEvent(@KeyGestureType int value) { private static int keyGestureTypeToLogEvent(@KeyGestureType int value) { switch (value) { case KEY_GESTURE_TYPE_HOME: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME; Loading Loading @@ -460,14 +527,79 @@ public final class KeyGestureEvent { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER; case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS; case KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME: case KEY_GESTURE_TYPE_LAUNCH_APPLICATION: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME; case KEY_GESTURE_TYPE_DESKTOP_MODE: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE; case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION; default: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED; return LOG_EVENT_UNSPECIFIED; } } /** * Find Log event type corresponding to app launch data. * Returns {@code LOG_EVENT_UNSPECIFIED} if no matching event found */ private static int getLogEventFromLaunchAppData(@Nullable AppLaunchData data) { if (data == null) { return LOG_EVENT_UNSPECIFIED; } if (data instanceof AppLaunchData.CategoryData) { return getLogEventFromSelectorCategory( ((AppLaunchData.CategoryData) data).getCategory()); } else if (data instanceof AppLaunchData.RoleData) { return getLogEventFromRole(((AppLaunchData.RoleData) data).getRole()); } else if (data instanceof AppLaunchData.ComponentData) { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME; } else { throw new IllegalArgumentException("AppLaunchData type is invalid!"); } } private static int getLogEventFromSelectorCategory(@NonNull String category) { switch (category) { case Intent.CATEGORY_APP_BROWSER: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER; case Intent.CATEGORY_APP_EMAIL: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_EMAIL; case Intent.CATEGORY_APP_CONTACTS: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CONTACTS; case Intent.CATEGORY_APP_CALENDAR: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALENDAR; case Intent.CATEGORY_APP_CALCULATOR: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALCULATOR; case Intent.CATEGORY_APP_MUSIC: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MUSIC; case Intent.CATEGORY_APP_MAPS: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MAPS; case Intent.CATEGORY_APP_MESSAGING: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING; case Intent.CATEGORY_APP_GALLERY: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_GALLERY; case Intent.CATEGORY_APP_FILES: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FILES; case Intent.CATEGORY_APP_WEATHER: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER; case Intent.CATEGORY_APP_FITNESS: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS; default: return LOG_EVENT_UNSPECIFIED; } } /** * Find Log event corresponding to the provide system role name. * Returns {@code LOG_EVENT_UNSPECIFIED} if no matching event found. */ private static int getLogEventFromRole(@NonNull String role) { if (RoleManager.ROLE_BROWSER.equals(role)) { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER; } else if (RoleManager.ROLE_SMS.equals(role)) { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING; } else { return LOG_EVENT_UNSPECIFIED; } } Loading Loading @@ -577,8 +709,8 @@ public final class KeyGestureEvent { 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_LAUNCH_APPLICATION: return "KEY_GESTURE_TYPE_LAUNCH_APPLICATION"; case KEY_GESTURE_TYPE_DESKTOP_MODE: return "KEY_GESTURE_TYPE_DESKTOP_MODE"; case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION: Loading services/core/java/com/android/server/input/InputManagerInternal.java +7 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,13 @@ public abstract class InputManagerInternal { */ public abstract void notifyInputMethodConnectionActive(boolean connectionIsActive); /** * Notify user id changes to input. * * TODO(b/362473586): Cleanup after input shifts to Lifecycle with user change callbacks */ public abstract void setCurrentUser(@UserIdInt int newUserId); /** Callback interface for notifications relating to the lid switch. */ public interface LidSwitchCallback { /** Loading services/core/java/com/android/server/input/InputManagerService.java +15 −0 Original line number Diff line number Diff line Loading @@ -175,6 +175,7 @@ public class InputManagerService extends IInputManager.Stub 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_CURRENT_USER_CHANGED = 4; private static final int DEFAULT_VIBRATION_MAGNITUDE = 192; private static final AdditionalDisplayInputProperties Loading @@ -184,6 +185,8 @@ public class InputManagerService extends IInputManager.Stub private final Context mContext; private final InputManagerHandler mHandler; @UserIdInt private int mCurrentUserId = UserHandle.USER_SYSTEM; private DisplayManagerInternal mDisplayManagerInternal; private WindowManagerInternal mWindowManagerInternal; Loading Loading @@ -2982,6 +2985,10 @@ public class InputManagerService extends IInputManager.Stub mKeyGestureController.unregisterKeyGestureHandler(handler, Binder.getCallingPid()); } private void handleCurrentUserChanged(@UserIdInt int userId) { mCurrentUserId = userId; } /** * Callback interface implemented by the Window Manager. */ Loading Loading @@ -3150,6 +3157,9 @@ public class InputManagerService extends IInputManager.Stub boolean inTabletMode = (boolean) args.arg1; deliverTabletModeChanged(whenNanos, inTabletMode); break; case MSG_CURRENT_USER_CHANGED: handleCurrentUserChanged((int) msg.obj); break; } } } Loading Loading @@ -3512,6 +3522,11 @@ public class InputManagerService extends IInputManager.Stub InputManagerService.this.setAccessibilityPointerIconScaleFactor(displayId, scaleFactor); } @Override public void setCurrentUser(@UserIdInt int newUserId) { mHandler.obtainMessage(MSG_CURRENT_USER_CHANGED, newUserId).sendToTarget(); } @Override public boolean setKernelWakeEnabled(int deviceId, boolean enabled) { return mNative.setKernelWakeEnabled(deviceId, enabled); Loading Loading
core/java/android/hardware/input/AidlKeyGestureEvent.aidl +6 −0 Original line number Diff line number Diff line Loading @@ -26,4 +26,10 @@ parcelable AidlKeyGestureEvent { int action; int displayId; int flags; // App launch parameters: only set when gestureType = KEY_GESTURE_TYPE_LAUNCH_APPLICATION String appLaunchCategory; String appLaunchRole; String appLaunchPackageName; String appLaunchClassName; }
core/java/android/hardware/input/AppLaunchData.java 0 → 100644 +176 −0 Original line number Diff line number Diff line /* * 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.NonNull; import android.annotation.Nullable; import android.text.TextUtils; import java.util.Objects; /** * Provides data for launching an application. * * @hide */ public interface AppLaunchData { /** Creates AppLaunchData for the provided category */ @NonNull static AppLaunchData createLaunchDataForCategory(@NonNull String category) { return new CategoryData(category); } /** Creates AppLaunchData for the provided role */ @NonNull static AppLaunchData createLaunchDataForRole(@NonNull String role) { return new RoleData(role); } /** Creates AppLaunchData for the target package name and class name */ @NonNull static AppLaunchData createLaunchDataForComponent(@NonNull String packageName, @NonNull String className) { return new ComponentData(packageName, className); } @Nullable static AppLaunchData createLaunchData(@Nullable String category, @Nullable String role, @Nullable String packageName, @Nullable String className) { if (!TextUtils.isEmpty(category)) { return new CategoryData(category); } if (!TextUtils.isEmpty(role)) { return new RoleData(role); } if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) { return new ComponentData(packageName, className); } return null; } /** Intent category based app launch data */ class CategoryData implements AppLaunchData { @NonNull private final String mCategory; public CategoryData(@NonNull String category) { mCategory = category; } @NonNull public String getCategory() { return mCategory; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof CategoryData that)) return false; return Objects.equals(mCategory, that.mCategory); } @Override public int hashCode() { return Objects.hash(mCategory); } @Override public String toString() { return "CategoryData{" + "mCategory='" + mCategory + '\'' + '}'; } } /** Role based app launch data */ class RoleData implements AppLaunchData { @NonNull private final String mRole; public RoleData(@NonNull String role) { mRole = role; } @NonNull public String getRole() { return mRole; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof RoleData roleData)) return false; return Objects.equals(mRole, roleData.mRole); } @Override public int hashCode() { return Objects.hash(mRole); } @Override public String toString() { return "RoleData{" + "mRole='" + mRole + '\'' + '}'; } } /** Target application launch data */ class ComponentData implements AppLaunchData { @NonNull private final String mPackageName; @NonNull private final String mClassName; public ComponentData(@NonNull String packageName, @NonNull String className) { mPackageName = packageName; mClassName = className; } @NonNull public String getPackageName() { return mPackageName; } @NonNull public String getClassName() { return mClassName; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ComponentData that)) return false; return Objects.equals(mPackageName, that.mPackageName) && Objects.equals( mClassName, that.mClassName); } @Override public int hashCode() { return Objects.hash(mPackageName, mClassName); } @Override public String toString() { return "ComponentData{" + "mPackageName='" + mPackageName + '\'' + ", mClassName='" + mClassName + '\'' + '}'; } } }
core/java/android/hardware/input/KeyGestureEvent.java +141 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package android.hardware.input; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.role.RoleManager; import android.content.Intent; import android.view.Display; import android.view.KeyCharacterMap; Loading @@ -26,6 +28,7 @@ import com.android.internal.util.FrameworkStatsLog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** * Provides information about the keyboard gesture event being triggered by an external keyboard. Loading @@ -37,6 +40,9 @@ public final class KeyGestureEvent { @NonNull private AidlKeyGestureEvent mKeyGestureEvent; private static final int LOG_EVENT_UNSPECIFIED = FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED; public static final int KEY_GESTURE_TYPE_UNSPECIFIED = 0; public static final int KEY_GESTURE_TYPE_HOME = 1; public static final int KEY_GESTURE_TYPE_RECENT_APPS = 2; Loading Loading @@ -76,6 +82,8 @@ public final class KeyGestureEvent { public static final int KEY_GESTURE_TYPE_SLEEP = 36; public static final int KEY_GESTURE_TYPE_WAKEUP = 37; public static final int KEY_GESTURE_TYPE_MEDIA_KEY = 38; // TODO(b/280423320): Remove "LAUNCH_DEFAULT_..." gestures and rely on launch intent to find // the correct logging event. public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_BROWSER = 39; public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_EMAIL = 40; public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_CONTACTS = 41; Loading @@ -88,7 +96,7 @@ public final class KeyGestureEvent { public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FILES = 48; public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_WEATHER = 49; public static final int KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS = 50; public static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME = 51; public static final int KEY_GESTURE_TYPE_LAUNCH_APPLICATION = 51; public static final int KEY_GESTURE_TYPE_DESKTOP_MODE = 52; public static final int KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION = 53; public static final int KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER = 54; Loading Loading @@ -166,7 +174,7 @@ public final class KeyGestureEvent { 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_LAUNCH_APPLICATION, KEY_GESTURE_TYPE_DESKTOP_MODE, KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION, KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER, Loading Loading @@ -210,6 +218,8 @@ public final class KeyGestureEvent { private int mAction = KeyGestureEvent.ACTION_GESTURE_COMPLETE; private int mDisplayId = Display.DEFAULT_DISPLAY; private int mFlags = 0; @Nullable private AppLaunchData mAppLaunchData = null; /** * @see KeyGestureEvent#getDeviceId() Loading Loading @@ -267,6 +277,14 @@ public final class KeyGestureEvent { return this; } /** * @see KeyGestureEvent#getAppLaunchData() */ public Builder setAppLaunchData(@NonNull AppLaunchData appLaunchData) { mAppLaunchData = appLaunchData; return this; } /** * Build {@link KeyGestureEvent} */ Loading @@ -279,6 +297,21 @@ public final class KeyGestureEvent { event.action = mAction; event.displayId = mDisplayId; event.flags = mFlags; if (mAppLaunchData != null) { if (mAppLaunchData instanceof AppLaunchData.CategoryData) { event.appLaunchCategory = ((AppLaunchData.CategoryData) mAppLaunchData).getCategory(); } else if (mAppLaunchData instanceof AppLaunchData.RoleData) { event.appLaunchRole = ((AppLaunchData.RoleData) mAppLaunchData).getRole(); } else if (mAppLaunchData instanceof AppLaunchData.ComponentData) { event.appLaunchPackageName = ((AppLaunchData.ComponentData) mAppLaunchData).getPackageName(); event.appLaunchClassName = ((AppLaunchData.ComponentData) mAppLaunchData).getClassName(); } else { throw new IllegalArgumentException("AppLaunchData type is invalid!"); } } return new KeyGestureEvent(event); } } Loading Loading @@ -315,6 +348,27 @@ public final class KeyGestureEvent { return (mKeyGestureEvent.flags & FLAG_CANCELLED) != 0; } public int getLogEvent() { if (getKeyGestureType() == KEY_GESTURE_TYPE_LAUNCH_APPLICATION) { return getLogEventFromLaunchAppData(getAppLaunchData()); } return keyGestureTypeToLogEvent(getKeyGestureType()); } /** * @return Launch app data associated with the event, only if key gesture type is * {@code KEY_GESTURE_TYPE_LAUNCH_APPLICATION} */ @Nullable public AppLaunchData getAppLaunchData() { if (mKeyGestureEvent.gestureType != KEY_GESTURE_TYPE_LAUNCH_APPLICATION) { return null; } return AppLaunchData.createLaunchData(mKeyGestureEvent.appLaunchCategory, mKeyGestureEvent.appLaunchRole, mKeyGestureEvent.appLaunchPackageName, mKeyGestureEvent.appLaunchClassName); } @Override public String toString() { return "KeyGestureEvent { " Loading @@ -324,7 +378,8 @@ public final class KeyGestureEvent { + "keyGestureType = " + keyGestureTypeToString(mKeyGestureEvent.gestureType) + ", " + "action = " + mKeyGestureEvent.action + ", " + "displayId = " + mKeyGestureEvent.displayId + ", " + "flags = " + mKeyGestureEvent.flags + "flags = " + mKeyGestureEvent.flags + ", " + "appLaunchData = " + getAppLaunchData() + " }"; } Loading @@ -339,7 +394,11 @@ public final class KeyGestureEvent { && mKeyGestureEvent.gestureType == that.mKeyGestureEvent.gestureType && mKeyGestureEvent.action == that.mKeyGestureEvent.action && mKeyGestureEvent.displayId == that.mKeyGestureEvent.displayId && mKeyGestureEvent.flags == that.mKeyGestureEvent.flags; && mKeyGestureEvent.flags == that.mKeyGestureEvent.flags && Objects.equals(mKeyGestureEvent.appLaunchCategory, that.mKeyGestureEvent.appLaunchCategory) && Objects.equals(mKeyGestureEvent.appLaunchRole, that.mKeyGestureEvent.appLaunchRole) && Objects.equals(mKeyGestureEvent.appLaunchPackageName, that.mKeyGestureEvent.appLaunchPackageName) && Objects.equals(mKeyGestureEvent.appLaunchClassName, that.mKeyGestureEvent.appLaunchClassName); } @Override Loading @@ -352,13 +411,21 @@ public final class KeyGestureEvent { _hash = 31 * _hash + mKeyGestureEvent.action; _hash = 31 * _hash + mKeyGestureEvent.displayId; _hash = 31 * _hash + mKeyGestureEvent.flags; _hash = 31 * _hash + (mKeyGestureEvent.appLaunchCategory != null ? mKeyGestureEvent.appLaunchCategory.hashCode() : 0); _hash = 31 * _hash + (mKeyGestureEvent.appLaunchRole != null ? mKeyGestureEvent.appLaunchRole.hashCode() : 0); _hash = 31 * _hash + (mKeyGestureEvent.appLaunchPackageName != null ? mKeyGestureEvent.appLaunchPackageName.hashCode() : 0); _hash = 31 * _hash + (mKeyGestureEvent.appLaunchClassName != null ? mKeyGestureEvent.appLaunchClassName.hashCode() : 0); return _hash; } /** * Convert KeyGestureEvent type to corresponding log event got KeyboardSystemsEvent */ public static int keyGestureTypeToLogEvent(@KeyGestureType int value) { private static int keyGestureTypeToLogEvent(@KeyGestureType int value) { switch (value) { case KEY_GESTURE_TYPE_HOME: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME; Loading Loading @@ -460,14 +527,79 @@ public final class KeyGestureEvent { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER; case KEY_GESTURE_TYPE_LAUNCH_DEFAULT_FITNESS: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS; case KEY_GESTURE_TYPE_LAUNCH_APPLICATION_BY_PACKAGE_NAME: case KEY_GESTURE_TYPE_LAUNCH_APPLICATION: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME; case KEY_GESTURE_TYPE_DESKTOP_MODE: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__DESKTOP_MODE; case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MULTI_WINDOW_NAVIGATION; default: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED; return LOG_EVENT_UNSPECIFIED; } } /** * Find Log event type corresponding to app launch data. * Returns {@code LOG_EVENT_UNSPECIFIED} if no matching event found */ private static int getLogEventFromLaunchAppData(@Nullable AppLaunchData data) { if (data == null) { return LOG_EVENT_UNSPECIFIED; } if (data instanceof AppLaunchData.CategoryData) { return getLogEventFromSelectorCategory( ((AppLaunchData.CategoryData) data).getCategory()); } else if (data instanceof AppLaunchData.RoleData) { return getLogEventFromRole(((AppLaunchData.RoleData) data).getRole()); } else if (data instanceof AppLaunchData.ComponentData) { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME; } else { throw new IllegalArgumentException("AppLaunchData type is invalid!"); } } private static int getLogEventFromSelectorCategory(@NonNull String category) { switch (category) { case Intent.CATEGORY_APP_BROWSER: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER; case Intent.CATEGORY_APP_EMAIL: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_EMAIL; case Intent.CATEGORY_APP_CONTACTS: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CONTACTS; case Intent.CATEGORY_APP_CALENDAR: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALENDAR; case Intent.CATEGORY_APP_CALCULATOR: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALCULATOR; case Intent.CATEGORY_APP_MUSIC: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MUSIC; case Intent.CATEGORY_APP_MAPS: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MAPS; case Intent.CATEGORY_APP_MESSAGING: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING; case Intent.CATEGORY_APP_GALLERY: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_GALLERY; case Intent.CATEGORY_APP_FILES: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FILES; case Intent.CATEGORY_APP_WEATHER: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER; case Intent.CATEGORY_APP_FITNESS: return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS; default: return LOG_EVENT_UNSPECIFIED; } } /** * Find Log event corresponding to the provide system role name. * Returns {@code LOG_EVENT_UNSPECIFIED} if no matching event found. */ private static int getLogEventFromRole(@NonNull String role) { if (RoleManager.ROLE_BROWSER.equals(role)) { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER; } else if (RoleManager.ROLE_SMS.equals(role)) { return FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING; } else { return LOG_EVENT_UNSPECIFIED; } } Loading Loading @@ -577,8 +709,8 @@ public final class KeyGestureEvent { 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_LAUNCH_APPLICATION: return "KEY_GESTURE_TYPE_LAUNCH_APPLICATION"; case KEY_GESTURE_TYPE_DESKTOP_MODE: return "KEY_GESTURE_TYPE_DESKTOP_MODE"; case KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION: Loading
services/core/java/com/android/server/input/InputManagerInternal.java +7 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,13 @@ public abstract class InputManagerInternal { */ public abstract void notifyInputMethodConnectionActive(boolean connectionIsActive); /** * Notify user id changes to input. * * TODO(b/362473586): Cleanup after input shifts to Lifecycle with user change callbacks */ public abstract void setCurrentUser(@UserIdInt int newUserId); /** Callback interface for notifications relating to the lid switch. */ public interface LidSwitchCallback { /** Loading
services/core/java/com/android/server/input/InputManagerService.java +15 −0 Original line number Diff line number Diff line Loading @@ -175,6 +175,7 @@ public class InputManagerService extends IInputManager.Stub 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_CURRENT_USER_CHANGED = 4; private static final int DEFAULT_VIBRATION_MAGNITUDE = 192; private static final AdditionalDisplayInputProperties Loading @@ -184,6 +185,8 @@ public class InputManagerService extends IInputManager.Stub private final Context mContext; private final InputManagerHandler mHandler; @UserIdInt private int mCurrentUserId = UserHandle.USER_SYSTEM; private DisplayManagerInternal mDisplayManagerInternal; private WindowManagerInternal mWindowManagerInternal; Loading Loading @@ -2982,6 +2985,10 @@ public class InputManagerService extends IInputManager.Stub mKeyGestureController.unregisterKeyGestureHandler(handler, Binder.getCallingPid()); } private void handleCurrentUserChanged(@UserIdInt int userId) { mCurrentUserId = userId; } /** * Callback interface implemented by the Window Manager. */ Loading Loading @@ -3150,6 +3157,9 @@ public class InputManagerService extends IInputManager.Stub boolean inTabletMode = (boolean) args.arg1; deliverTabletModeChanged(whenNanos, inTabletMode); break; case MSG_CURRENT_USER_CHANGED: handleCurrentUserChanged((int) msg.obj); break; } } } Loading Loading @@ -3512,6 +3522,11 @@ public class InputManagerService extends IInputManager.Stub InputManagerService.this.setAccessibilityPointerIconScaleFactor(displayId, scaleFactor); } @Override public void setCurrentUser(@UserIdInt int newUserId) { mHandler.obtainMessage(MSG_CURRENT_USER_CHANGED, newUserId).sendToTarget(); } @Override public boolean setKernelWakeEnabled(int deviceId, boolean enabled) { return mNative.setKernelWakeEnabled(deviceId, enabled); Loading