Loading core/java/android/hardware/input/IInputManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.hardware.input.TouchCalibration; import android.os.CombinedVibration; import android.hardware.input.IInputSensorEventListener; import android.hardware.input.InputSensorInfo; import android.hardware.input.KeyGlyphMap; import android.hardware.lights.Light; import android.hardware.lights.LightState; import android.os.IBinder; Loading Loading @@ -236,4 +237,6 @@ interface IInputManager { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + "android.Manifest.permission.MONITOR_STICKY_MODIFIER_STATE)") void unregisterStickyModifierStateListener(IStickyModifierStateListener listener); KeyGlyphMap getKeyGlyphMap(int deviceId); } core/java/android/hardware/input/InputManager.java +46 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.hardware.input; import static com.android.input.flags.Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API; import static com.android.input.flags.Flags.FLAG_DEVICE_ASSOCIATIONS; import static com.android.hardware.input.Flags.keyboardLayoutPreviewFlag; import static com.android.hardware.input.Flags.keyboardGlyphMap; import android.Manifest; import android.annotation.FlaggedApi; Loading Loading @@ -157,6 +158,34 @@ public final class InputManager { public static final String META_DATA_KEYBOARD_LAYOUTS = "android.hardware.input.metadata.KEYBOARD_LAYOUTS"; /** * Broadcast Action: Query available keyboard glyph maps. * <p> * The input manager service locates available keyboard glyph maps * by querying broadcast receivers that are registered for this action. * An application can offer additional keyboard glyph maps to the user * by declaring a suitable broadcast receiver in its manifest. * </p> * * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_QUERY_KEYBOARD_GLYPH_MAPS = "android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS"; /** * Metadata Key: Keyboard glyph map metadata associated with * {@link #ACTION_QUERY_KEYBOARD_GLYPH_MAPS}. * <p> * Specifies the resource id of a XML resource that describes the keyboard * glyph maps that are provided by the application. * </p> * * @hide */ public static final String META_DATA_KEYBOARD_GLYPH_MAPS = "android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS"; /** * Prevent touches from being consumed by apps if these touches passed through a non-trusted * window from a different UID and are considered unsafe. Loading Loading @@ -897,6 +926,23 @@ public final class InputManager { return new KeyboardLayoutPreviewDrawable(mContext, keyLayout, width, height); } /** * Provides associated glyph map for the keyboard device (if available) * * @hide */ @Nullable public KeyGlyphMap getKeyGlyphMap(int deviceId) { if (!keyboardGlyphMap()) { return null; } try { return mIm.getKeyGlyphMap(deviceId); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } /** * Injects an input event into the event system, targeting windows owned by the provided uid. * Loading core/java/android/hardware/input/KeyGlyphMap.aidl 0 → 100644 +19 −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; parcelable KeyGlyphMap; No newline at end of file core/java/android/hardware/input/KeyGlyphMap.java 0 → 100644 +187 −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.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; import android.util.SparseIntArray; import android.view.KeyEvent; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** * This class provides access to device specific key glyphs, modifier glyphs and device specific * shortcuts and keys * * @hide */ public final class KeyGlyphMap implements Parcelable { private static final String TAG = "KeyGlyphMap"; @NonNull private final ComponentName mComponentName; @NonNull private final SparseIntArray mKeyGlyphs; @NonNull private final SparseIntArray mModifierGlyphs; @NonNull private final int[] mFunctionRowKeys; @NonNull private final Map<KeyCombination, Integer> mHardwareShortcuts; public static final @NonNull Parcelable.Creator<KeyGlyphMap> CREATOR = new Parcelable.Creator<>() { public KeyGlyphMap createFromParcel(Parcel in) { return new KeyGlyphMap(in); } public KeyGlyphMap[] newArray(int size) { return new KeyGlyphMap[size]; } }; public KeyGlyphMap(@NonNull ComponentName componentName, @NonNull SparseIntArray keyGlyphs, @NonNull SparseIntArray modifierGlyphs, @NonNull int[] functionRowKeys, @NonNull Map<KeyCombination, Integer> hardwareShortcuts) { mComponentName = componentName; mKeyGlyphs = keyGlyphs; mModifierGlyphs = modifierGlyphs; mFunctionRowKeys = functionRowKeys; mHardwareShortcuts = hardwareShortcuts; } public KeyGlyphMap(Parcel in) { mComponentName = in.readParcelable(getClass().getClassLoader(), ComponentName.class); mKeyGlyphs = in.readSparseIntArray(); mModifierGlyphs = in.readSparseIntArray(); mFunctionRowKeys = new int[in.readInt()]; in.readIntArray(mFunctionRowKeys); mHardwareShortcuts = new HashMap<>(in.readInt()); in.readMap(mHardwareShortcuts, getClass().getClassLoader(), KeyCombination.class, Integer.class); } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeParcelable(mComponentName, 0); dest.writeSparseIntArray(mKeyGlyphs); dest.writeSparseIntArray(mModifierGlyphs); dest.writeInt(mFunctionRowKeys.length); dest.writeIntArray(mFunctionRowKeys); dest.writeInt(mHardwareShortcuts.size()); dest.writeMap(mHardwareShortcuts); } @Override public int describeContents() { return 0; } /** * Defines a key combination that includes a keycode and modifier state. */ public record KeyCombination(int modifierState, int keycode) {} /** * Returns keycodes generated from the functional row defined for the keyboard. */ public int[] getFunctionRowKeys() { return mFunctionRowKeys; } /** * Returns hardware defined shortcuts that are handled in the firmware of a particular * keyboard (e.g. Fn+Backspace = Back, etc.) * * @return a map of (modifier + key) combinations to keycode mappings that are handled by the * device hardware/firmware. */ public Map<KeyCombination, Integer> getHardwareShortcuts() { return mHardwareShortcuts; } /** * Provides the drawable resource for the glyph for a keycode. * Returns null if not available. */ @Nullable public Drawable getDrawableForKeycode(Context context, int keycode) { return getDrawable(context, mKeyGlyphs.get(keycode, 0)); } /** * Provides the drawable resource for the glyph for a modifier key. * Returns null if not available. */ @Nullable public Drawable getDrawableForModifier(Context context, int modifierKeycode) { int modifier = switch (modifierKeycode) { case KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_META_RIGHT -> KeyEvent.META_META_ON; case KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_CTRL_RIGHT -> KeyEvent.META_CTRL_ON; case KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_ALT_RIGHT -> KeyEvent.META_ALT_ON; case KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SHIFT_RIGHT -> KeyEvent.META_SHIFT_ON; case KeyEvent.KEYCODE_FUNCTION -> KeyEvent.META_FUNCTION_ON; case KeyEvent.KEYCODE_SYM -> KeyEvent.META_SYM_ON; case KeyEvent.KEYCODE_CAPS_LOCK -> KeyEvent.META_CAPS_LOCK_ON; case KeyEvent.KEYCODE_NUM_LOCK -> KeyEvent.META_NUM_LOCK_ON; case KeyEvent.KEYCODE_SCROLL_LOCK -> KeyEvent.META_SCROLL_LOCK_ON; default -> 0; }; return getDrawable(context, mModifierGlyphs.get(modifier, 0)); } @Nullable private Drawable getDrawable(Context context, @DrawableRes int drawableRes) { PackageManager pm = context.getPackageManager(); try { ActivityInfo receiver = pm.getReceiverInfo(mComponentName, PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); Resources resources = pm.getResourcesForApplication(receiver.applicationInfo); return resources.getDrawable(drawableRes, null); } catch (PackageManager.NameNotFoundException ignored) { Log.e(TAG, "Package name not found for " + mComponentName); } return null; } @Override public String toString() { return "KeyGlyphMap{" + "mComponentName=" + mComponentName + ", mKeyGlyphs=" + mKeyGlyphs + ", mModifierGlyphs=" + mModifierGlyphs + ", mFunctionRowKeys=" + Arrays.toString(mFunctionRowKeys) + ", mHardwareShortcuts=" + mHardwareShortcuts + '}'; } } core/java/android/hardware/input/input_framework.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -54,3 +54,10 @@ flag { description: "Offers a setting to enable touchpad tap dragging" bug: "321978150" } flag { namespace: "input_native" name: "keyboard_glyph_map" description: "Allows system to provide keyboard specific key drawables and shortcuts via config files" bug: "345440920" } Loading
core/java/android/hardware/input/IInputManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.hardware.input.TouchCalibration; import android.os.CombinedVibration; import android.hardware.input.IInputSensorEventListener; import android.hardware.input.InputSensorInfo; import android.hardware.input.KeyGlyphMap; import android.hardware.lights.Light; import android.hardware.lights.LightState; import android.os.IBinder; Loading Loading @@ -236,4 +237,6 @@ interface IInputManager { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + "android.Manifest.permission.MONITOR_STICKY_MODIFIER_STATE)") void unregisterStickyModifierStateListener(IStickyModifierStateListener listener); KeyGlyphMap getKeyGlyphMap(int deviceId); }
core/java/android/hardware/input/InputManager.java +46 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.hardware.input; import static com.android.input.flags.Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API; import static com.android.input.flags.Flags.FLAG_DEVICE_ASSOCIATIONS; import static com.android.hardware.input.Flags.keyboardLayoutPreviewFlag; import static com.android.hardware.input.Flags.keyboardGlyphMap; import android.Manifest; import android.annotation.FlaggedApi; Loading Loading @@ -157,6 +158,34 @@ public final class InputManager { public static final String META_DATA_KEYBOARD_LAYOUTS = "android.hardware.input.metadata.KEYBOARD_LAYOUTS"; /** * Broadcast Action: Query available keyboard glyph maps. * <p> * The input manager service locates available keyboard glyph maps * by querying broadcast receivers that are registered for this action. * An application can offer additional keyboard glyph maps to the user * by declaring a suitable broadcast receiver in its manifest. * </p> * * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_QUERY_KEYBOARD_GLYPH_MAPS = "android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS"; /** * Metadata Key: Keyboard glyph map metadata associated with * {@link #ACTION_QUERY_KEYBOARD_GLYPH_MAPS}. * <p> * Specifies the resource id of a XML resource that describes the keyboard * glyph maps that are provided by the application. * </p> * * @hide */ public static final String META_DATA_KEYBOARD_GLYPH_MAPS = "android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS"; /** * Prevent touches from being consumed by apps if these touches passed through a non-trusted * window from a different UID and are considered unsafe. Loading Loading @@ -897,6 +926,23 @@ public final class InputManager { return new KeyboardLayoutPreviewDrawable(mContext, keyLayout, width, height); } /** * Provides associated glyph map for the keyboard device (if available) * * @hide */ @Nullable public KeyGlyphMap getKeyGlyphMap(int deviceId) { if (!keyboardGlyphMap()) { return null; } try { return mIm.getKeyGlyphMap(deviceId); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } /** * Injects an input event into the event system, targeting windows owned by the provided uid. * Loading
core/java/android/hardware/input/KeyGlyphMap.aidl 0 → 100644 +19 −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; parcelable KeyGlyphMap; No newline at end of file
core/java/android/hardware/input/KeyGlyphMap.java 0 → 100644 +187 −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.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; import android.util.SparseIntArray; import android.view.KeyEvent; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** * This class provides access to device specific key glyphs, modifier glyphs and device specific * shortcuts and keys * * @hide */ public final class KeyGlyphMap implements Parcelable { private static final String TAG = "KeyGlyphMap"; @NonNull private final ComponentName mComponentName; @NonNull private final SparseIntArray mKeyGlyphs; @NonNull private final SparseIntArray mModifierGlyphs; @NonNull private final int[] mFunctionRowKeys; @NonNull private final Map<KeyCombination, Integer> mHardwareShortcuts; public static final @NonNull Parcelable.Creator<KeyGlyphMap> CREATOR = new Parcelable.Creator<>() { public KeyGlyphMap createFromParcel(Parcel in) { return new KeyGlyphMap(in); } public KeyGlyphMap[] newArray(int size) { return new KeyGlyphMap[size]; } }; public KeyGlyphMap(@NonNull ComponentName componentName, @NonNull SparseIntArray keyGlyphs, @NonNull SparseIntArray modifierGlyphs, @NonNull int[] functionRowKeys, @NonNull Map<KeyCombination, Integer> hardwareShortcuts) { mComponentName = componentName; mKeyGlyphs = keyGlyphs; mModifierGlyphs = modifierGlyphs; mFunctionRowKeys = functionRowKeys; mHardwareShortcuts = hardwareShortcuts; } public KeyGlyphMap(Parcel in) { mComponentName = in.readParcelable(getClass().getClassLoader(), ComponentName.class); mKeyGlyphs = in.readSparseIntArray(); mModifierGlyphs = in.readSparseIntArray(); mFunctionRowKeys = new int[in.readInt()]; in.readIntArray(mFunctionRowKeys); mHardwareShortcuts = new HashMap<>(in.readInt()); in.readMap(mHardwareShortcuts, getClass().getClassLoader(), KeyCombination.class, Integer.class); } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeParcelable(mComponentName, 0); dest.writeSparseIntArray(mKeyGlyphs); dest.writeSparseIntArray(mModifierGlyphs); dest.writeInt(mFunctionRowKeys.length); dest.writeIntArray(mFunctionRowKeys); dest.writeInt(mHardwareShortcuts.size()); dest.writeMap(mHardwareShortcuts); } @Override public int describeContents() { return 0; } /** * Defines a key combination that includes a keycode and modifier state. */ public record KeyCombination(int modifierState, int keycode) {} /** * Returns keycodes generated from the functional row defined for the keyboard. */ public int[] getFunctionRowKeys() { return mFunctionRowKeys; } /** * Returns hardware defined shortcuts that are handled in the firmware of a particular * keyboard (e.g. Fn+Backspace = Back, etc.) * * @return a map of (modifier + key) combinations to keycode mappings that are handled by the * device hardware/firmware. */ public Map<KeyCombination, Integer> getHardwareShortcuts() { return mHardwareShortcuts; } /** * Provides the drawable resource for the glyph for a keycode. * Returns null if not available. */ @Nullable public Drawable getDrawableForKeycode(Context context, int keycode) { return getDrawable(context, mKeyGlyphs.get(keycode, 0)); } /** * Provides the drawable resource for the glyph for a modifier key. * Returns null if not available. */ @Nullable public Drawable getDrawableForModifier(Context context, int modifierKeycode) { int modifier = switch (modifierKeycode) { case KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_META_RIGHT -> KeyEvent.META_META_ON; case KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_CTRL_RIGHT -> KeyEvent.META_CTRL_ON; case KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_ALT_RIGHT -> KeyEvent.META_ALT_ON; case KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SHIFT_RIGHT -> KeyEvent.META_SHIFT_ON; case KeyEvent.KEYCODE_FUNCTION -> KeyEvent.META_FUNCTION_ON; case KeyEvent.KEYCODE_SYM -> KeyEvent.META_SYM_ON; case KeyEvent.KEYCODE_CAPS_LOCK -> KeyEvent.META_CAPS_LOCK_ON; case KeyEvent.KEYCODE_NUM_LOCK -> KeyEvent.META_NUM_LOCK_ON; case KeyEvent.KEYCODE_SCROLL_LOCK -> KeyEvent.META_SCROLL_LOCK_ON; default -> 0; }; return getDrawable(context, mModifierGlyphs.get(modifier, 0)); } @Nullable private Drawable getDrawable(Context context, @DrawableRes int drawableRes) { PackageManager pm = context.getPackageManager(); try { ActivityInfo receiver = pm.getReceiverInfo(mComponentName, PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); Resources resources = pm.getResourcesForApplication(receiver.applicationInfo); return resources.getDrawable(drawableRes, null); } catch (PackageManager.NameNotFoundException ignored) { Log.e(TAG, "Package name not found for " + mComponentName); } return null; } @Override public String toString() { return "KeyGlyphMap{" + "mComponentName=" + mComponentName + ", mKeyGlyphs=" + mKeyGlyphs + ", mModifierGlyphs=" + mModifierGlyphs + ", mFunctionRowKeys=" + Arrays.toString(mFunctionRowKeys) + ", mHardwareShortcuts=" + mHardwareShortcuts + '}'; } }
core/java/android/hardware/input/input_framework.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -54,3 +54,10 @@ flag { description: "Offers a setting to enable touchpad tap dragging" bug: "321978150" } flag { namespace: "input_native" name: "keyboard_glyph_map" description: "Allows system to provide keyboard specific key drawables and shortcuts via config files" bug: "345440920" }