diff options
| author | Przemyslaw Szczepaniak <pszczepaniak@google.com> | 2013-01-16 17:24:44 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-01-22 17:20:37 +0000 |
| commit | 9c4012b31b0c09cb14689bd96a71aae42c8a00cd (patch) | |
| tree | 202330fd6f0f08726ae812ba635010e825e4c9d7 /core/java/android/speech/tts | |
| parent | b3608ad87739a8ec087a498d8c9397caf01f7738 (diff) | |
| download | frameworks_base-9c4012b31b0c09cb14689bd96a71aae42c8a00cd.zip frameworks_base-9c4012b31b0c09cb14689bd96a71aae42c8a00cd.tar.gz frameworks_base-9c4012b31b0c09cb14689bd96a71aae42c8a00cd.tar.bz2 | |
Make TextToSpeech.shutdown() work before init callback.
TextToSpeech.shutdown() never worked properly if was called before receiving
onServiceConnected in connection object. Also, due to recent changes,
TextToSpeech.shutdown() did not work until async task created in
onServiceConnected returned its result to the main thread.
This change makes .shutdown() work in all those cases. To allow that
runAction can now execute code with connection that's not fully setuped
- so we can shutt it down. Also, newly created connection is now hold in
new member variable mConnectingServiceConnection, so it can be closed
before receiving onServiceConnected callback.
Also, I changed name of OnServiceConnectedAsyncTask to
SetupConnectionAsyncTask, I find it more descriptive.
Bug: 8003757
Change-Id: I41d84cfdb8fa28fe44235fb4a9764fa8f3d0643c
Diffstat (limited to 'core/java/android/speech/tts')
| -rw-r--r-- | core/java/android/speech/tts/TextToSpeech.java | 83 |
1 files changed, 55 insertions, 28 deletions
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java index 30a8626..e2dc5d5 100644 --- a/core/java/android/speech/tts/TextToSpeech.java +++ b/core/java/android/speech/tts/TextToSpeech.java @@ -479,6 +479,7 @@ public class TextToSpeech { } private final Context mContext; + private Connection mConnectingServiceConnection; private Connection mServiceConnection; private OnInitListener mInitListener; // Written from an unspecified application thread, read from @@ -554,21 +555,24 @@ public class TextToSpeech { initTts(); } - private <R> R runActionNoReconnect(Action<R> action, R errorResult, String method) { - return runAction(action, errorResult, method, false); + private <R> R runActionNoReconnect(Action<R> action, R errorResult, String method, + boolean onlyEstablishedConnection) { + return runAction(action, errorResult, method, false, onlyEstablishedConnection); } private <R> R runAction(Action<R> action, R errorResult, String method) { - return runAction(action, errorResult, method, true); + return runAction(action, errorResult, method, true, true); } - private <R> R runAction(Action<R> action, R errorResult, String method, boolean reconnect) { + private <R> R runAction(Action<R> action, R errorResult, String method, + boolean reconnect, boolean onlyEstablishedConnection) { synchronized (mStartLock) { if (mServiceConnection == null) { Log.w(TAG, method + " failed: not bound to TTS engine"); return errorResult; } - return mServiceConnection.runAction(action, errorResult, method, reconnect); + return mServiceConnection.runAction(action, errorResult, method, reconnect, + onlyEstablishedConnection); } } @@ -631,6 +635,7 @@ public class TextToSpeech { return false; } else { Log.i(TAG, "Sucessfully bound to " + engine); + mConnectingServiceConnection = connection; return true; } } @@ -654,6 +659,16 @@ public class TextToSpeech { * so the TextToSpeech engine can be cleanly stopped. */ public void shutdown() { + // Special case, we are asked to shutdown connection that did finalize its connection. + synchronized (mStartLock) { + if (mConnectingServiceConnection != null) { + mContext.unbindService(mConnectingServiceConnection); + mConnectingServiceConnection = null; + return; + } + } + + // Post connection case runActionNoReconnect(new Action<Void>() { @Override public Void run(ITextToSpeechService service) throws RemoteException { @@ -671,7 +686,7 @@ public class TextToSpeech { mCurrentEngine = null; return null; } - }, null, "shutdown"); + }, null, "shutdown", false); } /** @@ -1310,7 +1325,9 @@ public class TextToSpeech { private class Connection implements ServiceConnection { private ITextToSpeechService mService; - private OnServiceConnectedAsyncTask mOnServiceConnectedAsyncTask; + private SetupConnectionAsyncTask mOnSetupConnectionAsyncTask; + + private boolean mEstablished; private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() { @Override @@ -1338,13 +1355,11 @@ public class TextToSpeech { } }; - private class OnServiceConnectedAsyncTask extends AsyncTask<Void, Void, Integer> { + private class SetupConnectionAsyncTask extends AsyncTask<Void, Void, Integer> { private final ComponentName mName; - private final ITextToSpeechService mConnectedService; - public OnServiceConnectedAsyncTask(ComponentName name, IBinder service) { + public SetupConnectionAsyncTask(ComponentName name) { mName = name; - mConnectedService = ITextToSpeechService.Stub.asInterface(service); } @Override @@ -1355,8 +1370,8 @@ public class TextToSpeech { } try { - mConnectedService.setCallback(getCallerIdentity(), mCallback); - String[] defaultLanguage = mConnectedService.getClientDefaultLanguage(); + mService.setCallback(getCallerIdentity(), mCallback); + String[] defaultLanguage = mService.getClientDefaultLanguage(); mParams.putString(Engine.KEY_PARAM_LANGUAGE, defaultLanguage[0]); mParams.putString(Engine.KEY_PARAM_COUNTRY, defaultLanguage[1]); @@ -1374,13 +1389,10 @@ public class TextToSpeech { @Override protected void onPostExecute(Integer result) { synchronized(mStartLock) { - if (mOnServiceConnectedAsyncTask == this) { - mOnServiceConnectedAsyncTask = null; + if (mOnSetupConnectionAsyncTask == this) { + mOnSetupConnectionAsyncTask = null; } - - mServiceConnection = Connection.this; - mService = mConnectedService; - + mEstablished = true; dispatchOnInit(result); } } @@ -1389,14 +1401,20 @@ public class TextToSpeech { @Override public void onServiceConnected(ComponentName name, IBinder service) { synchronized(mStartLock) { + mConnectingServiceConnection = null; + Log.i(TAG, "Connected to " + name); - if (mOnServiceConnectedAsyncTask != null) { - mOnServiceConnectedAsyncTask.cancel(false); + if (mOnSetupConnectionAsyncTask != null) { + mOnSetupConnectionAsyncTask.cancel(false); } - mOnServiceConnectedAsyncTask = new OnServiceConnectedAsyncTask(name, service); - mOnServiceConnectedAsyncTask.execute(); + mService = ITextToSpeechService.Stub.asInterface(service); + mServiceConnection = Connection.this; + + mEstablished = false; + mOnSetupConnectionAsyncTask = new SetupConnectionAsyncTask(name); + mOnSetupConnectionAsyncTask.execute(); } } @@ -1407,14 +1425,14 @@ public class TextToSpeech { /** * Clear connection related fields and cancel mOnServiceConnectedAsyncTask if set. * - * @return true if we cancel mOnServiceConnectedAsyncTask in progress. + * @return true if we cancel mOnSetupConnectionAsyncTask in progress. */ private boolean clearServiceConnection() { synchronized(mStartLock) { boolean result = false; - if (mOnServiceConnectedAsyncTask != null) { - result = mOnServiceConnectedAsyncTask.cancel(false); - mOnServiceConnectedAsyncTask = null; + if (mOnSetupConnectionAsyncTask != null) { + result = mOnSetupConnectionAsyncTask.cancel(false); + mOnSetupConnectionAsyncTask = null; } mService = null; @@ -1445,13 +1463,22 @@ public class TextToSpeech { clearServiceConnection(); } - public <R> R runAction(Action<R> action, R errorResult, String method, boolean reconnect) { + public boolean isEstablished() { + return mService != null && mEstablished; + } + + public <R> R runAction(Action<R> action, R errorResult, String method, + boolean reconnect, boolean onlyEstablishedConnection) { synchronized (mStartLock) { try { if (mService == null) { Log.w(TAG, method + " failed: not connected to TTS engine"); return errorResult; } + if (onlyEstablishedConnection && isEstablished()) { + Log.w(TAG, method + " failed: TTS engine connection not fully setuped"); + return errorResult; + } return action.run(mService); } catch (RemoteException ex) { Log.e(TAG, method + " failed", ex); |
