From 91c23ca03f9ffa9ac9f2644e50e51e481a423662 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 9 Jun 2016 15:01:52 -0700 Subject: [PATCH] Fix sentence capitalization of locale names. It turns out that out previous CL [1] is not sufficient to address all the requests regarding capitalization. With [1], now InputMethodSubtype#getLocaleDisplayName() returns a locale name whose capitalization is basically optimized to be used as a list item. It works well for list UI, but on a UI element that looks like a sentence text, we still need to capitalize the first character. This CL takes care of those UI elements in the Settings app. This CL also addresses a remaining TODO about locale-unaware text formatting by using about android.icu.text.ListFormatter. [1]: If105082ce703db7a86738455db7e9fb37f3c6fe8 e489baf96df2837a3a63b626d9023a4a8b322c28 Bug: 29035638 Change-Id: I59f93f0bc067cdd87c6065c972a7da3cde1128f9 --- .../InputMethodAndLanguageSettings.java | 16 +----- .../inputmethod/InputMethodAndSubtypeEnabler.java | 4 +- .../inputmethod/InputMethodAndSubtypeUtil.java | 58 ++++++++++++++++++++++ .../inputmethod/InputMethodPreference.java | 12 +---- .../inputmethod/InputMethodSubtypePreference.java | 4 +- .../inputmethod/PhysicalKeyboardFragment.java | 4 +- 6 files changed, 68 insertions(+), 30 deletions(-) diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java index 2db75a6377..dbcd9acdae 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java +++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java @@ -758,22 +758,10 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment final int inputMethodCount = (inputMethods == null ? 0 : inputMethods.size()); for (int i = 0; i < inputMethodCount; ++i) { InputMethodInfo inputMethod = inputMethods.get(i); - - StringBuilder builder = new StringBuilder(); List subtypes = inputMethodManager .getEnabledInputMethodSubtypeList(inputMethod, true); - final int subtypeCount = subtypes.size(); - for (int j = 0; j < subtypeCount; j++) { - InputMethodSubtype subtype = subtypes.get(j); - if (builder.length() > 0) { - builder.append(','); - } - CharSequence subtypeLabel = subtype.getDisplayName(context, - inputMethod.getPackageName(), inputMethod.getServiceInfo() - .applicationInfo); - builder.append(subtypeLabel); - } - String summary = builder.toString(); + String summary = InputMethodAndSubtypeUtil.getSubtypeLocaleNameListAsSentence( + subtypes, context, inputMethod); ServiceInfo serviceInfo = inputMethod.getServiceInfo(); ComponentName componentName = new ComponentName(serviceInfo.packageName, diff --git a/src/com/android/settings/inputmethod/InputMethodAndSubtypeEnabler.java b/src/com/android/settings/inputmethod/InputMethodAndSubtypeEnabler.java index 03e97ff509..a196ccff15 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndSubtypeEnabler.java +++ b/src/com/android/settings/inputmethod/InputMethodAndSubtypeEnabler.java @@ -189,8 +189,8 @@ public class InputMethodAndSubtypeEnabler extends SettingsPreferenceFragment final InputMethodSubtype subtype = imi.getSubtypeAt(index); if (subtype.overridesImplicitlyEnabledSubtype()) { if (autoSubtypeLabel == null) { - autoSubtypeLabel = subtype.getDisplayName( - context, imi.getPackageName(), imi.getServiceInfo().applicationInfo); + autoSubtypeLabel = InputMethodAndSubtypeUtil.getSubtypeLocaleNameAsSentence( + subtype, context, imi); } } else { final Preference subtypePref = new InputMethodSubtypePreference( diff --git a/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java b/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java index b79f44d7f2..3d8d573064 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java +++ b/src/com/android/settings/inputmethod/InputMethodAndSubtypeUtil.java @@ -16,8 +16,13 @@ package com.android.settings.inputmethod; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.ContentResolver; +import android.content.Context; import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.icu.text.ListFormatter; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.support.v7.preference.Preference; @@ -28,12 +33,14 @@ import android.util.Log; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodSubtype; +import com.android.internal.app.LocaleHelper; import com.android.internal.inputmethod.InputMethodUtils; import com.android.settings.SettingsPreferenceFragment; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; // TODO: Consolidate this with {@link InputMethodSettingValuesWrapper}. @@ -370,4 +377,55 @@ class InputMethodAndSubtypeUtil { prefs.edit().remove(key).apply(); } } + + @NonNull + static String getSubtypeLocaleNameAsSentence(@Nullable InputMethodSubtype subtype, + @NonNull final Context context, @NonNull final InputMethodInfo inputMethodInfo) { + if (subtype == null) { + return ""; + } + final Locale locale = getDisplayLocale(context); + final CharSequence subtypeName = subtype.getDisplayName(context, + inputMethodInfo.getPackageName(), inputMethodInfo.getServiceInfo() + .applicationInfo); + return LocaleHelper.toSentenceCase(subtypeName.toString(), locale); + } + + @NonNull + static String getSubtypeLocaleNameListAsSentence( + @NonNull final List subtypes, @NonNull final Context context, + @NonNull final InputMethodInfo inputMethodInfo) { + if (subtypes.isEmpty()) { + return ""; + } + final Locale locale = getDisplayLocale(context); + final int subtypeCount = subtypes.size(); + final CharSequence[] subtypeNames = new CharSequence[subtypeCount]; + for (int i = 0; i < subtypeCount; i++) { + subtypeNames[i] = subtypes.get(i).getDisplayName(context, + inputMethodInfo.getPackageName(), inputMethodInfo.getServiceInfo() + .applicationInfo); + } + return LocaleHelper.toSentenceCase( + ListFormatter.getInstance(locale).format(subtypeNames), locale); + } + + @NonNull + private static Locale getDisplayLocale(@Nullable final Context context) { + if (context == null) { + return Locale.getDefault(); + } + if (context.getResources() == null) { + return Locale.getDefault(); + } + final Configuration configuration = context.getResources().getConfiguration(); + if (configuration == null) { + return Locale.getDefault(); + } + final Locale configurationLocale = configuration.getLocales().get(0); + if (configurationLocale == null) { + return Locale.getDefault(); + } + return configurationLocale; + } } diff --git a/src/com/android/settings/inputmethod/InputMethodPreference.java b/src/com/android/settings/inputmethod/InputMethodPreference.java index f3737499e9..1d4fa67dda 100755 --- a/src/com/android/settings/inputmethod/InputMethodPreference.java +++ b/src/com/android/settings/inputmethod/InputMethodPreference.java @@ -39,7 +39,6 @@ import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedSwitchPreference; import java.text.Collator; -import java.util.ArrayList; import java.util.List; import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; @@ -213,17 +212,10 @@ class InputMethodPreference extends RestrictedSwitchPreference implements OnPref } private String getSummaryString() { - final Context context = getContext(); final InputMethodManager imm = getInputMethodManager(); final List subtypes = imm.getEnabledInputMethodSubtypeList(mImi, true); - final ArrayList subtypeLabels = new ArrayList<>(); - for (final InputMethodSubtype subtype : subtypes) { - final CharSequence label = subtype.getDisplayName( - context, mImi.getPackageName(), mImi.getServiceInfo().applicationInfo); - subtypeLabels.add(label); - } - // TODO: A delimiter of subtype labels should be localized. - return TextUtils.join(", ", subtypeLabels); + return InputMethodAndSubtypeUtil.getSubtypeLocaleNameListAsSentence( + subtypes, getContext(), mImi); } private void showSecurityWarnDialog(final InputMethodInfo imi) { diff --git a/src/com/android/settings/inputmethod/InputMethodSubtypePreference.java b/src/com/android/settings/inputmethod/InputMethodSubtypePreference.java index 7321b088f6..600542a6cb 100644 --- a/src/com/android/settings/inputmethod/InputMethodSubtypePreference.java +++ b/src/com/android/settings/inputmethod/InputMethodSubtypePreference.java @@ -41,8 +41,8 @@ class InputMethodSubtypePreference extends SwitchWithNoTextPreference { super(context); setPersistent(false); setKey(imi.getId() + subtype.hashCode()); - final CharSequence subtypeLabel = subtype.getDisplayName(context, - imi.getPackageName(), imi.getServiceInfo().applicationInfo); + final CharSequence subtypeLabel = + InputMethodAndSubtypeUtil.getSubtypeLocaleNameAsSentence(subtype, context, imi); setTitle(subtypeLabel); final String subtypeLocaleString = subtype.getLocale(); if (TextUtils.isEmpty(subtypeLocaleString)) { diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java index 0117a69fc6..e22d22cbe5 100644 --- a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java +++ b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java @@ -496,8 +496,8 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment @NonNull Context context, @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype imSubtype) { if (imSubtype != null) { - return imSubtype.getDisplayName( - context, imi.getPackageName(), imi.getServiceInfo().applicationInfo); + return InputMethodAndSubtypeUtil.getSubtypeLocaleNameAsSentence( + imSubtype, context, imi); } return null; } -- 2.11.0