Merge "API cleanup for the spell checker framework"
diff --git a/api/current.txt b/api/current.txt
index bdc695f..035da89 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -18185,13 +18185,21 @@
public abstract class SpellCheckerService extends android.app.Service {
ctor public SpellCheckerService();
- method public void cancel();
- method public abstract android.view.textservice.SuggestionsInfo getSuggestions(android.view.textservice.TextInfo, int, java.lang.String);
- method public android.view.textservice.SuggestionsInfo[] getSuggestionsMultiple(android.view.textservice.TextInfo[], java.lang.String, int, boolean);
+ method public abstract android.service.textservice.SpellCheckerService.Session createSession();
method public final android.os.IBinder onBind(android.content.Intent);
field public static final java.lang.String SERVICE_INTERFACE = "android.service.textservice.SpellCheckerService";
}
+ public abstract class SpellCheckerService.Session {
+ ctor public SpellCheckerService.Session();
+ method public android.os.Bundle getBundle();
+ method public java.lang.String getLocale();
+ method public void onCancel();
+ method public abstract void onCreate();
+ method public abstract android.view.textservice.SuggestionsInfo onGetSuggestions(android.view.textservice.TextInfo, int);
+ method public android.view.textservice.SuggestionsInfo[] onGetSuggestionsMultiple(android.view.textservice.TextInfo[], int, boolean);
+ }
+
}
package android.service.wallpaper {
@@ -24308,7 +24316,7 @@
}
public final class TextServicesManager {
- method public android.view.textservice.SpellCheckerSession newSpellCheckerSession(java.util.Locale, android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean);
+ method public android.view.textservice.SpellCheckerSession newSpellCheckerSession(android.os.Bundle, java.util.Locale, android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean);
}
}
diff --git a/core/java/android/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java
index 6f70ab8..3e2e38e 100644
--- a/core/java/android/service/textservice/SpellCheckerService.java
+++ b/core/java/android/service/textservice/SpellCheckerService.java
@@ -22,6 +22,7 @@
import android.app.Service;
import android.content.Intent;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
@@ -43,45 +44,6 @@
private final SpellCheckerServiceBinder mBinder = new SpellCheckerServiceBinder(this);
- /**
- * Get suggestions for specified text in TextInfo.
- * This function will run on the incoming IPC thread. So, this is not called on the main thread,
- * but will be called in series on another thread.
- * @param textInfo the text metadata
- * @param suggestionsLimit the number of limit of suggestions returned
- * @param locale the locale for getting suggestions
- * @return SuggestionInfo which contains suggestions for textInfo
- */
- public abstract SuggestionsInfo getSuggestions(
- TextInfo textInfo, int suggestionsLimit, String locale);
-
- /**
- * A batch process of onGetSuggestions.
- * This function will run on the incoming IPC thread. So, this is not called on the main thread,
- * but will be called in series on another thread.
- * @param textInfos an array of the text metadata
- * @param locale the locale for getting suggestions
- * @param suggestionsLimit the number of limit of suggestions returned
- * @param sequentialWords true if textInfos can be treated as sequential words.
- * @return an array of SuggestionInfo of onGetSuggestions
- */
- public SuggestionsInfo[] getSuggestionsMultiple(
- TextInfo[] textInfos, String locale, int suggestionsLimit, boolean sequentialWords) {
- final int length = textInfos.length;
- final SuggestionsInfo[] retval = new SuggestionsInfo[length];
- for (int i = 0; i < length; ++i) {
- retval[i] = getSuggestions(textInfos[i], suggestionsLimit, locale);
- retval[i].setCookieAndSequence(textInfos[i].getCookie(), textInfos[i].getSequence());
- }
- return retval;
- }
-
- /**
- * Request to abort all tasks executed in SpellChecker.
- * This function will run on the incoming IPC thread. So, this is not called on the main thread,
- * but will be called in series on another thread.
- */
- public void cancel() {}
/**
* Implement to return the implementation of the internal spell checker
@@ -95,36 +57,125 @@
return mBinder;
}
- private static class SpellCheckerSessionImpl extends ISpellCheckerSession.Stub {
- private final WeakReference<SpellCheckerService> mInternalServiceRef;
- private final String mLocale;
- private final ISpellCheckerSessionListener mListener;
+ /**
+ * Factory method to create a spell checker session impl
+ * @return SpellCheckerSessionImpl which should be overridden by a concrete implementation.
+ */
+ public abstract Session createSession();
- public SpellCheckerSessionImpl(
- SpellCheckerService service, String locale, ISpellCheckerSessionListener listener) {
- mInternalServiceRef = new WeakReference<SpellCheckerService>(service);
- mLocale = locale;
+ /**
+ * This abstract class should be overridden by a concrete implementation of a spell checker.
+ */
+ public abstract class Session {
+ private InternalISpellCheckerSession mInternalSession;
+
+ /**
+ * @hide
+ */
+ public final void setInternalISpellCheckerSession(InternalISpellCheckerSession session) {
+ mInternalSession = session;
+ }
+
+ /**
+ * This is called after the class is initialized, at which point it knows it can call
+ * getLocale() etc...
+ */
+ public abstract void onCreate();
+
+ /**
+ * Get suggestions for specified text in TextInfo.
+ * This function will run on the incoming IPC thread.
+ * So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ * @param textInfo the text metadata
+ * @param suggestionsLimit the number of limit of suggestions returned
+ * @return SuggestionInfo which contains suggestions for textInfo
+ */
+ public abstract SuggestionsInfo onGetSuggestions(TextInfo textInfo, int suggestionsLimit);
+
+ /**
+ * A batch process of onGetSuggestions.
+ * This function will run on the incoming IPC thread.
+ * So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ * @param textInfos an array of the text metadata
+ * @param suggestionsLimit the number of limit of suggestions returned
+ * @param sequentialWords true if textInfos can be treated as sequential words.
+ * @return an array of SuggestionInfo of onGetSuggestions
+ */
+ public SuggestionsInfo[] onGetSuggestionsMultiple(TextInfo[] textInfos,
+ int suggestionsLimit, boolean sequentialWords) {
+ final int length = textInfos.length;
+ final SuggestionsInfo[] retval = new SuggestionsInfo[length];
+ for (int i = 0; i < length; ++i) {
+ retval[i] = onGetSuggestions(textInfos[i], suggestionsLimit);
+ retval[i].setCookieAndSequence(
+ textInfos[i].getCookie(), textInfos[i].getSequence());
+ }
+ return retval;
+ }
+
+ /**
+ * Request to abort all tasks executed in SpellChecker.
+ * This function will run on the incoming IPC thread.
+ * So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ */
+ public void onCancel() {}
+
+ /**
+ * @return Locale for this session
+ */
+ public String getLocale() {
+ return mInternalSession.getLocale();
+ }
+
+ /**
+ * @return Bundle for this session
+ */
+ public Bundle getBundle() {
+ return mInternalSession.getBundle();
+ }
+ }
+
+ // Preventing from exposing ISpellCheckerSession.aidl, create an internal class.
+ private static class InternalISpellCheckerSession extends ISpellCheckerSession.Stub {
+ private final ISpellCheckerSessionListener mListener;
+ private final Session mSession;
+ private final String mLocale;
+ private final Bundle mBundle;
+
+ public InternalISpellCheckerSession(String locale, ISpellCheckerSessionListener listener,
+ Bundle bundle, Session session) {
mListener = listener;
+ mSession = session;
+ mLocale = locale;
+ mBundle = bundle;
+ session.setInternalISpellCheckerSession(this);
}
@Override
- public void getSuggestionsMultiple(
+ public void onGetSuggestionsMultiple(
TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
- final SpellCheckerService service = mInternalServiceRef.get();
- if (service == null) return;
try {
mListener.onGetSuggestions(
- service.getSuggestionsMultiple(textInfos, mLocale,
- suggestionsLimit, sequentialWords));
+ mSession.onGetSuggestionsMultiple(
+ textInfos, suggestionsLimit, sequentialWords));
} catch (RemoteException e) {
}
}
@Override
- public void cancel() {
- final SpellCheckerService service = mInternalServiceRef.get();
- if (service == null) return;
- service.cancel();
+ public void onCancel() {
+ mSession.onCancel();
+ }
+
+ public String getLocale() {
+ return mLocale;
+ }
+
+ public Bundle getBundle() {
+ return mBundle;
}
}
@@ -137,10 +188,14 @@
@Override
public ISpellCheckerSession getISpellCheckerSession(
- String locale, ISpellCheckerSessionListener listener) {
+ String locale, ISpellCheckerSessionListener listener, Bundle bundle) {
final SpellCheckerService service = mInternalServiceRef.get();
if (service == null) return null;
- return new SpellCheckerSessionImpl(service, locale, listener);
+ final Session session = service.createSession();
+ final InternalISpellCheckerSession internalSession =
+ new InternalISpellCheckerSession(locale, listener, bundle, session);
+ session.onCreate();
+ return internalSession;
}
}
}
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index bf07e71..b940b80 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -233,7 +233,7 @@
Log.w(TAG, "Cancel spell checker tasks.");
}
try {
- mISpellCheckerSession.cancel();
+ mISpellCheckerSession.onCancel();
} catch (RemoteException e) {
Log.e(TAG, "Failed to cancel " + e);
}
@@ -247,7 +247,7 @@
Log.w(TAG, "Get suggestions from the spell checker.");
}
try {
- mISpellCheckerSession.getSuggestionsMultiple(
+ mISpellCheckerSession.onGetSuggestionsMultiple(
scp.mTextInfos, scp.mSuggestionsLimit, scp.mSequentialWords);
} catch (RemoteException e) {
Log.e(TAG, "Failed to get suggestions " + e);
diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java
index a60eb24..d60ce4f 100644
--- a/core/java/android/view/textservice/TextServicesManager.java
+++ b/core/java/android/view/textservice/TextServicesManager.java
@@ -19,11 +19,11 @@
import com.android.internal.textservice.ITextServicesManager;
import android.content.Context;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
-import android.view.textservice.SpellCheckerSession;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
import java.util.Locale;
@@ -74,7 +74,7 @@
*/
// TODO: Add a method to get enabled spell checkers.
// TODO: Handle referToSpellCheckerLanguageSettings
- public SpellCheckerSession newSpellCheckerSession(Locale locale,
+ public SpellCheckerSession newSpellCheckerSession(Bundle bundle, Locale locale,
SpellCheckerSessionListener listener, boolean referToSpellCheckerLanguageSettings) {
if (listener == null) {
throw new NullPointerException();
@@ -94,7 +94,7 @@
try {
sService.getSpellCheckerService(sci.getId(), localeString,
session.getTextServicesSessionListener(),
- session.getSpellCheckerSessionListener());
+ session.getSpellCheckerSessionListener(), bundle);
} catch (RemoteException e) {
return null;
}
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerService.aidl b/core/java/com/android/internal/textservice/ISpellCheckerService.aidl
index ff00492..67d7b3e 100644
--- a/core/java/com/android/internal/textservice/ISpellCheckerService.aidl
+++ b/core/java/com/android/internal/textservice/ISpellCheckerService.aidl
@@ -19,11 +19,13 @@
import com.android.internal.textservice.ISpellCheckerSession;
import com.android.internal.textservice.ISpellCheckerSessionListener;
+import android.os.Bundle;
+
/**
* Public interface to the global spell checker.
* @hide
*/
interface ISpellCheckerService {
ISpellCheckerSession getISpellCheckerSession(
- String locale, ISpellCheckerSessionListener listener);
+ String locale, ISpellCheckerSessionListener listener, in Bundle bundle);
}
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
index 79e43510c0..5a00603 100644
--- a/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
+++ b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
@@ -22,7 +22,7 @@
* @hide
*/
oneway interface ISpellCheckerSession {
- void getSuggestionsMultiple(
+ void onGetSuggestionsMultiple(
in TextInfo[] textInfos, int suggestionsLimit, boolean multipleWords);
- void cancel();
+ void onCancel();
}
diff --git a/core/java/com/android/internal/textservice/ITextServicesManager.aidl b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
index 4d7dfbb..bb4b2a3 100644
--- a/core/java/com/android/internal/textservice/ITextServicesManager.aidl
+++ b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
@@ -20,6 +20,7 @@
import com.android.internal.textservice.ITextServicesSessionListener;
import android.content.ComponentName;
+import android.os.Bundle;
import android.view.textservice.SpellCheckerInfo;
/**
@@ -30,7 +31,7 @@
SpellCheckerInfo getCurrentSpellChecker(String locale);
oneway void getSpellCheckerService(String sciId, in String locale,
in ITextServicesSessionListener tsListener,
- in ISpellCheckerSessionListener scListener);
+ in ISpellCheckerSessionListener scListener, in Bundle bundle);
oneway void finishSpellCheckerService(in ISpellCheckerSessionListener listener);
oneway void setCurrentSpellChecker(String sciId);
SpellCheckerInfo[] getEnabledSpellCheckers();
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index e97df84..238b747 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -31,19 +31,17 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Binder;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.SystemClock;
import android.provider.Settings;
-import android.text.TextUtils;
import android.service.textservice.SpellCheckerService;
-import android.util.Log;
+import android.text.TextUtils;
import android.util.Slog;
import android.view.textservice.SpellCheckerInfo;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
public class TextServicesManagerService extends ITextServicesManager.Stub {
@@ -180,7 +178,8 @@
@Override
public void getSpellCheckerService(String sciId, String locale,
- ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener) {
+ ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
+ Bundle bundle) {
if (!mSystemReady) {
return;
}
@@ -199,7 +198,7 @@
if (bindGroup != null) {
final InternalDeathRecipient recipient =
mSpellCheckerBindGroups.get(sciId).addListener(
- tsListener, locale, scListener, uid);
+ tsListener, locale, scListener, uid, bundle);
if (recipient == null) {
if (DBG) {
Slog.w(TAG, "Didn't create a death recipient.");
@@ -217,7 +216,7 @@
try {
final ISpellCheckerSession session =
bindGroup.mSpellChecker.getISpellCheckerSession(
- recipient.mScLocale, recipient.mScListener);
+ recipient.mScLocale, recipient.mScListener, bundle);
if (session != null) {
tsListener.onServiceConnected(session);
return;
@@ -236,7 +235,8 @@
}
final long ident = Binder.clearCallingIdentity();
try {
- startSpellCheckerServiceInnerLocked(sci, locale, tsListener, scListener, uid);
+ startSpellCheckerServiceInnerLocked(
+ sci, locale, tsListener, scListener, uid, bundle);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -246,13 +246,13 @@
private void startSpellCheckerServiceInnerLocked(SpellCheckerInfo info, String locale,
ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
- int uid) {
+ int uid, Bundle bundle) {
if (DBG) {
Slog.w(TAG, "Start spell checker session inner locked.");
}
final String sciId = info.getId();
final InternalServiceConnection connection = new InternalServiceConnection(
- sciId, locale, scListener);
+ sciId, locale, scListener, bundle);
final Intent serviceIntent = new Intent(SpellCheckerService.SERVICE_INTERFACE);
serviceIntent.setComponent(info.getComponent());
if (DBG) {
@@ -263,7 +263,7 @@
return;
}
final SpellCheckerBindGroup group = new SpellCheckerBindGroup(
- connection, tsListener, locale, scListener, uid);
+ connection, tsListener, locale, scListener, uid, bundle);
mSpellCheckerBindGroups.put(sciId, group);
}
@@ -332,10 +332,10 @@
public SpellCheckerBindGroup(InternalServiceConnection connection,
ITextServicesSessionListener listener, String locale,
- ISpellCheckerSessionListener scListener, int uid) {
+ ISpellCheckerSessionListener scListener, int uid, Bundle bundle) {
mInternalConnection = connection;
mConnected = false;
- addListener(listener, locale, scListener, uid);
+ addListener(listener, locale, scListener, uid, bundle);
}
public void onServiceConnected(ISpellCheckerService spellChecker) {
@@ -346,7 +346,7 @@
for (InternalDeathRecipient listener : mListeners) {
try {
final ISpellCheckerSession session = spellChecker.getISpellCheckerSession(
- listener.mScLocale, listener.mScListener);
+ listener.mScLocale, listener.mScListener, listener.mBundle);
listener.mTsListener.onServiceConnected(session);
} catch (RemoteException e) {
Slog.e(TAG, "Exception in getting the spell checker session: " + e);
@@ -360,7 +360,7 @@
}
public InternalDeathRecipient addListener(ITextServicesSessionListener tsListener,
- String locale, ISpellCheckerSessionListener scListener, int uid) {
+ String locale, ISpellCheckerSessionListener scListener, int uid, Bundle bundle) {
if (DBG) {
Slog.d(TAG, "addListener: " + locale);
}
@@ -375,7 +375,7 @@
}
}
recipient = new InternalDeathRecipient(
- this, tsListener, locale, scListener, uid);
+ this, tsListener, locale, scListener, uid, bundle);
scListener.asBinder().linkToDeath(recipient, 0);
mListeners.add(recipient);
} catch(RemoteException e) {
@@ -440,11 +440,13 @@
private final ISpellCheckerSessionListener mListener;
private final String mSciId;
private final String mLocale;
+ private final Bundle mBundle;
public InternalServiceConnection(
- String id, String locale, ISpellCheckerSessionListener listener) {
+ String id, String locale, ISpellCheckerSessionListener listener, Bundle bundle) {
mSciId = id;
mLocale = locale;
mListener = listener;
+ mBundle = bundle;
}
@Override
@@ -473,14 +475,16 @@
public final String mScLocale;
private final SpellCheckerBindGroup mGroup;
public final int mUid;
+ public final Bundle mBundle;
public InternalDeathRecipient(SpellCheckerBindGroup group,
ITextServicesSessionListener tsListener, String scLocale,
- ISpellCheckerSessionListener scListener, int uid) {
+ ISpellCheckerSessionListener scListener, int uid, Bundle bundle) {
mTsListener = tsListener;
mScListener = scListener;
mScLocale = scLocale;
mGroup = group;
mUid = uid;
+ mBundle = bundle;
}
public boolean hasSpellCheckerListener(ISpellCheckerSessionListener listener) {