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

Commit caa8e69a authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Fix issue #5756204: Crespo IME briefly appears shortened when..." into ics-mr1

parents 19636dc4 33b8ee50
Loading
Loading
Loading
Loading
+20 −3
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.view.textservice.SuggestionsInfo;
@@ -187,24 +188,40 @@ public abstract class SpellCheckerService extends Service {
        @Override
        public void onGetSuggestionsMultiple(
                TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
            int pri = Process.getThreadPriority(Process.myTid());
            try {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                mListener.onGetSuggestions(
                        mSession.onGetSuggestionsMultiple(
                                textInfos, suggestionsLimit, sequentialWords));
            } catch (RemoteException e) {
            } finally {
                Process.setThreadPriority(pri);
            }
        }

        @Override
        public void onCancel() {
            int pri = Process.getThreadPriority(Process.myTid());
            try {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                mSession.onCancel();
            } finally {
                Process.setThreadPriority(pri);
            }
        }

        @Override
        public void onClose() {
            int pri = Process.getThreadPriority(Process.myTid());
            try {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                mSession.onClose();
            } finally {
                Process.setThreadPriority(pri);
                mListener = null;
            }
        }

        public String getLocale() {
            return mLocale;
+104 −83
Original line number Diff line number Diff line
@@ -21,8 +21,11 @@ import com.android.internal.textservice.ISpellCheckerSessionListener;
import com.android.internal.textservice.ITextServicesManager;
import com.android.internal.textservice.ITextServicesSessionListener;

import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.view.textservice.SpellCheckerInfo;
@@ -205,6 +208,8 @@ public class SpellCheckerSession {

        private boolean mOpened;
        private ISpellCheckerSession mISpellCheckerSession;
        private HandlerThread mThread;
        private Handler mAsyncHandler;

        public SpellCheckerSessionListenerImpl(Handler handler) {
            mOpened = false;
@@ -216,6 +221,7 @@ public class SpellCheckerSession {
            public final TextInfo[] mTextInfos;
            public final int mSuggestionsLimit;
            public final boolean mSequentialWords;
            public ISpellCheckerSession mSession;
            public SpellCheckerParams(int what, TextInfo[] textInfos, int suggestionsLimit,
                    boolean sequentialWords) {
                mWhat = what;
@@ -225,27 +231,86 @@ public class SpellCheckerSession {
            }
        }

        private void processTask(SpellCheckerParams scp) {
        private void processTask(ISpellCheckerSession session, SpellCheckerParams scp,
                boolean async) {
            if (async || mAsyncHandler == null) {
                switch (scp.mWhat) {
                    case TASK_CANCEL:
                    processCancel();
                        if (DBG) {
                            Log.w(TAG, "Cancel spell checker tasks.");
                        }
                        try {
                            session.onCancel();
                        } catch (RemoteException e) {
                            Log.e(TAG, "Failed to cancel " + e);
                        }
                        break;
                    case TASK_GET_SUGGESTIONS_MULTIPLE:
                    processGetSuggestionsMultiple(scp);
                        if (DBG) {
                            Log.w(TAG, "Get suggestions from the spell checker.");
                        }
                        try {
                            session.onGetSuggestionsMultiple(scp.mTextInfos,
                                    scp.mSuggestionsLimit, scp.mSequentialWords);
                        } catch (RemoteException e) {
                            Log.e(TAG, "Failed to get suggestions " + e);
                        }
                        break;
                    case TASK_CLOSE:
                    processClose();
                        if (DBG) {
                            Log.w(TAG, "Close spell checker tasks.");
                        }
                        try {
                            session.onClose();
                        } catch (RemoteException e) {
                            Log.e(TAG, "Failed to close " + e);
                        }
                        break;
                }
            } else {
                // The interface is to a local object, so need to execute it
                // asynchronously.
                scp.mSession = session;
                mAsyncHandler.sendMessage(Message.obtain(mAsyncHandler, 1, scp));
            }

            if (scp.mWhat == TASK_CLOSE) {
                // If we are closing, we want to clean up our state now even
                // if it is pending as an async operation.
                synchronized (this) {
                    mISpellCheckerSession = null;
                    mHandler = null;
                    if (mThread != null) {
                        mThread.quit();
                    }
                    mThread = null;
                    mAsyncHandler = null;
                }
            }
        }

        public synchronized void onServiceConnected(ISpellCheckerSession session) {
            synchronized (this) {
                mISpellCheckerSession = session;
                if (session.asBinder() instanceof Binder && mThread == null) {
                    // If this is a local object, we need to do our own threading
                    // to make sure we handle it asynchronously.
                    mThread = new HandlerThread("SpellCheckerSession",
                            Process.THREAD_PRIORITY_BACKGROUND);
                    mThread.start();
                    mAsyncHandler = new Handler(mThread.getLooper()) {
                        @Override public void handleMessage(Message msg) {
                            SpellCheckerParams scp = (SpellCheckerParams)msg.obj;
                            processTask(scp.mSession, scp, true);
                        }
                    };
                }
                mOpened = true;
            }
            if (DBG)
                Log.d(TAG, "onServiceConnected - Success");
            while (!mPendingTasks.isEmpty()) {
                processTask(mPendingTasks.poll());
                processTask(session, mPendingTasks.poll(), false);
            }
        }

@@ -277,20 +342,15 @@ public class SpellCheckerSession {
            return mOpened && mISpellCheckerSession == null;
        }

        public boolean checkOpenConnection() {
            if (mISpellCheckerSession != null) {
                return true;
            }
            Log.e(TAG, "not connected to the spellchecker service.");
            return false;
        }

        private void processOrEnqueueTask(SpellCheckerParams scp) {
            if (DBG) {
                Log.d(TAG, "process or enqueue task: " + mISpellCheckerSession);
            }
            ISpellCheckerSession session;
            synchronized (this) {
                session = mISpellCheckerSession;
                if (session == null) {
                    SpellCheckerParams closeTask = null;
            if (mISpellCheckerSession == null) {
                    if (scp.mWhat == TASK_CANCEL) {
                        while (!mPendingTasks.isEmpty()) {
                            final SpellCheckerParams tmp = mPendingTasks.poll();
@@ -305,59 +365,20 @@ public class SpellCheckerSession {
                    if (closeTask != null) {
                        mPendingTasks.offer(closeTask);
                    }
            } else {
                processTask(scp);
            }
        }

        private void processCancel() {
            if (!checkOpenConnection()) {
                return;
            }
            if (DBG) {
                Log.w(TAG, "Cancel spell checker tasks.");
            }
            try {
                mISpellCheckerSession.onCancel();
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to cancel " + e);
            }
        }

        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;
                }
            if (DBG) {
                Log.w(TAG, "Get suggestions from the spell checker.");
            }
            try {
                mISpellCheckerSession.onGetSuggestionsMultiple(
                        scp.mTextInfos, scp.mSuggestionsLimit, scp.mSequentialWords);
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to get suggestions " + e);
            }
            processTask(session, scp, false);
        }

        @Override
        public void onGetSuggestions(SuggestionsInfo[] results) {
            mHandler.sendMessage(Message.obtain(mHandler, MSG_ON_GET_SUGGESTION_MULTIPLE, results));
            synchronized (this) {
                if (mHandler != null) {
                    mHandler.sendMessage(Message.obtain(mHandler,
                            MSG_ON_GET_SUGGESTION_MULTIPLE, results));
                }
            }
        }
    }