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

Commit 1c50d4a7 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari Committed by Automerger Merge Worker
Browse files

Merge "Modify Script matching algorithm" into udc-dev am: cbb43d66

parents 74ede1ff cbb43d66
Loading
Loading
Loading
Loading
+29 −14
Original line number Diff line number Diff line
@@ -1261,28 +1261,43 @@ final class KeyboardLayoutManager implements InputManager.InputDeviceListener {

    private static boolean isLayoutCompatibleWithLanguageTag(KeyboardLayout layout,
            @NonNull String languageTag) {
        final int[] scriptsFromLanguageTag = UScript.getCode(Locale.forLanguageTag(languageTag));
        LocaleList layoutLocales = layout.getLocales();
        if (layoutLocales.isEmpty()) {
            // KCM file doesn't have an associated language tag. This can be from
            // a 3rd party app so need to include it as a potential layout.
            return true;
        }
        // Match derived Script codes
        final int[] scriptsFromLanguageTag = getScriptCodes(Locale.forLanguageTag(languageTag));
        if (scriptsFromLanguageTag.length == 0) {
            // If no scripts inferred from languageTag then allowing the layout
            return true;
        }
        LocaleList locales = layout.getLocales();
        if (locales.isEmpty()) {
            // KCM file doesn't have an associated language tag. This can be from
            // a 3rd party app so need to include it as a potential layout.
        for (int i = 0; i < layoutLocales.size(); i++) {
            final Locale locale = layoutLocales.get(i);
            int[] scripts = getScriptCodes(locale);
            if (haveCommonValue(scripts, scriptsFromLanguageTag)) {
                return true;
            }
        for (int i = 0; i < locales.size(); i++) {
            final Locale locale = locales.get(i);
        }
        return false;
    }

    private static int[] getScriptCodes(@Nullable Locale locale) {
        if (locale == null) {
                continue;
            return new int[0];
        }
            int[] scripts = UScript.getCode(locale);
            if (scripts != null && haveCommonValue(scripts, scriptsFromLanguageTag)) {
                return true;
        if (!TextUtils.isEmpty(locale.getScript())) {
            int scriptCode = UScript.getCodeFromName(locale.getScript());
            if (scriptCode != UScript.INVALID_CODE) {
                return new int[]{scriptCode};
            }
        }
        return false;
        int[] scripts = UScript.getCode(locale);
        if (scripts != null) {
            return scripts;
        }
        return new int[0];
    }

    private static boolean haveCommonValue(int[] arr1, int[] arr2) {
+8 −0
Original line number Diff line number Diff line
@@ -72,10 +72,18 @@
        android:keyboardLayout="@raw/dummy_keyboard_layout"
        android:keyboardLocale="ru-Cyrl" />

    <keyboard-layout
        android:name="keyboard_layout_english_without_script_code"
        android:label="English(No script code)"
        android:keyboardLayout="@raw/dummy_keyboard_layout"
        android:keyboardLocale="en"
        android:keyboardLayoutType="qwerty" />

    <keyboard-layout
        android:name="keyboard_layout_vendorId:1,productId:1"
        android:label="vendorId:1,productId:1"
        android:keyboardLayout="@raw/dummy_keyboard_layout"
        androidprv:vendorId="1"
        androidprv:productId="1" />

</keyboard-layouts>
+54 −23
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import android.content.pm.ServiceInfo
import android.hardware.input.IInputManager
import android.hardware.input.InputManager
import android.hardware.input.KeyboardLayout
import android.icu.lang.UScript
import android.icu.util.ULocale
import android.os.Bundle
import android.os.test.TestLooper
@@ -52,7 +51,6 @@ import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.util.Locale

private fun createKeyboard(
    deviceId: Int,
@@ -553,24 +551,17 @@ class KeyboardLayoutManagerTests {
                0,
                keyboardLayouts.size
            )

            val englishScripts = UScript.getCode(Locale.forLanguageTag("hi-Latn"))
            for (kl in keyboardLayouts) {
                var isCompatible = false
                for (i in 0 until kl.locales.size()) {
                    val locale: Locale = kl.locales.get(i) ?: continue
                    val scripts = UScript.getCode(locale)
                    if (scripts != null && areScriptsCompatible(scripts, englishScripts)) {
                        isCompatible = true
                        break
                    }
                }
                assertTrue(
                    "New UI: getKeyboardLayoutListForInputDevice API should only return " +
                            "compatible layouts but found " + kl.descriptor,
                    isCompatible
            assertTrue("New UI: getKeyboardLayoutListForInputDevice API should return a list " +
                    "containing English(US) layout for hi-Latn",
                containsLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
            )
            assertTrue("New UI: getKeyboardLayoutListForInputDevice API should return a list " +
                    "containing English(No script code) layout for hi-Latn",
                containsLayout(
                    keyboardLayouts,
                    createLayoutDescriptor("keyboard_layout_english_without_script_code")
                )
            )
            }

            // Check Layouts for "hi" which by default uses 'Deva' script.
            keyboardLayouts =
@@ -600,6 +591,46 @@ class KeyboardLayoutManagerTests {
                    1,
                keyboardLayouts.size
            )

            // Special case Japanese: UScript ignores provided script code for certain language tags
            // Should manually match provided script codes and then rely on Uscript to derive
            // script from language tags and match those.
            keyboardLayouts =
                keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
                        keyboardDevice.identifier, USER_ID, imeInfo,
                        createImeSubtypeForLanguageTag("ja-Latn-JP")
                )
            assertNotEquals(
                "New UI: getKeyboardLayoutListForInputDevice API should return the list of " +
                        "supported layouts with matching script code for ja-Latn-JP",
                0,
                keyboardLayouts.size
            )
            assertTrue("New UI: getKeyboardLayoutListForInputDevice API should return a list " +
                    "containing English(US) layout for ja-Latn-JP",
                containsLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
            )
            assertTrue("New UI: getKeyboardLayoutListForInputDevice API should return a list " +
                    "containing English(No script code) layout for ja-Latn-JP",
                containsLayout(
                    keyboardLayouts,
                    createLayoutDescriptor("keyboard_layout_english_without_script_code")
                )
            )

            // If script code not explicitly provided for Japanese should rely on Uscript to find
            // derived script code and hence no suitable layout will be found.
            keyboardLayouts =
                keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
                        keyboardDevice.identifier, USER_ID, imeInfo,
                        createImeSubtypeForLanguageTag("ja-JP")
                )
            assertEquals(
                "New UI: getKeyboardLayoutListForInputDevice API should return empty list of " +
                        "supported layouts with matching script code for ja-JP",
                0,
                keyboardLayouts.size
            )
        }
    }

@@ -779,10 +810,10 @@ class KeyboardLayoutManagerTests {
    private fun createLayoutDescriptor(keyboardName: String): String =
        "$PACKAGE_NAME/$RECEIVER_NAME/$keyboardName"

    private fun areScriptsCompatible(scriptList1: IntArray, scriptList2: IntArray): Boolean {
        for (s1 in scriptList1) {
            for (s2 in scriptList2) {
                if (s1 == s2) return true
    private fun containsLayout(layoutList: Array<KeyboardLayout>, layoutDesc: String): Boolean {
        for (kl in layoutList) {
            if (kl.descriptor.equals(layoutDesc)) {
                return true
            }
        }
        return false