summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/TextServicesManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/TextServicesManagerService.java')
-rw-r--r--services/java/com/android/server/TextServicesManagerService.java120
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);
}