summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml36
-rwxr-xr-xcore/java/android/speech/tts/ITts.aidl4
-rwxr-xr-xcore/java/android/speech/tts/ITtsCallback.aidl2
-rwxr-xr-x[-rw-r--r--]core/java/android/speech/tts/TextToSpeech.java78
-rwxr-xr-xpackages/TtsService/src/android/tts/TtsService.java66
5 files changed, 155 insertions, 31 deletions
diff --git a/api/current.xml b/api/current.xml
index 88e5025..a5c4e68 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -115058,6 +115058,8 @@
</parameter>
<parameter name="queueMode" type="int">
</parameter>
+<parameter name="params" type="java.util.HashMap&lt;java.lang.String, java.lang.String&gt;">
+</parameter>
</method>
<method name="setLanguage"
return="int"
@@ -115072,6 +115074,19 @@
<parameter name="loc" type="java.util.Locale">
</parameter>
</method>
+<method name="setOnUtteranceCompletedListener"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.speech.tts.TextToSpeech.OnUtteranceCompletedListener">
+</parameter>
+</method>
<method name="setPitch"
return="int"
abstract="false"
@@ -115275,6 +115290,27 @@
</parameter>
</method>
</interface>
+<interface name="TextToSpeech.OnUtteranceCompletedListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onUtteranceCompleted"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="utteranceId" type="java.lang.String">
+</parameter>
+</method>
+</interface>
</package>
<package name="android.telephony"
>
diff --git a/core/java/android/speech/tts/ITts.aidl b/core/java/android/speech/tts/ITts.aidl
index 5b18b5d..1812188 100755
--- a/core/java/android/speech/tts/ITts.aidl
+++ b/core/java/android/speech/tts/ITts.aidl
@@ -55,9 +55,9 @@ interface ITts {
void addEarconFile(in String callingApp, in String earcon, in String filename);
- void registerCallback(ITtsCallback cb);
+ int registerCallback(in String callingApp, ITtsCallback cb);
- void unregisterCallback(ITtsCallback cb);
+ int unregisterCallback(in String callingApp, ITtsCallback cb);
int playSilence(in String callingApp, in long duration, in int queueMode, in String[] params);
}
diff --git a/core/java/android/speech/tts/ITtsCallback.aidl b/core/java/android/speech/tts/ITtsCallback.aidl
index 48ed73e..c9898eb 100755
--- a/core/java/android/speech/tts/ITtsCallback.aidl
+++ b/core/java/android/speech/tts/ITtsCallback.aidl
@@ -23,5 +23,5 @@ package android.speech.tts;
* {@hide}
*/
oneway interface ITtsCallback {
- void markReached(String mark);
+ void utteranceCompleted(String utteranceId);
}
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 2369535..a2e70b8 100644..100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -99,6 +99,18 @@ public class TextToSpeech {
}
/**
+ * Called when the TTS has completed saying something that has an utterance ID set.
+ *
+ * The OnUtteranceCompletedListener must implement the onUtteranceCompleted function.
+ * onUtteranceCompleted is passed a String that is the utteranceId given in
+ * the original speak call.
+ */
+ public interface OnUtteranceCompletedListener {
+ public void onUtteranceCompleted(String utteranceId);
+ }
+
+
+ /**
* Internal constants for the TTS functionality
*
* {@hide}
@@ -147,6 +159,7 @@ public class TextToSpeech {
private ServiceConnection mServiceConnection;
private ITts mITts = null;
+ private ITtsCallback mITtscallback = null;
private Context mContext = null;
private String mPackageName = "";
private OnInitListener mInitListener = null;
@@ -178,6 +191,7 @@ public class TextToSpeech {
mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY] = Engine.TTS_KEY_PARAM_COUNTRY;
mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT] = Engine.TTS_KEY_PARAM_VARIANT;
mCachedParams[Engine.TTS_PARAM_POSITION_STREAM] = Engine.TTS_KEY_PARAM_STREAM;
+ mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = Engine.TTS_KEY_PARAM_UTTERANCE_ID;
mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] =
String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE);
@@ -189,7 +203,7 @@ public class TextToSpeech {
mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] =
String.valueOf(Engine.TTS_DEFAULT_STREAM);
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = "";
+ mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = "";
initTts();
}
@@ -380,7 +394,7 @@ public class TextToSpeech {
}
extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
if (extra != null) {
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = extra;
+ mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
}
}
result = mITts.speak(mPackageName, text, queueMode, mCachedParams);
@@ -437,7 +451,7 @@ public class TextToSpeech {
}
extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
if (extra != null) {
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = extra;
+ mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
}
}
result = mITts.playEarcon(mPackageName, earcon, queueMode, null);
@@ -477,13 +491,19 @@ public class TextToSpeech {
*
* @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
*/
- public int playSilence(long durationInMs, int queueMode) {
+ public int playSilence(long durationInMs, int queueMode, HashMap<String,String> params) {
synchronized (mStartLock) {
int result = TTS_ERROR;
if (!mStarted) {
return result;
}
try {
+ if ((params != null) && (!params.isEmpty())) {
+ String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
+ if (extra != null) {
+ mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
+ }
+ }
result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams);
} catch (RemoteException e) {
// TTS died; restart it.
@@ -845,7 +865,7 @@ public class TextToSpeech {
// no need to read the stream type here
String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
if (extra != null) {
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = extra;
+ mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
}
}
if (mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename)){
@@ -887,4 +907,52 @@ public class TextToSpeech {
mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = "";
}
+ /**
+ * Sets the OnUtteranceCompletedListener that will fire when an utterance completes.
+ *
+ * @param listener
+ * The OnUtteranceCompletedListener
+ *
+ * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ */
+ public int setOnUtteranceCompletedListener(
+ final OnUtteranceCompletedListener listener) {
+ synchronized (mStartLock) {
+ int result = TTS_ERROR;
+ if (!mStarted) {
+ return result;
+ }
+ mITtscallback = new ITtsCallback.Stub() {
+ public void utteranceCompleted(String utteranceId) throws RemoteException {
+ if (listener != null) {
+ listener.onUtteranceCompleted(utteranceId);
+ }
+ }
+ };
+ try {
+ result = mITts.registerCallback(mPackageName, mITtscallback);
+ } catch (RemoteException e) {
+ // TTS died; restart it.
+ Log.e("TextToSpeech.java - registerCallback", "RemoteException");
+ e.printStackTrace();
+ mStarted = false;
+ initTts();
+ } catch (NullPointerException e) {
+ // TTS died; restart it.
+ Log.e("TextToSpeech.java - registerCallback", "NullPointerException");
+ e.printStackTrace();
+ mStarted = false;
+ initTts();
+ } catch (IllegalStateException e) {
+ // TTS died; restart it.
+ Log.e("TextToSpeech.java - registerCallback", "IllegalStateException");
+ e.printStackTrace();
+ mStarted = false;
+ initTts();
+ } finally {
+ return result;
+ }
+ }
+ }
+
}
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 949dfae..09bb8f9 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -60,19 +60,19 @@ public class TtsService extends Service implements OnCompletionListener {
public int mType = TEXT;
public long mDuration = 0;
public String mFilename = null;
- public String callingApp = "";
+ public String mCallingApp = "";
public SpeechItem(String source, String text, ArrayList<String> params, int itemType) {
mText = text;
mParams = params;
mType = itemType;
- callingApp = source;
+ mCallingApp = source;
}
public SpeechItem(String source, long silenceTime) {
mDuration = silenceTime;
mType = SILENCE;
- callingApp = source;
+ mCallingApp = source;
}
public SpeechItem(String source, String text, ArrayList<String> params, int itemType, String filename) {
@@ -80,7 +80,7 @@ public class TtsService extends Service implements OnCompletionListener {
mParams = params;
mType = itemType;
mFilename = filename;
- callingApp = source;
+ mCallingApp = source;
}
}
@@ -117,7 +117,8 @@ public class TtsService extends Service implements OnCompletionListener {
private static final String CATEGORY = "android.intent.category.TTS";
private static final String PKGNAME = "android.tts";
- final RemoteCallbackList<android.speech.tts.ITtsCallback> mCallbacks = new RemoteCallbackList<ITtsCallback>();
+ private final RemoteCallbackList<android.speech.tts.ITtsCallback> mCallbacks = new RemoteCallbackList<ITtsCallback>();
+ private HashMap<String, android.speech.tts.ITtsCallback> mCallbacksMap;
private Boolean mIsSpeaking;
private ArrayList<SpeechItem> mSpeechQueue;
@@ -147,6 +148,7 @@ public class TtsService extends Service implements OnCompletionListener {
mEarcons = new HashMap<String, SoundResource>();
mUtterances = new HashMap<String, SoundResource>();
+ mCallbacksMap = new HashMap<String, android.speech.tts.ITtsCallback>();
mSpeechQueue = new ArrayList<SpeechItem>();
mPlayer = null;
@@ -377,7 +379,7 @@ public class TtsService extends Service implements OnCompletionListener {
if (speechQueueAvailable) {
Log.i("TTS", "Stopping");
for (int i = mSpeechQueue.size() - 1; i > -1; i--){
- if (mSpeechQueue.get(i).callingApp.equals(callingApp)){
+ if (mSpeechQueue.get(i).mCallingApp.equals(callingApp)){
mSpeechQueue.remove(i);
}
}
@@ -439,11 +441,14 @@ public class TtsService extends Service implements OnCompletionListener {
slnc.start();
}
- private void speakInternalOnly(final String text,
- final ArrayList<String> params) {
+ private void speakInternalOnly(final SpeechItem speechItem) {
class SynthThread implements Runnable {
public void run() {
+ String text = speechItem.mText;
+ ArrayList<String> params = speechItem.mParams;
+ String callingApp = speechItem.mCallingApp;
boolean synthAvailable = false;
+ String utteranceId = "";
try {
synthAvailable = synthesizerLock.tryLock();
if (!synthAvailable) {
@@ -469,6 +474,8 @@ public class TtsService extends Service implements OnCompletionListener {
country = params.get(i+1);
} else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){
variant = params.get(i+1);
+ } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){
+ utteranceId = params.get(i+1);
} else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_STREAM)) {
try {
streamType = Integer.parseInt(params.get(i + 1));
@@ -493,6 +500,9 @@ public class TtsService extends Service implements OnCompletionListener {
if (synthAvailable) {
synthesizerLock.unlock();
}
+ if (utteranceId.length() > 0){
+ dispatchUtteranceCompletedCallback(utteranceId, callingApp);
+ }
processSpeechQueue();
}
}
@@ -577,17 +587,20 @@ public class TtsService extends Service implements OnCompletionListener {
sendBroadcast(i);
}
- private void dispatchSpeechCompletedCallbacks(String mark) {
+
+ private void dispatchUtteranceCompletedCallback(String utteranceId, String packageName) {
+ ITtsCallback cb = mCallbacksMap.get(packageName);
+ if (cb == null){
+ return;
+ }
Log.i("TTS callback", "dispatch started");
// Broadcast to all clients the new value.
final int N = mCallbacks.beginBroadcast();
- for (int i = 0; i < N; i++) {
- try {
- mCallbacks.getBroadcastItem(i).markReached(mark);
- } catch (RemoteException e) {
- // The RemoteCallbackList will take care of removing
- // the dead object for us.
- }
+ try {
+ cb.utteranceCompleted(utteranceId);
+ } catch (RemoteException e) {
+ // The RemoteCallbackList will take care of removing
+ // the dead object for us.
}
mCallbacks.finishBroadcast();
Log.i("TTS callback", "dispatch completed to " + N);
@@ -597,7 +610,7 @@ public class TtsService extends Service implements OnCompletionListener {
if (currentSpeechItem.mText.length() < MAX_SPEECH_ITEM_CHAR_LENGTH){
return currentSpeechItem;
} else {
- String callingApp = currentSpeechItem.callingApp;
+ String callingApp = currentSpeechItem.mCallingApp;
ArrayList<SpeechItem> splitItems = new ArrayList<SpeechItem>();
int start = 0;
int end = start + MAX_SPEECH_ITEM_CHAR_LENGTH - 1;
@@ -643,8 +656,7 @@ public class TtsService extends Service implements OnCompletionListener {
if (sr == null) {
if (currentSpeechItem.mType == SpeechItem.TEXT) {
currentSpeechItem = splitCurrentTextIfNeeded(currentSpeechItem);
- speakInternalOnly(currentSpeechItem.mText,
- currentSpeechItem.mParams);
+ speakInternalOnly(currentSpeechItem);
} else if (currentSpeechItem.mType == SpeechItem.TEXT_TO_FILE) {
synthToFileInternalOnly(currentSpeechItem.mText,
currentSpeechItem.mParams, currentSpeechItem.mFilename);
@@ -775,14 +787,22 @@ public class TtsService extends Service implements OnCompletionListener {
private final android.speech.tts.ITts.Stub mBinder = new Stub() {
- public void registerCallback(ITtsCallback cb) {
- if (cb != null)
+ public int registerCallback(String packageName, ITtsCallback cb) {
+ if (cb != null) {
mCallbacks.register(cb);
+ mCallbacksMap.put(packageName, cb);
+ return TextToSpeech.TTS_SUCCESS;
+ }
+ return TextToSpeech.TTS_ERROR;
}
- public void unregisterCallback(ITtsCallback cb) {
- if (cb != null)
+ public int unregisterCallback(String packageName, ITtsCallback cb) {
+ if (cb != null) {
+ mCallbacksMap.remove(packageName);
mCallbacks.unregister(cb);
+ return TextToSpeech.TTS_SUCCESS;
+ }
+ return TextToSpeech.TTS_ERROR;
}
/**