summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-12-13 15:40:18 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-12-13 15:40:18 -0800
commitcaa8e69a65e15ce2d9e52b18c7caa547eb9a2f48 (patch)
tree3c762b6556947bbb015713ff6a6ef401b83e0343
parent19636dc4217078a3bfd4b3909b5ac05f8a9aca8f (diff)
parent33b8ee509f36a0168c8ce5a9091b57ab936f4c13 (diff)
downloadbase-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.java23
-rw-r--r--core/java/android/view/textservice/SpellCheckerSession.java187
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));
+ }
+ }
}
}