Loading api/current.xml +36 −0 Original line number Original line Diff line number Diff line Loading @@ -111100,6 +111100,8 @@ </parameter> </parameter> <parameter name="queueMode" type="int"> <parameter name="queueMode" type="int"> </parameter> </parameter> <parameter name="params" type="java.util.HashMap<java.lang.String, java.lang.String>"> </parameter> </method> </method> <method name="setLanguage" <method name="setLanguage" return="int" return="int" Loading @@ -111114,6 +111116,19 @@ <parameter name="loc" type="java.util.Locale"> <parameter name="loc" type="java.util.Locale"> </parameter> </parameter> </method> </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" <method name="setPitch" return="int" return="int" abstract="false" abstract="false" Loading Loading @@ -111317,6 +111332,27 @@ </parameter> </parameter> </method> </method> </interface> </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> <package name="android.telephony" <package name="android.telephony" > > core/java/android/speech/tts/ITts.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -55,9 +55,9 @@ interface ITts { void addEarconFile(in String callingApp, in String earcon, in String filename); 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); int playSilence(in String callingApp, in long duration, in int queueMode, in String[] params); } } core/java/android/speech/tts/ITtsCallback.aidl +1 −1 Original line number Original line Diff line number Diff line Loading @@ -23,5 +23,5 @@ package android.speech.tts; * {@hide} * {@hide} */ */ oneway interface ITtsCallback { oneway interface ITtsCallback { void markReached(String mark); void utteranceCompleted(String utteranceId); } } core/java/android/speech/tts/TextToSpeech.java 100644 → 100755 +73 −5 Original line number Original line Diff line number Diff line Loading @@ -98,6 +98,18 @@ public class TextToSpeech { public void onInit(int status); public void onInit(int status); } } /** * 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 * Internal constants for the TTS functionality * * Loading Loading @@ -147,6 +159,7 @@ public class TextToSpeech { private ServiceConnection mServiceConnection; private ServiceConnection mServiceConnection; private ITts mITts = null; private ITts mITts = null; private ITtsCallback mITtscallback = null; private Context mContext = null; private Context mContext = null; private String mPackageName = ""; private String mPackageName = ""; private OnInitListener mInitListener = null; private OnInitListener mInitListener = null; Loading Loading @@ -178,6 +191,7 @@ public class TextToSpeech { mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY] = Engine.TTS_KEY_PARAM_COUNTRY; 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_VARIANT] = Engine.TTS_KEY_PARAM_VARIANT; mCachedParams[Engine.TTS_PARAM_POSITION_STREAM] = Engine.TTS_KEY_PARAM_STREAM; 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] = mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE); String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE); Loading Loading @@ -380,7 +394,7 @@ public class TextToSpeech { } } extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); if (extra != null) { 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); result = mITts.speak(mPackageName, text, queueMode, mCachedParams); Loading Loading @@ -437,7 +451,7 @@ public class TextToSpeech { } } extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); if (extra != null) { 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); result = mITts.playEarcon(mPackageName, earcon, queueMode, null); Loading Loading @@ -477,13 +491,19 @@ public class TextToSpeech { * * * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. * @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) { synchronized (mStartLock) { int result = TTS_ERROR; int result = TTS_ERROR; if (!mStarted) { if (!mStarted) { return result; return result; } } try { 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); result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams); } catch (RemoteException e) { } catch (RemoteException e) { // TTS died; restart it. // TTS died; restart it. Loading Loading @@ -845,7 +865,7 @@ public class TextToSpeech { // no need to read the stream type here // no need to read the stream type here String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); if (extra != null) { 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)){ if (mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename)){ Loading Loading @@ -887,4 +907,52 @@ public class TextToSpeech { mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = ""; 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; } } } } } packages/TtsService/src/android/tts/TtsService.java +43 −23 Original line number Original line Diff line number Diff line Loading @@ -60,19 +60,19 @@ public class TtsService extends Service implements OnCompletionListener { public int mType = TEXT; public int mType = TEXT; public long mDuration = 0; public long mDuration = 0; public String mFilename = null; public String mFilename = null; public String callingApp = ""; public String mCallingApp = ""; public SpeechItem(String source, String text, ArrayList<String> params, int itemType) { public SpeechItem(String source, String text, ArrayList<String> params, int itemType) { mText = text; mText = text; mParams = params; mParams = params; mType = itemType; mType = itemType; callingApp = source; mCallingApp = source; } } public SpeechItem(String source, long silenceTime) { public SpeechItem(String source, long silenceTime) { mDuration = silenceTime; mDuration = silenceTime; mType = SILENCE; mType = SILENCE; callingApp = source; mCallingApp = source; } } public SpeechItem(String source, String text, ArrayList<String> params, int itemType, String filename) { public SpeechItem(String source, String text, ArrayList<String> params, int itemType, String filename) { Loading @@ -80,7 +80,7 @@ public class TtsService extends Service implements OnCompletionListener { mParams = params; mParams = params; mType = itemType; mType = itemType; mFilename = filename; mFilename = filename; callingApp = source; mCallingApp = source; } } } } Loading Loading @@ -117,7 +117,8 @@ public class TtsService extends Service implements OnCompletionListener { private static final String CATEGORY = "android.intent.category.TTS"; private static final String CATEGORY = "android.intent.category.TTS"; private static final String PKGNAME = "android.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 Boolean mIsSpeaking; private ArrayList<SpeechItem> mSpeechQueue; private ArrayList<SpeechItem> mSpeechQueue; Loading Loading @@ -147,6 +148,7 @@ public class TtsService extends Service implements OnCompletionListener { mEarcons = new HashMap<String, SoundResource>(); mEarcons = new HashMap<String, SoundResource>(); mUtterances = new HashMap<String, SoundResource>(); mUtterances = new HashMap<String, SoundResource>(); mCallbacksMap = new HashMap<String, android.speech.tts.ITtsCallback>(); mSpeechQueue = new ArrayList<SpeechItem>(); mSpeechQueue = new ArrayList<SpeechItem>(); mPlayer = null; mPlayer = null; Loading Loading @@ -377,7 +379,7 @@ public class TtsService extends Service implements OnCompletionListener { if (speechQueueAvailable) { if (speechQueueAvailable) { Log.i("TTS", "Stopping"); Log.i("TTS", "Stopping"); for (int i = mSpeechQueue.size() - 1; i > -1; i--){ 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); mSpeechQueue.remove(i); } } } } Loading Loading @@ -439,11 +441,14 @@ public class TtsService extends Service implements OnCompletionListener { slnc.start(); slnc.start(); } } private void speakInternalOnly(final String text, private void speakInternalOnly(final SpeechItem speechItem) { final ArrayList<String> params) { class SynthThread implements Runnable { class SynthThread implements Runnable { public void run() { public void run() { String text = speechItem.mText; ArrayList<String> params = speechItem.mParams; String callingApp = speechItem.mCallingApp; boolean synthAvailable = false; boolean synthAvailable = false; String utteranceId = ""; try { try { synthAvailable = synthesizerLock.tryLock(); synthAvailable = synthesizerLock.tryLock(); if (!synthAvailable) { if (!synthAvailable) { Loading @@ -469,6 +474,8 @@ public class TtsService extends Service implements OnCompletionListener { country = params.get(i+1); country = params.get(i+1); } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){ } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){ variant = params.get(i+1); 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)) { } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_STREAM)) { try { try { streamType = Integer.parseInt(params.get(i + 1)); streamType = Integer.parseInt(params.get(i + 1)); Loading @@ -493,6 +500,9 @@ public class TtsService extends Service implements OnCompletionListener { if (synthAvailable) { if (synthAvailable) { synthesizerLock.unlock(); synthesizerLock.unlock(); } } if (utteranceId.length() > 0){ dispatchUtteranceCompletedCallback(utteranceId, callingApp); } processSpeechQueue(); processSpeechQueue(); } } } } Loading Loading @@ -577,18 +587,21 @@ public class TtsService extends Service implements OnCompletionListener { sendBroadcast(i); 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"); Log.i("TTS callback", "dispatch started"); // Broadcast to all clients the new value. // Broadcast to all clients the new value. final int N = mCallbacks.beginBroadcast(); final int N = mCallbacks.beginBroadcast(); for (int i = 0; i < N; i++) { try { try { mCallbacks.getBroadcastItem(i).markReached(mark); cb.utteranceCompleted(utteranceId); } catch (RemoteException e) { } catch (RemoteException e) { // The RemoteCallbackList will take care of removing // The RemoteCallbackList will take care of removing // the dead object for us. // the dead object for us. } } } mCallbacks.finishBroadcast(); mCallbacks.finishBroadcast(); Log.i("TTS callback", "dispatch completed to " + N); Log.i("TTS callback", "dispatch completed to " + N); } } Loading @@ -597,7 +610,7 @@ public class TtsService extends Service implements OnCompletionListener { if (currentSpeechItem.mText.length() < MAX_SPEECH_ITEM_CHAR_LENGTH){ if (currentSpeechItem.mText.length() < MAX_SPEECH_ITEM_CHAR_LENGTH){ return currentSpeechItem; return currentSpeechItem; } else { } else { String callingApp = currentSpeechItem.callingApp; String callingApp = currentSpeechItem.mCallingApp; ArrayList<SpeechItem> splitItems = new ArrayList<SpeechItem>(); ArrayList<SpeechItem> splitItems = new ArrayList<SpeechItem>(); int start = 0; int start = 0; int end = start + MAX_SPEECH_ITEM_CHAR_LENGTH - 1; int end = start + MAX_SPEECH_ITEM_CHAR_LENGTH - 1; Loading Loading @@ -643,8 +656,7 @@ public class TtsService extends Service implements OnCompletionListener { if (sr == null) { if (sr == null) { if (currentSpeechItem.mType == SpeechItem.TEXT) { if (currentSpeechItem.mType == SpeechItem.TEXT) { currentSpeechItem = splitCurrentTextIfNeeded(currentSpeechItem); currentSpeechItem = splitCurrentTextIfNeeded(currentSpeechItem); speakInternalOnly(currentSpeechItem.mText, speakInternalOnly(currentSpeechItem); currentSpeechItem.mParams); } else if (currentSpeechItem.mType == SpeechItem.TEXT_TO_FILE) { } else if (currentSpeechItem.mType == SpeechItem.TEXT_TO_FILE) { synthToFileInternalOnly(currentSpeechItem.mText, synthToFileInternalOnly(currentSpeechItem.mText, currentSpeechItem.mParams, currentSpeechItem.mFilename); currentSpeechItem.mParams, currentSpeechItem.mFilename); Loading Loading @@ -775,14 +787,22 @@ public class TtsService extends Service implements OnCompletionListener { private final android.speech.tts.ITts.Stub mBinder = new Stub() { private final android.speech.tts.ITts.Stub mBinder = new Stub() { public void registerCallback(ITtsCallback cb) { public int registerCallback(String packageName, ITtsCallback cb) { if (cb != null) if (cb != null) { mCallbacks.register(cb); mCallbacks.register(cb); mCallbacksMap.put(packageName, cb); return TextToSpeech.TTS_SUCCESS; } return TextToSpeech.TTS_ERROR; } } public void unregisterCallback(ITtsCallback cb) { public int unregisterCallback(String packageName, ITtsCallback cb) { if (cb != null) if (cb != null) { mCallbacksMap.remove(packageName); mCallbacks.unregister(cb); mCallbacks.unregister(cb); return TextToSpeech.TTS_SUCCESS; } return TextToSpeech.TTS_ERROR; } } /** /** Loading Loading
api/current.xml +36 −0 Original line number Original line Diff line number Diff line Loading @@ -111100,6 +111100,8 @@ </parameter> </parameter> <parameter name="queueMode" type="int"> <parameter name="queueMode" type="int"> </parameter> </parameter> <parameter name="params" type="java.util.HashMap<java.lang.String, java.lang.String>"> </parameter> </method> </method> <method name="setLanguage" <method name="setLanguage" return="int" return="int" Loading @@ -111114,6 +111116,19 @@ <parameter name="loc" type="java.util.Locale"> <parameter name="loc" type="java.util.Locale"> </parameter> </parameter> </method> </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" <method name="setPitch" return="int" return="int" abstract="false" abstract="false" Loading Loading @@ -111317,6 +111332,27 @@ </parameter> </parameter> </method> </method> </interface> </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> <package name="android.telephony" <package name="android.telephony" > >
core/java/android/speech/tts/ITts.aidl +2 −2 Original line number Original line Diff line number Diff line Loading @@ -55,9 +55,9 @@ interface ITts { void addEarconFile(in String callingApp, in String earcon, in String filename); 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); int playSilence(in String callingApp, in long duration, in int queueMode, in String[] params); } }
core/java/android/speech/tts/ITtsCallback.aidl +1 −1 Original line number Original line Diff line number Diff line Loading @@ -23,5 +23,5 @@ package android.speech.tts; * {@hide} * {@hide} */ */ oneway interface ITtsCallback { oneway interface ITtsCallback { void markReached(String mark); void utteranceCompleted(String utteranceId); } }
core/java/android/speech/tts/TextToSpeech.java 100644 → 100755 +73 −5 Original line number Original line Diff line number Diff line Loading @@ -98,6 +98,18 @@ public class TextToSpeech { public void onInit(int status); public void onInit(int status); } } /** * 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 * Internal constants for the TTS functionality * * Loading Loading @@ -147,6 +159,7 @@ public class TextToSpeech { private ServiceConnection mServiceConnection; private ServiceConnection mServiceConnection; private ITts mITts = null; private ITts mITts = null; private ITtsCallback mITtscallback = null; private Context mContext = null; private Context mContext = null; private String mPackageName = ""; private String mPackageName = ""; private OnInitListener mInitListener = null; private OnInitListener mInitListener = null; Loading Loading @@ -178,6 +191,7 @@ public class TextToSpeech { mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY] = Engine.TTS_KEY_PARAM_COUNTRY; 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_VARIANT] = Engine.TTS_KEY_PARAM_VARIANT; mCachedParams[Engine.TTS_PARAM_POSITION_STREAM] = Engine.TTS_KEY_PARAM_STREAM; 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] = mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE); String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE); Loading Loading @@ -380,7 +394,7 @@ public class TextToSpeech { } } extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); if (extra != null) { 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); result = mITts.speak(mPackageName, text, queueMode, mCachedParams); Loading Loading @@ -437,7 +451,7 @@ public class TextToSpeech { } } extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); if (extra != null) { 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); result = mITts.playEarcon(mPackageName, earcon, queueMode, null); Loading Loading @@ -477,13 +491,19 @@ public class TextToSpeech { * * * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS. * @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) { synchronized (mStartLock) { int result = TTS_ERROR; int result = TTS_ERROR; if (!mStarted) { if (!mStarted) { return result; return result; } } try { 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); result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams); } catch (RemoteException e) { } catch (RemoteException e) { // TTS died; restart it. // TTS died; restart it. Loading Loading @@ -845,7 +865,7 @@ public class TextToSpeech { // no need to read the stream type here // no need to read the stream type here String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID); if (extra != null) { 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)){ if (mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename)){ Loading Loading @@ -887,4 +907,52 @@ public class TextToSpeech { mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = ""; 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; } } } } }
packages/TtsService/src/android/tts/TtsService.java +43 −23 Original line number Original line Diff line number Diff line Loading @@ -60,19 +60,19 @@ public class TtsService extends Service implements OnCompletionListener { public int mType = TEXT; public int mType = TEXT; public long mDuration = 0; public long mDuration = 0; public String mFilename = null; public String mFilename = null; public String callingApp = ""; public String mCallingApp = ""; public SpeechItem(String source, String text, ArrayList<String> params, int itemType) { public SpeechItem(String source, String text, ArrayList<String> params, int itemType) { mText = text; mText = text; mParams = params; mParams = params; mType = itemType; mType = itemType; callingApp = source; mCallingApp = source; } } public SpeechItem(String source, long silenceTime) { public SpeechItem(String source, long silenceTime) { mDuration = silenceTime; mDuration = silenceTime; mType = SILENCE; mType = SILENCE; callingApp = source; mCallingApp = source; } } public SpeechItem(String source, String text, ArrayList<String> params, int itemType, String filename) { public SpeechItem(String source, String text, ArrayList<String> params, int itemType, String filename) { Loading @@ -80,7 +80,7 @@ public class TtsService extends Service implements OnCompletionListener { mParams = params; mParams = params; mType = itemType; mType = itemType; mFilename = filename; mFilename = filename; callingApp = source; mCallingApp = source; } } } } Loading Loading @@ -117,7 +117,8 @@ public class TtsService extends Service implements OnCompletionListener { private static final String CATEGORY = "android.intent.category.TTS"; private static final String CATEGORY = "android.intent.category.TTS"; private static final String PKGNAME = "android.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 Boolean mIsSpeaking; private ArrayList<SpeechItem> mSpeechQueue; private ArrayList<SpeechItem> mSpeechQueue; Loading Loading @@ -147,6 +148,7 @@ public class TtsService extends Service implements OnCompletionListener { mEarcons = new HashMap<String, SoundResource>(); mEarcons = new HashMap<String, SoundResource>(); mUtterances = new HashMap<String, SoundResource>(); mUtterances = new HashMap<String, SoundResource>(); mCallbacksMap = new HashMap<String, android.speech.tts.ITtsCallback>(); mSpeechQueue = new ArrayList<SpeechItem>(); mSpeechQueue = new ArrayList<SpeechItem>(); mPlayer = null; mPlayer = null; Loading Loading @@ -377,7 +379,7 @@ public class TtsService extends Service implements OnCompletionListener { if (speechQueueAvailable) { if (speechQueueAvailable) { Log.i("TTS", "Stopping"); Log.i("TTS", "Stopping"); for (int i = mSpeechQueue.size() - 1; i > -1; i--){ 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); mSpeechQueue.remove(i); } } } } Loading Loading @@ -439,11 +441,14 @@ public class TtsService extends Service implements OnCompletionListener { slnc.start(); slnc.start(); } } private void speakInternalOnly(final String text, private void speakInternalOnly(final SpeechItem speechItem) { final ArrayList<String> params) { class SynthThread implements Runnable { class SynthThread implements Runnable { public void run() { public void run() { String text = speechItem.mText; ArrayList<String> params = speechItem.mParams; String callingApp = speechItem.mCallingApp; boolean synthAvailable = false; boolean synthAvailable = false; String utteranceId = ""; try { try { synthAvailable = synthesizerLock.tryLock(); synthAvailable = synthesizerLock.tryLock(); if (!synthAvailable) { if (!synthAvailable) { Loading @@ -469,6 +474,8 @@ public class TtsService extends Service implements OnCompletionListener { country = params.get(i+1); country = params.get(i+1); } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){ } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){ variant = params.get(i+1); 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)) { } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_STREAM)) { try { try { streamType = Integer.parseInt(params.get(i + 1)); streamType = Integer.parseInt(params.get(i + 1)); Loading @@ -493,6 +500,9 @@ public class TtsService extends Service implements OnCompletionListener { if (synthAvailable) { if (synthAvailable) { synthesizerLock.unlock(); synthesizerLock.unlock(); } } if (utteranceId.length() > 0){ dispatchUtteranceCompletedCallback(utteranceId, callingApp); } processSpeechQueue(); processSpeechQueue(); } } } } Loading Loading @@ -577,18 +587,21 @@ public class TtsService extends Service implements OnCompletionListener { sendBroadcast(i); 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"); Log.i("TTS callback", "dispatch started"); // Broadcast to all clients the new value. // Broadcast to all clients the new value. final int N = mCallbacks.beginBroadcast(); final int N = mCallbacks.beginBroadcast(); for (int i = 0; i < N; i++) { try { try { mCallbacks.getBroadcastItem(i).markReached(mark); cb.utteranceCompleted(utteranceId); } catch (RemoteException e) { } catch (RemoteException e) { // The RemoteCallbackList will take care of removing // The RemoteCallbackList will take care of removing // the dead object for us. // the dead object for us. } } } mCallbacks.finishBroadcast(); mCallbacks.finishBroadcast(); Log.i("TTS callback", "dispatch completed to " + N); Log.i("TTS callback", "dispatch completed to " + N); } } Loading @@ -597,7 +610,7 @@ public class TtsService extends Service implements OnCompletionListener { if (currentSpeechItem.mText.length() < MAX_SPEECH_ITEM_CHAR_LENGTH){ if (currentSpeechItem.mText.length() < MAX_SPEECH_ITEM_CHAR_LENGTH){ return currentSpeechItem; return currentSpeechItem; } else { } else { String callingApp = currentSpeechItem.callingApp; String callingApp = currentSpeechItem.mCallingApp; ArrayList<SpeechItem> splitItems = new ArrayList<SpeechItem>(); ArrayList<SpeechItem> splitItems = new ArrayList<SpeechItem>(); int start = 0; int start = 0; int end = start + MAX_SPEECH_ITEM_CHAR_LENGTH - 1; int end = start + MAX_SPEECH_ITEM_CHAR_LENGTH - 1; Loading Loading @@ -643,8 +656,7 @@ public class TtsService extends Service implements OnCompletionListener { if (sr == null) { if (sr == null) { if (currentSpeechItem.mType == SpeechItem.TEXT) { if (currentSpeechItem.mType == SpeechItem.TEXT) { currentSpeechItem = splitCurrentTextIfNeeded(currentSpeechItem); currentSpeechItem = splitCurrentTextIfNeeded(currentSpeechItem); speakInternalOnly(currentSpeechItem.mText, speakInternalOnly(currentSpeechItem); currentSpeechItem.mParams); } else if (currentSpeechItem.mType == SpeechItem.TEXT_TO_FILE) { } else if (currentSpeechItem.mType == SpeechItem.TEXT_TO_FILE) { synthToFileInternalOnly(currentSpeechItem.mText, synthToFileInternalOnly(currentSpeechItem.mText, currentSpeechItem.mParams, currentSpeechItem.mFilename); currentSpeechItem.mParams, currentSpeechItem.mFilename); Loading Loading @@ -775,14 +787,22 @@ public class TtsService extends Service implements OnCompletionListener { private final android.speech.tts.ITts.Stub mBinder = new Stub() { private final android.speech.tts.ITts.Stub mBinder = new Stub() { public void registerCallback(ITtsCallback cb) { public int registerCallback(String packageName, ITtsCallback cb) { if (cb != null) if (cb != null) { mCallbacks.register(cb); mCallbacks.register(cb); mCallbacksMap.put(packageName, cb); return TextToSpeech.TTS_SUCCESS; } return TextToSpeech.TTS_ERROR; } } public void unregisterCallback(ITtsCallback cb) { public int unregisterCallback(String packageName, ITtsCallback cb) { if (cb != null) if (cb != null) { mCallbacksMap.remove(packageName); mCallbacks.unregister(cb); mCallbacks.unregister(cb); return TextToSpeech.TTS_SUCCESS; } return TextToSpeech.TTS_ERROR; } } /** /** Loading