diff options
author | satok <satok@google.com> | 2011-07-28 20:40:38 +0900 |
---|---|---|
committer | satok <satok@google.com> | 2011-07-29 09:57:07 +0900 |
commit | 6be6d7548fb7c29a4d46dc985318ab2adf69f95f (patch) | |
tree | 5997d25d03c50eb01ec81955ce33ea76356a7fa3 /services/java/com/android/server/TextServicesManagerService.java | |
parent | 2043b01b207aae3458da395bc6d501d76e59425c (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.java | 104 |
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) { |