Skip to content

Commit be836ee

Browse files
satok16Android (Google) Code Review
authored andcommitted
Merge "Reset the default system ime to the proper one when the system locale is changed" into jb-dev
2 parents b0dcf5e + 5b927c4 commit be836ee

File tree

1 file changed

+101
-23
lines changed

1 file changed

+101
-23
lines changed

services/java/com/android/server/InputMethodManagerService.java

Lines changed: 101 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import android.app.Notification;
4040
import android.app.NotificationManager;
4141
import android.app.PendingIntent;
42+
import android.content.BroadcastReceiver;
4243
import android.content.ComponentName;
4344
import android.content.ContentResolver;
4445
import android.content.Context;
@@ -110,6 +111,7 @@
110111
import java.util.HashMap;
111112
import java.util.HashSet;
112113
import java.util.List;
114+
import java.util.Locale;
113115
import java.util.TreeMap;
114116

115117
/**
@@ -152,6 +154,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
152154
private static final String TAG_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE =
153155
"EnabledWhenDefaultIsNotAsciiCapable";
154156
private static final String TAG_ASCII_CAPABLE = "AsciiCapable";
157+
private static final Locale ENGLISH_LOCALE = new Locale("en");
155158

156159
final Context mContext;
157160
final Resources mRes;
@@ -371,6 +374,7 @@ public String toString() {
371374
private View mSwitchingDialogTitleView;
372375
private InputMethodInfo[] mIms;
373376
private int[] mSubtypeIds;
377+
private Locale mLastSystemLocale;
374378

375379
class SettingsObserver extends ContentObserver {
376380
SettingsObserver(Handler handler) {
@@ -586,6 +590,7 @@ public void executeMessage(Message msg) {
586590
mImeSwitcherNotification.vibrate = null;
587591
Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
588592
mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
593+
mLastSystemLocale = mRes.getConfiguration().locale;
589594

590595
mShowOngoingImeSwitcherForPhones = false;
591596

@@ -612,32 +617,102 @@ public void executeMessage(Message msg) {
612617

613618
if (TextUtils.isEmpty(Settings.Secure.getString(
614619
mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD))) {
615-
InputMethodInfo defIm = null;
616-
for (InputMethodInfo imi: mMethodList) {
617-
if (defIm == null && imi.getIsDefaultResourceId() != 0) {
618-
try {
619-
Resources res = context.createPackageContext(
620-
imi.getPackageName(), 0).getResources();
621-
if (res.getBoolean(imi.getIsDefaultResourceId())) {
622-
defIm = imi;
623-
Slog.i(TAG, "Selected default: " + imi.getId());
620+
resetDefaultImeLocked(context);
621+
}
622+
623+
mSettingsObserver = new SettingsObserver(mHandler);
624+
updateFromSettingsLocked();
625+
626+
// IMMS wants to receive Intent.ACTION_LOCALE_CHANGED in order to update the current IME
627+
// according to the new system locale.
628+
final IntentFilter filter = new IntentFilter();
629+
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
630+
mContext.registerReceiver(
631+
new BroadcastReceiver() {
632+
@Override
633+
public void onReceive(Context context, Intent intent) {
634+
synchronized(mMethodMap) {
635+
checkCurrentLocaleChangedLocked();
624636
}
625-
} catch (PackageManager.NameNotFoundException ex) {
626-
} catch (Resources.NotFoundException ex) {
627637
}
628-
}
638+
}, filter);
639+
}
640+
641+
private void checkCurrentLocaleChangedLocked() {
642+
final Locale newLocale = mRes.getConfiguration().locale;
643+
if (newLocale != null && !newLocale.equals(mLastSystemLocale)) {
644+
if (DEBUG) {
645+
Slog.i(TAG, "Locale has been changed to " + newLocale);
629646
}
630-
if (defIm == null && mMethodList.size() > 0) {
631-
defIm = getMostApplicableDefaultIMELocked();
632-
Slog.i(TAG, "No default found, using " + defIm.getId());
647+
buildInputMethodListLocked(mMethodList, mMethodMap);
648+
// Reset the current ime to the proper one
649+
resetDefaultImeLocked(mContext);
650+
mLastSystemLocale = newLocale;
651+
}
652+
}
653+
654+
private void resetDefaultImeLocked(Context context) {
655+
// Do not reset the default (current) IME when it is a 3rd-party IME
656+
if (mCurMethodId != null && !isSystemIme(mMethodMap.get(mCurMethodId))) {
657+
return;
658+
}
659+
660+
InputMethodInfo defIm = null;
661+
for (InputMethodInfo imi : mMethodList) {
662+
if (defIm == null) {
663+
if (isValidSystemDefaultIme(imi, context)) {
664+
defIm = imi;
665+
Slog.i(TAG, "Selected default: " + imi.getId());
666+
}
633667
}
634-
if (defIm != null) {
635-
setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false);
668+
}
669+
if (defIm == null && mMethodList.size() > 0) {
670+
defIm = getMostApplicableDefaultIMELocked();
671+
Slog.i(TAG, "No default found, using " + defIm.getId());
672+
}
673+
if (defIm != null) {
674+
setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false);
675+
}
676+
}
677+
678+
private static boolean isValidSystemDefaultIme(InputMethodInfo imi, Context context) {
679+
if (!isSystemIme(imi)) {
680+
return false;
681+
}
682+
if (imi.getIsDefaultResourceId() != 0) {
683+
try {
684+
Resources res = context.createPackageContext(
685+
imi.getPackageName(), 0).getResources();
686+
if (res.getBoolean(imi.getIsDefaultResourceId())
687+
&& containsSubtypeOf(imi, context.getResources().getConfiguration().
688+
locale.getLanguage())) {
689+
return true;
690+
}
691+
} catch (PackageManager.NameNotFoundException ex) {
692+
} catch (Resources.NotFoundException ex) {
636693
}
637694
}
695+
if (imi.getSubtypeCount() == 0) {
696+
Slog.w(TAG, "Found no subtypes in a system IME: " + imi.getPackageName());
697+
}
698+
return false;
699+
}
638700

639-
mSettingsObserver = new SettingsObserver(mHandler);
640-
updateFromSettingsLocked();
701+
private static boolean isSystemImeThatHasEnglishSubtype(InputMethodInfo imi) {
702+
if (!isSystemIme(imi)) {
703+
return false;
704+
}
705+
return containsSubtypeOf(imi, ENGLISH_LOCALE.getLanguage());
706+
}
707+
708+
private static boolean containsSubtypeOf(InputMethodInfo imi, String language) {
709+
final int N = imi.getSubtypeCount();
710+
for (int i = 0; i < N; ++i) {
711+
if (imi.getSubtypeAt(i).getLocale().startsWith(language)) {
712+
return true;
713+
}
714+
}
715+
return false;
641716
}
642717

643718
@Override
@@ -663,6 +738,7 @@ public void systemReady(StatusBarManagerService statusBar) {
663738
mContext.getSystemService(Context.KEYGUARD_SERVICE);
664739
mNotificationManager = (NotificationManager)
665740
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
741+
mLastSystemLocale = mContext.getResources().getConfiguration().locale;
666742
mStatusBar = statusBar;
667743
statusBar.setIconVisibility("ime", false);
668744
updateImeWindowStatusLocked();
@@ -2043,7 +2119,7 @@ public boolean handleMessage(Message msg) {
20432119
return false;
20442120
}
20452121

2046-
private boolean isSystemIme(InputMethodInfo inputMethod) {
2122+
private static boolean isSystemIme(InputMethodInfo inputMethod) {
20472123
return (inputMethod.getServiceInfo().applicationInfo.flags
20482124
& ApplicationInfo.FLAG_SYSTEM) != 0;
20492125
}
@@ -2139,9 +2215,11 @@ void buildInputMethodListLocked(ArrayList<InputMethodInfo> list,
21392215
final String id = p.getId();
21402216
map.put(id, p);
21412217

2142-
// System IMEs are enabled by default, unless there's a hard keyboard
2143-
// and the system IME was explicitly disabled
2144-
if (isSystemIme(p) && (!haveHardKeyboard || disabledSysImes.indexOf(id) < 0)) {
2218+
// Valid system default IMEs and IMEs that have English subtypes are enabled
2219+
// by default, unless there's a hard keyboard and the system IME was explicitly
2220+
// disabled
2221+
if ((isValidSystemDefaultIme(p, mContext) || isSystemImeThatHasEnglishSubtype(p))
2222+
&& (!haveHardKeyboard || disabledSysImes.indexOf(id) < 0)) {
21452223
setInputMethodEnabledLocked(id, true);
21462224
}
21472225

0 commit comments

Comments
 (0)