diff options
Diffstat (limited to 'services/java/com/android/server/TextServicesManagerService.java')
-rw-r--r-- | services/java/com/android/server/TextServicesManagerService.java | 120 |
1 files changed, 101 insertions, 19 deletions
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java index 18ddabd..f6c369e 100644 --- a/services/java/com/android/server/TextServicesManagerService.java +++ b/services/java/com/android/server/TextServicesManagerService.java @@ -131,6 +131,11 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { if (DBG) Slog.d(TAG, "Add: " + compName); try { final SpellCheckerInfo sci = new SpellCheckerInfo(context, ri); + if (sci.getSubtypeCount() <= 0) { + Slog.w(TAG, "Skipping text service " + compName + + ": it does not contain subtypes."); + continue; + } list.add(sci); map.put(sci.getId(), sci); } catch (XmlPullParserException e) { @@ -173,7 +178,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { @Override public SpellCheckerInfo getCurrentSpellChecker(String locale) { synchronized (mSpellCheckerMap) { - String curSpellCheckerId = + final String curSpellCheckerId = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.SELECTED_SPELL_CHECKER); if (DBG) { @@ -186,9 +191,11 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { } } + // TODO: Respect allowImplicitlySelectedSubtype // TODO: Save SpellCheckerSubtype by supported languages. @Override - public SpellCheckerSubtype getCurrentSpellCheckerSubtype(String locale) { + public SpellCheckerSubtype getCurrentSpellCheckerSubtype( + String locale, boolean allowImplicitlySelectedSubtype) { synchronized (mSpellCheckerMap) { final String subtypeHashCodeStr = Settings.Secure.getString(mContext.getContentResolver(), @@ -197,21 +204,46 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { Slog.w(TAG, "getCurrentSpellChecker: " + subtypeHashCodeStr); } final SpellCheckerInfo sci = getCurrentSpellChecker(null); - if (sci.getSubtypeCount() == 0) { + if (sci == null || sci.getSubtypeCount() == 0) { + if (DBG) { + Slog.w(TAG, "Subtype not found."); + } return null; } - if (TextUtils.isEmpty(subtypeHashCodeStr)) { - // Return the first Subtype if there is no settings for the current subtype. - return sci.getSubtypeAt(0); + final int hashCode; + if (!TextUtils.isEmpty(subtypeHashCodeStr)) { + hashCode = Integer.valueOf(subtypeHashCodeStr); + } else { + hashCode = 0; } - final int hashCode = Integer.valueOf(subtypeHashCodeStr); + if (hashCode == 0 && !allowImplicitlySelectedSubtype) { + return null; + } + final String systemLocale = + mContext.getResources().getConfiguration().locale.toString(); + SpellCheckerSubtype candidate = null; for (int i = 0; i < sci.getSubtypeCount(); ++i) { final SpellCheckerSubtype scs = sci.getSubtypeAt(i); - if (scs.hashCode() == hashCode) { + if (hashCode == 0) { + if (systemLocale.equals(locale)) { + return scs; + } else if (candidate == null) { + final String scsLocale = scs.getLocale(); + if (systemLocale.length() >= 2 + && scsLocale.length() >= 2 + && systemLocale.substring(0, 2).equals( + scsLocale.substring(0, 2))) { + candidate = scs; + } + } + } else if (scs.hashCode() == hashCode) { + if (DBG) { + Slog.w(TAG, "Return subtype " + scs.hashCode()); + } return scs; } } - return sci.getSubtypeAt(0); + return candidate; } } @@ -283,6 +315,13 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { return; } + @Override + public boolean isSpellCheckerEnabled() { + synchronized(mSpellCheckerMap) { + return isSpellCheckerEnabledLocked(); + } + } + private void startSpellCheckerServiceInnerLocked(SpellCheckerInfo info, String locale, ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener, int uid, Bundle bundle) { @@ -354,7 +393,21 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { "Requires permission " + android.Manifest.permission.WRITE_SECURE_SETTINGS); } - setCurrentSpellCheckerLocked(hashCode); + setCurrentSpellCheckerSubtypeLocked(hashCode); + } + } + + @Override + public void setSpellCheckerEnabled(boolean enabled) { + synchronized(mSpellCheckerMap) { + if (mContext.checkCallingOrSelfPermission( + android.Manifest.permission.WRITE_SECURE_SETTINGS) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException( + "Requires permission " + + android.Manifest.permission.WRITE_SECURE_SETTINGS); + } + setSpellCheckerEnabledLocked(enabled); } } @@ -363,35 +416,64 @@ public class TextServicesManagerService extends ITextServicesManager.Stub { Slog.w(TAG, "setCurrentSpellChecker: " + sciId); } if (TextUtils.isEmpty(sciId) || !mSpellCheckerMap.containsKey(sciId)) return; + final SpellCheckerInfo currentSci = getCurrentSpellChecker(null); + if (currentSci != null && currentSci.getId().equals(sciId)) { + // Do nothing if the current spell checker is same as new spell checker. + return; + } final long ident = Binder.clearCallingIdentity(); try { Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.SELECTED_SPELL_CHECKER, sciId); + setCurrentSpellCheckerSubtypeLocked(0); } finally { Binder.restoreCallingIdentity(ident); } } - private void setCurrentSpellCheckerLocked(int hashCode) { + private void setCurrentSpellCheckerSubtypeLocked(int hashCode) { if (DBG) { Slog.w(TAG, "setCurrentSpellCheckerSubtype: " + hashCode); } final SpellCheckerInfo sci = getCurrentSpellChecker(null); - if (sci == null) return; - boolean found = false; - for (int i = 0; i < sci.getSubtypeCount(); ++i) { + int tempHashCode = 0; + for (int i = 0; sci != null && i < sci.getSubtypeCount(); ++i) { if(sci.getSubtypeAt(i).hashCode() == hashCode) { - found = true; + tempHashCode = hashCode; break; } } - if (!found) { - return; - } final long ident = Binder.clearCallingIdentity(); try { Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, String.valueOf(hashCode)); + Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE, String.valueOf(tempHashCode)); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + private void setSpellCheckerEnabledLocked(boolean enabled) { + if (DBG) { + Slog.w(TAG, "setSpellCheckerEnabled: " + enabled); + } + final long ident = Binder.clearCallingIdentity(); + try { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.SPELL_CHECKER_ENABLED, enabled ? 1 : 0); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + private boolean isSpellCheckerEnabledLocked() { + final long ident = Binder.clearCallingIdentity(); + try { + final boolean retval = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.SPELL_CHECKER_ENABLED, 1) == 1; + if (DBG) { + Slog.w(TAG, "getSpellCheckerEnabled: " + retval); + } + return retval; } finally { Binder.restoreCallingIdentity(ident); } |