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

Commit 7591b30c authored by helen cheuk's avatar helen cheuk
Browse files

[Custom Key Glyph] Return all the maps in keyboard glyph maps xml

This CL fixes below issues
1. loadGlyphMapDataList only returns the first map, it should return all
   maps
2. add new API getDrawableForModifierState for modifier state like KeyEvent.META_META_ON

Bug: 375701353
Test: KeyboardGlyphManagerTests
Flag: com.android.hardware.input.keyboard_glyph_map
Change-Id: I5753ed2769f8039b3cbb9935f73110cdfb4f5e2c
parent ec018922
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -158,6 +158,15 @@ public final class KeyGlyphMap implements Parcelable {
        return getDrawable(context, mModifierGlyphs.get(modifier, 0));
    }

    /**
     * Provides the drawable resource for the glyph for a modifier state (e.g. META_META_ON).
     * Returns null if not available.
     */
    @Nullable
    public Drawable getDrawableForModifierState(Context context, int modifierState) {
        return getDrawable(context, mModifierGlyphs.get(modifierState, 0));
    }

    @Nullable
    private Drawable getDrawable(Context context, @DrawableRes int drawableRes) {
        PackageManager pm = context.getPackageManager();
+8 −6
Original line number Diff line number Diff line
@@ -149,17 +149,17 @@ public final class KeyboardGlyphManager implements InputManager.InputDeviceListe
                continue;
            }
            final ActivityInfo activityInfo = resolveInfo.activityInfo;
            KeyGlyphMapData data = getKeyboardGlyphMapsInPackage(pm, activityInfo);
            if (data == null) {
            List<KeyGlyphMapData> data = getKeyboardGlyphMapsInPackage(pm, activityInfo);
            if (data == null || data.isEmpty()) {
                continue;
            }
            glyphMaps.add(data);
            glyphMaps.addAll(data);
        }
        return glyphMaps;
    }

    @Nullable
    private KeyGlyphMapData getKeyboardGlyphMapsInPackage(PackageManager pm,
    private List<KeyGlyphMapData> getKeyboardGlyphMapsInPackage(PackageManager pm,
            @NonNull ActivityInfo receiver) {
        Bundle metaData = receiver.metaData;
        if (metaData == null) {
@@ -175,6 +175,7 @@ public final class KeyboardGlyphManager implements InputManager.InputDeviceListe

        try {
            Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
            List<KeyGlyphMapData> glyphMaps = new ArrayList<>();
            try (XmlResourceParser parser = resources.getXml(configResId)) {
                XmlUtils.beginDocument(parser, TAG_KEYBOARD_GLYPH_MAPS);

@@ -193,13 +194,14 @@ public final class KeyboardGlyphManager implements InputManager.InputDeviceListe
                        int vendor = a.getInt(R.styleable.KeyboardGlyphMap_vendorId, -1);
                        int product = a.getInt(R.styleable.KeyboardGlyphMap_productId, -1);
                        if (glyphMapRes != 0 && vendor != -1 && product != -1) {
                            return new KeyGlyphMapData(receiver.packageName, receiver.name,
                                    glyphMapRes, vendor, product);
                            glyphMaps.add(new KeyGlyphMapData(receiver.packageName, receiver.name,
                                    glyphMapRes, vendor, product));
                        }
                    } finally {
                        a.recycle();
                    }
                }
                return glyphMaps;
            }
        } catch (Exception ex) {
            Slog.w(TAG, "Could not parse keyboard glyph map resource from receiver "
+4 −0
Original line number Diff line number Diff line
@@ -19,4 +19,8 @@
        androidprv:glyphMap="@xml/test_glyph_map"
        androidprv:vendorId="0x1234"
        androidprv:productId="0x3456" />
    <keyboard-glyph-map
        androidprv:glyphMap="@xml/test_glyph_map2"
        androidprv:vendorId="0x1235"
        androidprv:productId="0x3457" />
</keyboard-glyph-maps>
 No newline at end of file
+33 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ 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.
  -->
<keyboard-glyph-map xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
    <key-glyph
        androidprv:keycode="KEYCODE_BACK"
        androidprv:glyphDrawable="@drawable/test_key_drawable" />
    <modifier-glyph
        androidprv:modifier="META"
        androidprv:glyphDrawable="@drawable/test_modifier_drawable" />
    <function-row-key androidprv:keycode="KEYCODE_EMOJI_PICKER" />
    <hardware-defined-shortcut
        androidprv:keycode="KEYCODE_1"
        androidprv:modifierState="FUNCTION"
        androidprv:outKeycode="KEYCODE_BACK" />
    <hardware-defined-shortcut
        androidprv:keycode="KEYCODE_2"
        androidprv:modifierState="FUNCTION|META"
        androidprv:outKeycode="KEYCODE_HOME" />
</keyboard-glyph-map>
 No newline at end of file
+12 −1
Original line number Diff line number Diff line
@@ -59,6 +59,9 @@ class KeyboardGlyphManagerTests {
        const val DEVICE_ID = 1
        const val VENDOR_ID = 0x1234
        const val PRODUCT_ID = 0x3456
        const val DEVICE_ID2 = 2
        const val VENDOR_ID2 = 0x1235
        const val PRODUCT_ID2 = 0x3457
        const val PACKAGE_NAME = "KeyboardLayoutManagerTests"
        const val RECEIVER_NAME = "DummyReceiver"
    }
@@ -96,8 +99,11 @@ class KeyboardGlyphManagerTests {
            .thenReturn(inputManager)

        keyboardDevice = createKeyboard(DEVICE_ID, VENDOR_ID, PRODUCT_ID, 0, "", "")
        Mockito.`when`(inputManagerRule.mock.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
        Mockito.`when`(inputManagerRule.mock.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID, DEVICE_ID2))
        Mockito.`when`(inputManagerRule.mock.getInputDevice(DEVICE_ID)).thenReturn(keyboardDevice)

        val keyboardDevice2 = createKeyboard(DEVICE_ID2, VENDOR_ID2, PRODUCT_ID2, 0, "", "")
        Mockito.`when`(inputManagerRule.mock.getInputDevice(DEVICE_ID2)).thenReturn(keyboardDevice2)
    }

    private fun setupBroadcastReceiver() {
@@ -143,6 +149,10 @@ class KeyboardGlyphManagerTests {
            "Glyph map for test keyboard(deviceId=$DEVICE_ID) must exist",
            keyboardGlyphManager.getKeyGlyphMap(DEVICE_ID)
        )
        assertNotNull(
            "Glyph map for test keyboard(deviceId=$DEVICE_ID2) must exist",
            keyboardGlyphManager.getKeyGlyphMap(DEVICE_ID2)
        )
        assertNull(
            "Glyph map for non-existing keyboard must be null",
            keyboardGlyphManager.getKeyGlyphMap(-2)
@@ -158,6 +168,7 @@ class KeyboardGlyphManagerTests {

        assertNotNull(glyphMap.getDrawableForModifier(context, KeyEvent.KEYCODE_META_LEFT))
        assertNotNull(glyphMap.getDrawableForModifier(context, KeyEvent.KEYCODE_META_RIGHT))
        assertNotNull(glyphMap.getDrawableForModifierState(context, KeyEvent.META_META_ON))

        val functionRowKeys = glyphMap.functionRowKeys
        assertEquals(1, functionRowKeys.size)