diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-12-13 15:40:18 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-12-13 15:40:18 -0800 |
commit | caa8e69a65e15ce2d9e52b18c7caa547eb9a2f48 (patch) | |
tree | 3c762b6556947bbb015713ff6a6ef401b83e0343 | |
parent | 19636dc4217078a3bfd4b3909b5ac05f8a9aca8f (diff) | |
parent | 33b8ee509f36a0168c8ce5a9091b57ab936f4c13 (diff) | |
download | base-caa8e69a65e15ce2d9e52b18c7caa547eb9a2f48.tar.gz |
Merge "Fix issue #5756204: Crespo IME briefly appears shortened when..." into ics-mr1
-rw-r--r-- | core/java/android/service/textservice/SpellCheckerService.java | 23 | ||||
-rw-r--r-- | core/java/android/view/textservice/SpellCheckerSession.java | 187 |
2 files changed, 124 insertions, 86 deletions
diff --git a/core/java/android/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java index 28251a6245c9..83ea8748b3f7 100644 --- a/core/java/android/service/textservice/SpellCheckerService.java +++ b/core/java/android/service/textservice/SpellCheckerService.java @@ -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,23 +188,39 @@ 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() { - mSession.onCancel(); + int pri = Process.getThreadPriority(Process.myTid()); + try { + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); + mSession.onCancel(); + } finally { + Process.setThreadPriority(pri); + } } @Override public void onClose() { - mSession.onClose(); - mListener = null; + int pri = Process.getThreadPriority(Process.myTid()); + try { + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); + mSession.onClose(); + } finally { + Process.setThreadPriority(pri); + mListener = null; + } } public String getLocale() { diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java index 489587ed36d1..ca6577f1510f 100644 --- a/core/java/android/view/textservice/SpellCheckerSession.java +++ b/core/java/android/view/textservice/SpellCheckerSession.java @@ -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) { - switch (scp.mWhat) { - case TASK_CANCEL: - processCancel(); - break; - case TASK_GET_SUGGESTIONS_MULTIPLE: - processGetSuggestionsMultiple(scp); - break; - case TASK_CLOSE: - processClose(); - break; + private void processTask(ISpellCheckerSession session, SpellCheckerParams scp, + boolean async) { + if (async || mAsyncHandler == null) { + switch (scp.mWhat) { + case TASK_CANCEL: + 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: + 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: + 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) { - mISpellCheckerSession = session; - mOpened = true; + 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,87 +342,43 @@ 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); } - SpellCheckerParams closeTask = null; - if (mISpellCheckerSession == null) { - if (scp.mWhat == TASK_CANCEL) { - while (!mPendingTasks.isEmpty()) { - final SpellCheckerParams tmp = mPendingTasks.poll(); - if (tmp.mWhat == TASK_CLOSE) { - // Only one close task should be processed, while we need to remove all - // close tasks from the queue - closeTask = tmp; + ISpellCheckerSession session; + synchronized (this) { + session = mISpellCheckerSession; + if (session == null) { + SpellCheckerParams closeTask = null; + if (scp.mWhat == TASK_CANCEL) { + while (!mPendingTasks.isEmpty()) { + final SpellCheckerParams tmp = mPendingTasks.poll(); + if (tmp.mWhat == TASK_CLOSE) { + // Only one close task should be processed, while we need to remove all + // close tasks from the queue + closeTask = tmp; + } } } + mPendingTasks.offer(scp); + if (closeTask != null) { + mPendingTasks.offer(closeTask); + } + return; } - mPendingTasks.offer(scp); - 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)); + } + } } } |