Loading core/java/android/service/textservice/SpellCheckerService.java +20 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading core/java/android/view/textservice/SpellCheckerSession.java +104 −83 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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); } } Loading Loading @@ -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(); Loading @@ -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)); } } } } Loading Loading
core/java/android/service/textservice/SpellCheckerService.java +20 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading
core/java/android/view/textservice/SpellCheckerSession.java +104 −83 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading @@ -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); } } Loading Loading @@ -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(); Loading @@ -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)); } } } } Loading