summaryrefslogtreecommitdiffstats
path: root/core/java/android/speech/tts
diff options
context:
space:
mode:
authorPrzemyslaw Szczepaniak <pszczepaniak@google.com>2012-11-07 14:03:53 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-11-20 04:01:09 -0800
commit8f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7 (patch)
treea3c7327f649e0a95d71a79a1113d1c50c0623642 /core/java/android/speech/tts
parentb920b40510cd237b9dd60a00717527cd4ece2247 (diff)
downloadframeworks_base-8f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7.zip
frameworks_base-8f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7.tar.gz
frameworks_base-8f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7.tar.bz2
TTS onServiceConnection moved to async task
ITextToSpeechService.setCallback (service rpc call) is no longer executed on UI thread. I kept OnInitListener.onInit being called on the UI thread. It's not specified explicitly, but I don't want to introduce subtle bugs. +bonus import fix. Bug: 6540404 Change-Id: I0136e7efeb374b605ed29ee8b3f550ec2bd2c356
Diffstat (limited to 'core/java/android/speech/tts')
-rw-r--r--core/java/android/speech/tts/TextToSpeech.java106
-rw-r--r--core/java/android/speech/tts/TextToSpeechService.java1
2 files changed, 81 insertions, 26 deletions
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 9d570fc..f4c401b 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.media.AudioManager;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
@@ -1276,9 +1277,11 @@ public class TextToSpeech {
return mEnginesHelper.getEngines();
}
-
private class Connection implements ServiceConnection {
private ITextToSpeechService mService;
+
+ private OnServiceConnectedAsyncTask mOnServiceConnectedAsyncTask;
+
private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
@Override
public void onDone(String utteranceId) {
@@ -1305,23 +1308,59 @@ public class TextToSpeech {
}
};
+ private class OnServiceConnectedAsyncTask extends AsyncTask<Void, Void, Integer> {
+ private final ComponentName mName;
+ private final ITextToSpeechService mConnectedService;
+
+ public OnServiceConnectedAsyncTask(ComponentName name, IBinder service) {
+ mName = name;
+ mConnectedService = ITextToSpeechService.Stub.asInterface(service);
+ }
+
+ @Override
+ protected Integer doInBackground(Void... params) {
+ synchronized(mStartLock) {
+ if (isCancelled()) {
+ return null;
+ }
+
+ try {
+ mConnectedService.setCallback(getCallerIdentity(), mCallback);
+ Log.i(TAG, "Setuped connection to " + mName);
+ return SUCCESS;
+ } catch (RemoteException re) {
+ Log.e(TAG, "Error connecting to service, setCallback() failed");
+ return ERROR;
+ }
+ }
+ }
+
+ @Override
+ protected void onPostExecute(Integer result) {
+ synchronized(mStartLock) {
+ if (mOnServiceConnectedAsyncTask == this) {
+ mOnServiceConnectedAsyncTask = null;
+ }
+
+ mServiceConnection = Connection.this;
+ mService = mConnectedService;
+
+ dispatchOnInit(result);
+ }
+ }
+ }
+
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- Log.i(TAG, "Connected to " + name);
synchronized(mStartLock) {
- if (mServiceConnection != null) {
- // Disconnect any previous service connection
- mServiceConnection.disconnect();
- }
- mServiceConnection = this;
- mService = ITextToSpeechService.Stub.asInterface(service);
- try {
- mService.setCallback(getCallerIdentity(), mCallback);
- dispatchOnInit(SUCCESS);
- } catch (RemoteException re) {
- Log.e(TAG, "Error connecting to service, setCallback() failed");
- dispatchOnInit(ERROR);
+ Log.i(TAG, "Connected to " + name);
+
+ if (mOnServiceConnectedAsyncTask != null) {
+ mOnServiceConnectedAsyncTask.cancel(false);
}
+
+ mOnServiceConnectedAsyncTask = new OnServiceConnectedAsyncTask(name, service);
+ mOnServiceConnectedAsyncTask.execute();
}
}
@@ -1329,28 +1368,45 @@ public class TextToSpeech {
return mCallback;
}
- @Override
- public void onServiceDisconnected(ComponentName name) {
+ /**
+ * Clear connection related fields and cancel mOnServiceConnectedAsyncTask if set.
+ *
+ * @return true if we cancel mOnServiceConnectedAsyncTask in progress.
+ */
+ private boolean clearServiceConnection() {
synchronized(mStartLock) {
+ boolean result = false;
+ if (mOnServiceConnectedAsyncTask != null) {
+ result = mOnServiceConnectedAsyncTask.cancel(false);
+ mOnServiceConnectedAsyncTask = null;
+ }
+
mService = null;
// If this is the active connection, clear it
if (mServiceConnection == this) {
mServiceConnection = null;
}
+ return result;
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.i(TAG, "Asked to disconnect from " + name);
+ if (clearServiceConnection()) {
+ /* We need to protect against a rare case where engine
+ * dies just after successful connection - and we process onServiceDisconnected
+ * before OnServiceConnectedAsyncTask.onPostExecute. onServiceDisconnected cancels
+ * OnServiceConnectedAsyncTask.onPostExecute and we don't call dispatchOnInit
+ * with ERROR as argument.
+ */
+ dispatchOnInit(ERROR);
}
}
public void disconnect() {
mContext.unbindService(this);
-
- synchronized (mStartLock) {
- mService = null;
- // If this is the active connection, clear it
- if (mServiceConnection == this) {
- mServiceConnection = null;
- }
-
- }
+ clearServiceConnection();
}
public <R> R runAction(Action<R> action, R errorResult, String method, boolean reconnect) {
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index d124e68..3ebe029 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -34,7 +34,6 @@ import android.text.TextUtils;
import android.util.Log;
import java.io.File;
-import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Set;