mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-17 07:22:45 +00:00
more exhaustive search for hinLocales, if present
This commit is contained in:
parent
67d4f53e73
commit
1dc53663f0
5 changed files with 62 additions and 68 deletions
|
@ -6,20 +6,12 @@
|
|||
|
||||
package org.dslul.openboard.inputmethod.compat
|
||||
|
||||
import android.os.Build
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
object EditorInfoCompatUtils {
|
||||
// Note that EditorInfo.IME_FLAG_FORCE_ASCII has been introduced
|
||||
// in API level 16 (Build.VERSION_CODES.JELLY_BEAN).
|
||||
private val FIELD_IME_FLAG_FORCE_ASCII = CompatUtils.getField(EditorInfo::class.java, "IME_FLAG_FORCE_ASCII")
|
||||
private val OBJ_IME_FLAG_FORCE_ASCII: Int? = CompatUtils.getFieldValue(null, null, FIELD_IME_FLAG_FORCE_ASCII) as? Int
|
||||
private val FIELD_HINT_LOCALES = CompatUtils.getField(EditorInfo::class.java, "hintLocales")
|
||||
|
||||
@JvmStatic
|
||||
fun hasFlagForceAscii(imeOptions: Int): Boolean {
|
||||
return if (OBJ_IME_FLAG_FORCE_ASCII == null) false else imeOptions and OBJ_IME_FLAG_FORCE_ASCII != 0
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun imeActionName(imeOptions: Int): String {
|
||||
|
@ -36,32 +28,16 @@ object EditorInfoCompatUtils {
|
|||
}
|
||||
}
|
||||
|
||||
fun imeOptionsName(imeOptions: Int): String {
|
||||
val action = imeActionName(imeOptions)
|
||||
val flags = StringBuilder()
|
||||
if (imeOptions and EditorInfo.IME_FLAG_NO_ENTER_ACTION != 0) {
|
||||
flags.append("flagNoEnterAction|")
|
||||
}
|
||||
if (imeOptions and EditorInfo.IME_FLAG_NAVIGATE_NEXT != 0) {
|
||||
flags.append("flagNavigateNext|")
|
||||
}
|
||||
if (imeOptions and EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS != 0) {
|
||||
flags.append("flagNavigatePrevious|")
|
||||
}
|
||||
if (hasFlagForceAscii(imeOptions)) {
|
||||
flags.append("flagForceAscii|")
|
||||
}
|
||||
return flags.toString() + action
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getPrimaryHintLocale(editorInfo: EditorInfo?): Locale? {
|
||||
if (editorInfo == null) {
|
||||
fun getHintLocales(editorInfo: EditorInfo?): List<Locale>? {
|
||||
if (editorInfo == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
return null
|
||||
}
|
||||
val localeList = CompatUtils.getFieldValue(editorInfo, null, FIELD_HINT_LOCALES) ?: return null
|
||||
return if (LocaleListCompatUtils.isEmpty(localeList)) {
|
||||
null
|
||||
} else LocaleListCompatUtils[localeList, 0]
|
||||
val localeList = editorInfo.hintLocales ?: return null
|
||||
val locales = ArrayList<Locale>(localeList.size())
|
||||
for (i in 0 until localeList.size()) {
|
||||
locales[i] = localeList.get(i)
|
||||
}
|
||||
return locales
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
* modified
|
||||
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.dslul.openboard.inputmethod.compat
|
||||
|
||||
import java.util.*
|
||||
|
||||
object LocaleListCompatUtils {
|
||||
private val CLASS_LocaleList = CompatUtils.getClass("android.os.LocaleList")
|
||||
private val METHOD_get = CompatUtils.getMethod(CLASS_LocaleList, "get", Int::class.javaPrimitiveType)
|
||||
private val METHOD_isEmpty = CompatUtils.getMethod(CLASS_LocaleList, "isEmpty")
|
||||
fun isEmpty(localeList: Any?): Boolean {
|
||||
return CompatUtils.invoke(localeList, java.lang.Boolean.FALSE, METHOD_isEmpty) as Boolean
|
||||
}
|
||||
|
||||
operator fun get(localeList: Any?, index: Int): Locale? {
|
||||
return CompatUtils.invoke(localeList, null, METHOD_get, index) as Locale
|
||||
}
|
||||
}
|
|
@ -290,8 +290,7 @@ public final class KeyboardLayoutSet {
|
|||
// TODO: Consolidate with {@link InputAttributes}.
|
||||
@SuppressWarnings("deprecation") final boolean deprecatedForceAscii = InputAttributes.inPrivateImeOptions(
|
||||
mPackageName, FORCE_ASCII, mParams.mEditorInfo);
|
||||
final boolean forceAscii = EditorInfoCompatUtils.hasFlagForceAscii(
|
||||
mParams.mEditorInfo.imeOptions)
|
||||
final boolean forceAscii = (mParams.mEditorInfo.imeOptions & EditorInfo.IME_FLAG_FORCE_ASCII) != 0
|
||||
|| deprecatedForceAscii;
|
||||
final RichInputMethodSubtype keyboardSubtype = (forceAscii && !asciiCapable)
|
||||
? RichInputMethodSubtype.getNoLanguageSubtype()
|
||||
|
|
|
@ -897,19 +897,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) {
|
||||
super.onStartInput(editorInfo, restarting);
|
||||
|
||||
// If the primary hint language does not match the current subtype language, then try
|
||||
// to switch to the primary hint language.
|
||||
// TODO: Support all the locales in EditorInfo#hintLocales.
|
||||
final Locale primaryHintLocale = EditorInfoCompatUtils.getPrimaryHintLocale(editorInfo);
|
||||
if (primaryHintLocale == null) {
|
||||
return;
|
||||
}
|
||||
final InputMethodSubtype newSubtype = mRichImm.findSubtypeByLocale(primaryHintLocale);
|
||||
if (newSubtype == null || newSubtype.equals(mRichImm.getCurrentSubtype().getRawSubtype())) {
|
||||
final List<Locale> hintLocales = EditorInfoCompatUtils.getHintLocales(editorInfo);
|
||||
if (hintLocales == null) {
|
||||
return;
|
||||
}
|
||||
// Try switching to a subtype matching the hint language.
|
||||
for (final Locale hintLocale : hintLocales) {
|
||||
final InputMethodSubtype newSubtype = mRichImm.findSubtypeByLocale(hintLocale);
|
||||
if (newSubtype == null) continue;
|
||||
if (newSubtype.equals(mRichImm.getCurrentSubtype().getRawSubtype()))
|
||||
return; // no need to switch, we already use the correct locale
|
||||
mHandler.postSwitchLanguage(newSubtype);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) {
|
||||
|
|
|
@ -18,9 +18,11 @@ import android.view.inputmethod.InputMethodSubtype;
|
|||
|
||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
||||
import org.dslul.openboard.inputmethod.compat.InputMethodSubtypeCompatUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.settings.Settings;
|
||||
import org.dslul.openboard.inputmethod.latin.settings.SubtypeSettingsKt;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.DeviceProtectedUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.LanguageOnSpacebarUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.ScriptUtils;
|
||||
import org.dslul.openboard.inputmethod.latin.utils.SubtypeLocaleUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -308,10 +310,10 @@ public class RichInputMethodManager {
|
|||
|
||||
public InputMethodSubtype findSubtypeByLocale(final Locale locale) {
|
||||
// Find the best subtype based on a straightforward matching algorithm.
|
||||
// TODO: Use LocaleList#getFirstMatch() instead.
|
||||
final List<InputMethodSubtype> subtypes =
|
||||
getMyEnabledInputMethodSubtypeList(true /* allowsImplicitlySelectedSubtypes */);
|
||||
final int count = subtypes.size();
|
||||
// search for exact match
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final Locale subtypeLocale = InputMethodSubtypeCompatUtils.getLocaleObject(subtype);
|
||||
|
@ -319,6 +321,7 @@ public class RichInputMethodManager {
|
|||
return subtype;
|
||||
}
|
||||
}
|
||||
// search for language + country + variant match
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final Locale subtypeLocale = InputMethodSubtypeCompatUtils.getLocaleObject(subtype);
|
||||
|
@ -328,6 +331,7 @@ public class RichInputMethodManager {
|
|||
return subtype;
|
||||
}
|
||||
}
|
||||
// search for language + country match
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final Locale subtypeLocale = InputMethodSubtypeCompatUtils.getLocaleObject(subtype);
|
||||
|
@ -336,6 +340,19 @@ public class RichInputMethodManager {
|
|||
return subtype;
|
||||
}
|
||||
}
|
||||
// search for secondary locale match
|
||||
final SharedPreferences prefs = DeviceProtectedUtils.getSharedPreferences(mContext);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final String subtypeLocale = subtype.getLocale();
|
||||
final List<Locale> secondaryLocales = Settings.getSecondaryLocales(prefs, subtypeLocale);
|
||||
for (final Locale secondaryLocale : secondaryLocales) {
|
||||
if (secondaryLocale.equals(locale)) {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
}
|
||||
// search for language match
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final Locale subtypeLocale = InputMethodSubtypeCompatUtils.getLocaleObject(subtype);
|
||||
|
@ -343,6 +360,30 @@ public class RichInputMethodManager {
|
|||
return subtype;
|
||||
}
|
||||
}
|
||||
// search for secondary language match
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final String subtypeLocale = subtype.getLocale();
|
||||
final List<Locale> secondaryLocales = Settings.getSecondaryLocales(prefs, subtypeLocale);
|
||||
for (final Locale secondaryLocale : secondaryLocales) {
|
||||
if (secondaryLocale.getLanguage().equals(locale.getLanguage())) {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// extra: if current script is not compatible to current subtype, search for compatible script
|
||||
// this is acceptable only because this function is only used for switching to a certain locale using EditorInfo.hintLocales
|
||||
final int script = ScriptUtils.getScriptFromSpellCheckerLocale(locale);
|
||||
if (script != ScriptUtils.getScriptFromSpellCheckerLocale(getCurrentSubtypeLocale())) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
final InputMethodSubtype subtype = subtypes.get(i);
|
||||
final Locale subtypeLocale = InputMethodSubtypeCompatUtils.getLocaleObject(subtype);
|
||||
if (ScriptUtils.getScriptFromSpellCheckerLocale(subtypeLocale) == script) {
|
||||
return subtype;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue