Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e36657e5 authored by satok's avatar satok Committed by Android (Google) Code Review
Browse files

Merge "Do not merge. Fix a memory leak of a Binder in SpellCheckerService" into ics-mr0

parents d4b22ab4 e30983e7
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -145,6 +145,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
         */
@@ -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;
        }
+29 −1
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -25,4 +25,5 @@ oneway interface ISpellCheckerSession {
    void onGetSuggestionsMultiple(
            in TextInfo[] textInfos, int suggestionsLimit, boolean multipleWords);
    void onCancel();
    void onClose();
}
+10 −5
Original line number Diff line number Diff line
@@ -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;
        }