summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/service/textservice/SpellCheckerService.java17
-rw-r--r--core/java/android/view/textservice/SpellCheckerSession.java30
-rw-r--r--core/java/com/android/internal/textservice/ISpellCheckerSession.aidl1
-rw-r--r--services/java/com/android/server/TextServicesManagerService.java15
4 files changed, 56 insertions, 7 deletions
diff --git a/core/java/android/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java
index 2ecf307..1ad851d 100644
--- a/core/java/android/service/textservice/SpellCheckerService.java
+++ b/core/java/android/service/textservice/SpellCheckerService.java
@@ -146,6 +146,15 @@ public abstract class SpellCheckerService extends Service {
public void onCancel() {}
/**
+ * @hide
+ * Request to close this session.
+ * 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 onClose() {}
+
+ /**
* @return Locale for this session
*/
public String getLocale() {
@@ -162,7 +171,7 @@ public abstract class SpellCheckerService extends Service {
// Preventing from exposing ISpellCheckerSession.aidl, create an internal class.
private static class InternalISpellCheckerSession extends ISpellCheckerSession.Stub {
- private final ISpellCheckerSessionListener mListener;
+ private ISpellCheckerSessionListener mListener;
private final Session mSession;
private final String mLocale;
private final Bundle mBundle;
@@ -192,6 +201,12 @@ public abstract class SpellCheckerService extends Service {
mSession.onCancel();
}
+ @Override
+ public void onClose() {
+ mSession.onClose();
+ mListener = null;
+ }
+
public String getLocale() {
return mLocale;
}
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 793f514..a80f4a3 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -152,6 +152,7 @@ public class SpellCheckerSession {
public void close() {
mIsUsed = false;
try {
+ mSpellCheckerSessionListenerImpl.close();
mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl);
} catch (RemoteException e) {
// do nothing
@@ -190,9 +191,10 @@ public class SpellCheckerSession {
private static class SpellCheckerSessionListenerImpl extends ISpellCheckerSessionListener.Stub {
private static final int TASK_CANCEL = 1;
private static final int TASK_GET_SUGGESTIONS_MULTIPLE = 2;
+ private static final int TASK_CLOSE = 3;
private final Queue<SpellCheckerParams> mPendingTasks =
new LinkedList<SpellCheckerParams>();
- private final Handler mHandler;
+ private Handler mHandler;
private boolean mOpened;
private ISpellCheckerSession mISpellCheckerSession;
@@ -224,6 +226,9 @@ public class SpellCheckerSession {
case TASK_GET_SUGGESTIONS_MULTIPLE:
processGetSuggestionsMultiple(scp);
break;
+ case TASK_CLOSE:
+ processClose();
+ break;
}
}
@@ -247,6 +252,13 @@ public class SpellCheckerSession {
suggestionsLimit, sequentialWords));
}
+ public void close() {
+ if (DBG) {
+ Log.w(TAG, "close");
+ }
+ processOrEnqueueTask(new SpellCheckerParams(TASK_CLOSE, null, 0, false));
+ }
+
public boolean isDisconnected() {
return mOpened && mISpellCheckerSession == null;
}
@@ -284,6 +296,22 @@ public class SpellCheckerSession {
}
}
+ private void processClose() {
+ if (!checkOpenConnection()) {
+ return;
+ }
+ if (DBG) {
+ Log.w(TAG, "Close spell checker tasks.");
+ }
+ try {
+ mISpellCheckerSession.onClose();
+ mISpellCheckerSession = null;
+ mHandler = null;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to close " + e);
+ }
+ }
+
private void processGetSuggestionsMultiple(SpellCheckerParams scp) {
if (!checkOpenConnection()) {
return;
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
index 5a00603..3c61968 100644
--- a/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
+++ b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
@@ -25,4 +25,5 @@ oneway interface ISpellCheckerSession {
void onGetSuggestionsMultiple(
in TextInfo[] textInfos, int suggestionsLimit, boolean multipleWords);
void onCancel();
+ void onClose();
}
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 1976eba..373b11c 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -334,7 +334,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
final String sciId = info.getId();
final InternalServiceConnection connection = new InternalServiceConnection(
- sciId, locale, scListener, bundle);
+ sciId, locale, bundle);
final Intent serviceIntent = new Intent(SpellCheckerService.SERVICE_INTERFACE);
serviceIntent.setComponent(info.getComponent());
if (DBG) {
@@ -635,7 +635,9 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
if (DBG) {
Slog.w(TAG, "Remove " + removeList.get(i));
}
- mListeners.remove(removeList.get(i));
+ final InternalDeathRecipient idr = removeList.get(i);
+ idr.mScListener.asBinder().unlinkToDeath(idr, 0);
+ mListeners.remove(idr);
}
cleanLocked();
}
@@ -664,6 +666,11 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
public void removeAll() {
Slog.e(TAG, "Remove the spell checker bind unexpectedly.");
synchronized(mSpellCheckerMap) {
+ final int size = mListeners.size();
+ for (int i = 0; i < size; ++i) {
+ final InternalDeathRecipient idr = mListeners.get(i);
+ idr.mScListener.asBinder().unlinkToDeath(idr, 0);
+ }
mListeners.clear();
cleanLocked();
}
@@ -671,15 +678,13 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
private class InternalServiceConnection implements ServiceConnection {
- private final ISpellCheckerSessionListener mListener;
private final String mSciId;
private final String mLocale;
private final Bundle mBundle;
public InternalServiceConnection(
- String id, String locale, ISpellCheckerSessionListener listener, Bundle bundle) {
+ String id, String locale, Bundle bundle) {
mSciId = id;
mLocale = locale;
- mListener = listener;
mBundle = bundle;
}