summaryrefslogtreecommitdiff
path: root/services/java/com/android/server/TextServicesManagerService.java
diff options
context:
space:
mode:
authorsatok <satok@google.com>2011-07-28 20:40:38 +0900
committersatok <satok@google.com>2011-07-29 09:57:07 +0900
commit6be6d7548fb7c29a4d46dc985318ab2adf69f95f (patch)
tree5997d25d03c50eb01ec81955ce33ea76356a7fa3 /services/java/com/android/server/TextServicesManagerService.java
parent2043b01b207aae3458da395bc6d501d76e59425c (diff)
Handle the existing binds to spell checkers correctly.
Change-Id: I32efce9f8c09b5a829b0431e8c444fc54b03b440
Diffstat (limited to 'services/java/com/android/server/TextServicesManagerService.java')
-rw-r--r--services/java/com/android/server/TextServicesManagerService.java104
1 files changed, 84 insertions, 20 deletions
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 3e76a3a1ae4e..b2d9917ee1e8 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -30,6 +30,7 @@ import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -177,7 +178,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
if (!mSystemReady) {
return;
}
- if (info == null || tsListener == null) {
+ if (info == null || tsListener == null || scListener == null) {
Slog.e(TAG, "getSpellCheckerService: Invalid input.");
return;
}
@@ -187,24 +188,66 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
return;
}
if (mSpellCheckerBindGroups.containsKey(sciId)) {
- mSpellCheckerBindGroups.get(sciId).addListener(tsListener, locale, scListener);
- return;
+ final SpellCheckerBindGroup bindGroup = mSpellCheckerBindGroups.get(sciId);
+ if (bindGroup != null) {
+ final InternalDeathRecipient recipient =
+ mSpellCheckerBindGroups.get(sciId).addListener(
+ tsListener, locale, scListener);
+ if (recipient == null) {
+ if (DBG) {
+ Slog.w(TAG, "Didn't create a death recipient.");
+ }
+ return;
+ }
+ if (bindGroup.mSpellChecker == null & bindGroup.mConnected) {
+ Slog.e(TAG, "The state of the spell checker bind group is illegal.");
+ bindGroup.removeAll();
+ } else if (bindGroup.mSpellChecker != null) {
+ if (DBG) {
+ Slog.w(TAG, "Existing bind found. Return a spell checker session now.");
+ }
+ try {
+ final ISpellCheckerSession session =
+ bindGroup.mSpellChecker.getISpellCheckerSession(
+ recipient.mScLocale, recipient.mScListener);
+ tsListener.onServiceConnected(session);
+ return;
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception in getting spell checker session: " + e);
+ bindGroup.removeAll();
+ }
+ }
+ }
}
- final InternalServiceConnection connection = new InternalServiceConnection(
- sciId, locale, scListener);
- final Intent serviceIntent = new Intent(SpellCheckerService.SERVICE_INTERFACE);
- serviceIntent.setComponent(info.getComponent());
- if (!mContext.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)) {
- Slog.e(TAG, "Failed to get a spell checker service.");
- return;
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ startSpellCheckerServiceInnerLocked(info, locale, tsListener, scListener);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
- final SpellCheckerBindGroup group = new SpellCheckerBindGroup(
- connection, tsListener, locale, scListener);
- mSpellCheckerBindGroups.put(sciId, group);
}
return;
}
+ private void startSpellCheckerServiceInnerLocked(SpellCheckerInfo info, String locale,
+ ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener) {
+ final String sciId = info.getId();
+ final InternalServiceConnection connection = new InternalServiceConnection(
+ sciId, locale, scListener);
+ final Intent serviceIntent = new Intent(SpellCheckerService.SERVICE_INTERFACE);
+ serviceIntent.setComponent(info.getComponent());
+ if (DBG) {
+ Slog.w(TAG, "bind service: " + info.getId());
+ }
+ if (!mContext.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)) {
+ Slog.e(TAG, "Failed to get a spell checker service.");
+ return;
+ }
+ final SpellCheckerBindGroup group = new SpellCheckerBindGroup(
+ connection, tsListener, locale, scListener);
+ mSpellCheckerBindGroups.put(sciId, group);
+ }
+
@Override
public SpellCheckerInfo[] getEnabledSpellCheckers() {
if (DBG) {
@@ -242,14 +285,17 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
// If there are no listeners anymore, the SpellCheckerBindGroup instance will be removed from
// mSpellCheckerBindGroups
private class SpellCheckerBindGroup {
- final InternalServiceConnection mInternalConnection;
- final ArrayList<InternalDeathRecipient> mListeners =
+ private final InternalServiceConnection mInternalConnection;
+ private final ArrayList<InternalDeathRecipient> mListeners =
new ArrayList<InternalDeathRecipient>();
+ public ISpellCheckerService mSpellChecker;
+ public boolean mConnected;
public SpellCheckerBindGroup(InternalServiceConnection connection,
ITextServicesSessionListener listener, String locale,
ISpellCheckerSessionListener scListener) {
mInternalConnection = connection;
+ mConnected = false;
addListener(listener, locale, scListener);
}
@@ -264,26 +310,32 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
listener.mScLocale, listener.mScListener);
listener.mTsListener.onServiceConnected(session);
} catch (RemoteException e) {
+ Slog.e(TAG, "Exception in getting spell checker session: " + e);
+ removeAll();
+ return;
}
}
+ mSpellChecker = spellChecker;
+ mConnected = true;
}
}
- public void addListener(ITextServicesSessionListener tsListener, String locale,
- ISpellCheckerSessionListener scListener) {
+ public InternalDeathRecipient addListener(ITextServicesSessionListener tsListener,
+ String locale, ISpellCheckerSessionListener scListener) {
if (DBG) {
Slog.d(TAG, "addListener: " + locale);
}
+ InternalDeathRecipient recipient = null;
synchronized(mSpellCheckerMap) {
try {
final int size = mListeners.size();
for (int i = 0; i < size; ++i) {
if (mListeners.get(i).hasSpellCheckerListener(scListener)) {
// do not add the lister if the group already contains this.
- return;
+ return null;
}
}
- final InternalDeathRecipient recipient = new InternalDeathRecipient(
+ recipient = new InternalDeathRecipient(
this, tsListener, locale, scListener);
scListener.asBinder().linkToDeath(recipient, 0);
mListeners.add(new InternalDeathRecipient(
@@ -293,6 +345,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
cleanLocked();
}
+ return recipient;
}
public void removeListener(ISpellCheckerSessionListener listener) {
@@ -322,11 +375,19 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
Slog.d(TAG, "cleanLocked");
}
if (mListeners.isEmpty()) {
- mSpellCheckerBindGroups.remove(this);
+ if (mSpellCheckerBindGroups.containsKey(this)) {
+ mSpellCheckerBindGroups.remove(this);
+ }
// Unbind service when there is no active clients.
mContext.unbindService(mInternalConnection);
}
}
+
+ public void removeAll() {
+ Slog.e(TAG, "Remove the spell checker bind unexpectedly.");
+ mListeners.clear();
+ cleanLocked();
+ }
}
private class InternalServiceConnection implements ServiceConnection {
@@ -343,6 +404,9 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized(mSpellCheckerMap) {
+ if (DBG) {
+ Slog.w(TAG, "onServiceConnected: " + name);
+ }
ISpellCheckerService spellChecker = ISpellCheckerService.Stub.asInterface(service);
final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
if (group != null) {