Skip to content

Commit 71e14da

Browse files
author
Dianne Hackborn
committed
Fix issue #5445666: bunch of com.android.server.TextServicesManagerService crashes
Only unbind once. Also protection from removing a SpellCheckerBindGroup from mSpellCheckerBindGroups if it is no longer the current entry there. Change-Id: Ic585295dfae77eae101a611afbf116bc681290ad
1 parent 541f6cf commit 71e14da

File tree

1 file changed

+78
-5
lines changed

1 file changed

+78
-5
lines changed

services/java/com/android/server/TextServicesManagerService.java

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,13 @@
4343
import android.view.textservice.SpellCheckerInfo;
4444
import android.view.textservice.SpellCheckerSubtype;
4545

46+
import java.io.FileDescriptor;
4647
import java.io.IOException;
48+
import java.io.PrintWriter;
4749
import java.util.ArrayList;
4850
import java.util.HashMap;
4951
import java.util.List;
52+
import java.util.Map;
5053

5154
public class TextServicesManagerService extends ITextServicesManager.Stub {
5255
private static final String TAG = TextServicesManagerService.class.getSimpleName();
@@ -480,6 +483,66 @@ private boolean isSpellCheckerEnabledLocked() {
480483
}
481484
}
482485

486+
@Override
487+
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
488+
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
489+
!= PackageManager.PERMISSION_GRANTED) {
490+
491+
pw.println("Permission Denial: can't dump TextServicesManagerService from from pid="
492+
+ Binder.getCallingPid()
493+
+ ", uid=" + Binder.getCallingUid());
494+
return;
495+
}
496+
497+
synchronized(mSpellCheckerMap) {
498+
pw.println("Current Text Services Manager state:");
499+
pw.println(" Spell Checker Map:");
500+
for (Map.Entry<String, SpellCheckerInfo> ent : mSpellCheckerMap.entrySet()) {
501+
pw.print(" "); pw.print(ent.getKey()); pw.println(":");
502+
SpellCheckerInfo info = ent.getValue();
503+
pw.print(" "); pw.print("id="); pw.println(info.getId());
504+
pw.print(" "); pw.print("comp=");
505+
pw.println(info.getComponent().toShortString());
506+
int NS = info.getSubtypeCount();
507+
for (int i=0; i<NS; i++) {
508+
SpellCheckerSubtype st = info.getSubtypeAt(i);
509+
pw.print(" "); pw.print("Subtype #"); pw.print(i); pw.println(":");
510+
pw.print(" "); pw.print("locale="); pw.println(st.getLocale());
511+
pw.print(" "); pw.print("extraValue=");
512+
pw.println(st.getExtraValue());
513+
}
514+
}
515+
pw.println("");
516+
pw.println(" Spell Checker Bind Groups:");
517+
for (Map.Entry<String, SpellCheckerBindGroup> ent
518+
: mSpellCheckerBindGroups.entrySet()) {
519+
SpellCheckerBindGroup grp = ent.getValue();
520+
pw.print(" "); pw.print(ent.getKey()); pw.print(" ");
521+
pw.print(grp); pw.println(":");
522+
pw.print(" "); pw.print("mInternalConnection=");
523+
pw.println(grp.mInternalConnection);
524+
pw.print(" "); pw.print("mSpellChecker=");
525+
pw.println(grp.mSpellChecker);
526+
pw.print(" "); pw.print("mBound="); pw.print(grp.mBound);
527+
pw.print(" mConnected="); pw.println(grp.mConnected);
528+
int NL = grp.mListeners.size();
529+
for (int i=0; i<NL; i++) {
530+
InternalDeathRecipient listener = grp.mListeners.get(i);
531+
pw.print(" "); pw.print("Listener #"); pw.print(i); pw.println(":");
532+
pw.print(" "); pw.print("mTsListener=");
533+
pw.println(listener.mTsListener);
534+
pw.print(" "); pw.print("mScListener=");
535+
pw.println(listener.mScListener);
536+
pw.print(" "); pw.print("mGroup=");
537+
pw.println(listener.mGroup);
538+
pw.print(" "); pw.print("mScLocale=");
539+
pw.print(listener.mScLocale);
540+
pw.print(" mUid="); pw.println(listener.mUid);
541+
}
542+
}
543+
}
544+
}
545+
483546
// SpellCheckerBindGroup contains active text service session listeners.
484547
// If there are no listeners anymore, the SpellCheckerBindGroup instance will be removed from
485548
// mSpellCheckerBindGroups
@@ -488,13 +551,15 @@ private class SpellCheckerBindGroup {
488551
private final InternalServiceConnection mInternalConnection;
489552
private final ArrayList<InternalDeathRecipient> mListeners =
490553
new ArrayList<InternalDeathRecipient>();
554+
public boolean mBound;
491555
public ISpellCheckerService mSpellChecker;
492556
public boolean mConnected;
493557

494558
public SpellCheckerBindGroup(InternalServiceConnection connection,
495559
ITextServicesSessionListener listener, String locale,
496560
ISpellCheckerSessionListener scListener, int uid, Bundle bundle) {
497561
mInternalConnection = connection;
562+
mBound = true;
498563
mConnected = false;
499564
addListener(listener, locale, scListener, uid, bundle);
500565
}
@@ -580,15 +645,18 @@ private void cleanLocked() {
580645
if (DBG) {
581646
Slog.d(TAG, "cleanLocked");
582647
}
583-
if (mListeners.isEmpty()) {
648+
// If there are no more active listeners, clean up. Only do this
649+
// once.
650+
if (mBound && mListeners.isEmpty()) {
651+
mBound = false;
584652
final String sciId = mInternalConnection.mSciId;
585-
if (mSpellCheckerBindGroups.containsKey(sciId)) {
653+
SpellCheckerBindGroup cur = mSpellCheckerBindGroups.get(sciId);
654+
if (cur == this) {
586655
if (DBG) {
587656
Slog.d(TAG, "Remove bind group.");
588657
}
589658
mSpellCheckerBindGroups.remove(sciId);
590659
}
591-
// Unbind service when there is no active clients.
592660
mContext.unbindService(mInternalConnection);
593661
}
594662
}
@@ -623,15 +691,20 @@ public void onServiceConnected(ComponentName name, IBinder service) {
623691
}
624692
ISpellCheckerService spellChecker = ISpellCheckerService.Stub.asInterface(service);
625693
final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
626-
if (group != null) {
694+
if (this == group.mInternalConnection) {
627695
group.onServiceConnected(spellChecker);
628696
}
629697
}
630698
}
631699

632700
@Override
633701
public void onServiceDisconnected(ComponentName name) {
634-
mSpellCheckerBindGroups.remove(mSciId);
702+
synchronized(mSpellCheckerMap) {
703+
final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
704+
if (this == group.mInternalConnection) {
705+
mSpellCheckerBindGroups.remove(mSciId);
706+
}
707+
}
635708
}
636709
}
637710

0 commit comments

Comments
 (0)