Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -27752,6 +27752,7 @@ package android.speech.tts { method public abstract deprecated void onError(java.lang.String); method public void onError(java.lang.String, int); method public abstract void onStart(java.lang.String); method public void onStop(java.lang.String, boolean); } public class Voice implements android.os.Parcelable { core/java/android/speech/tts/ITextToSpeechCallback.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ oneway interface ITextToSpeechCallback { * * @param utteranceId Unique id identifying synthesis request. */ void onStop(String utteranceId); void onStop(String utteranceId, boolean isStarted); /** * Tells the client that the synthesis has failed. Loading core/java/android/speech/tts/TextToSpeech.java +2 −2 Original line number Diff line number Diff line Loading @@ -2066,10 +2066,10 @@ public class TextToSpeech { private boolean mEstablished; private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() { public void onStop(String utteranceId) throws RemoteException { public void onStop(String utteranceId, boolean isStarted) throws RemoteException { UtteranceProgressListener listener = mUtteranceProgressListener; if (listener != null) { listener.onDone(utteranceId); listener.onStop(utteranceId, isStarted); } }; Loading core/java/android/speech/tts/TextToSpeechService.java +68 −11 Original line number Diff line number Diff line Loading @@ -455,10 +455,37 @@ public abstract class TextToSpeechService extends Service { private class SynthHandler extends Handler { private SpeechItem mCurrentSpeechItem = null; private ArrayList<Object> mFlushedObjects = new ArrayList<Object>(); private boolean mFlushAll; public SynthHandler(Looper looper) { super(looper); } private void startFlushingSpeechItems(Object callerIdentity) { synchronized (mFlushedObjects) { if (callerIdentity == null) { mFlushAll = true; } else { mFlushedObjects.add(callerIdentity); } } } private void endFlushingSpeechItems(Object callerIdentity) { synchronized (mFlushedObjects) { if (callerIdentity == null) { mFlushAll = false; } else { mFlushedObjects.remove(callerIdentity); } } } private boolean isFlushed(SpeechItem speechItem) { synchronized (mFlushedObjects) { return mFlushAll || mFlushedObjects.contains(speechItem.getCallerIdentity()); } } private synchronized SpeechItem getCurrentSpeechItem() { return mCurrentSpeechItem; } Loading Loading @@ -522,10 +549,14 @@ public abstract class TextToSpeechService extends Service { Runnable runnable = new Runnable() { @Override public void run() { if (isFlushed(speechItem)) { speechItem.stop(); } else { setCurrentSpeechItem(speechItem); speechItem.play(); setCurrentSpeechItem(null); } } }; Message msg = Message.obtain(this, runnable); Loading @@ -552,12 +583,14 @@ public abstract class TextToSpeechService extends Service { * * Called on a service binder thread. */ public int stopForApp(Object callerIdentity) { public int stopForApp(final Object callerIdentity) { if (callerIdentity == null) { return TextToSpeech.ERROR; } removeCallbacksAndMessages(callerIdentity); // Flush pending messages from callerIdentity startFlushingSpeechItems(callerIdentity); // This stops writing data to the file / or publishing // items to the audio playback handler. // Loading @@ -573,20 +606,39 @@ public abstract class TextToSpeechService extends Service { // Remove any enqueued audio too. mAudioPlaybackHandler.stopForApp(callerIdentity); // Stop flushing pending messages Runnable runnable = new Runnable() { @Override public void run() { endFlushingSpeechItems(callerIdentity); } }; sendMessage(Message.obtain(this, runnable)); return TextToSpeech.SUCCESS; } public int stopAll() { // Order to flush pending messages startFlushingSpeechItems(null); // Stop the current speech item unconditionally . SpeechItem current = setCurrentSpeechItem(null); if (current != null) { current.stop(); } // Remove all other items from the queue. removeCallbacksAndMessages(null); // Remove all pending playback as well. mAudioPlaybackHandler.stop(); // Message to stop flushing pending messages Runnable runnable = new Runnable() { @Override public void run() { endFlushingSpeechItems(null); } }; sendMessage(Message.obtain(this, runnable)); return TextToSpeech.SUCCESS; } } Loading Loading @@ -698,7 +750,6 @@ public abstract class TextToSpeechService extends Service { return mCallerIdentity; } public int getCallerUid() { return mCallerUid; } Loading Loading @@ -752,6 +803,10 @@ public abstract class TextToSpeechService extends Service { protected synchronized boolean isStopped() { return mStopped; } protected synchronized boolean isStarted() { return mStarted; } } /** Loading @@ -777,7 +832,7 @@ public abstract class TextToSpeechService extends Service { public void dispatchOnStop() { final String utteranceId = getUtteranceId(); if (utteranceId != null) { mCallbacks.dispatchOnStop(getCallerIdentity(), utteranceId); mCallbacks.dispatchOnStop(getCallerIdentity(), utteranceId, isStarted()); } } Loading Loading @@ -940,6 +995,8 @@ public abstract class TextToSpeechService extends Service { // turn implies that synthesis would not have started. synthesisCallback.stop(); TextToSpeechService.this.onStop(); } else { dispatchOnStop(); } } Loading Loading @@ -1345,11 +1402,11 @@ public abstract class TextToSpeechService extends Service { } } public void dispatchOnStop(Object callerIdentity, String utteranceId) { public void dispatchOnStop(Object callerIdentity, String utteranceId, boolean started) { ITextToSpeechCallback cb = getCallbackFor(callerIdentity); if (cb == null) return; try { cb.onStop(utteranceId); cb.onStop(utteranceId, started); } catch (RemoteException e) { Log.e(TAG, "Callback onStop failed: " + e); } Loading core/java/android/speech/tts/UtteranceProgressListener.java +19 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,20 @@ public abstract class UtteranceProgressListener { onError(utteranceId); } /** * Called when an utterance has been stopped while in progress or flushed from the * synthesis queue. This can happen if client calls {@link TextToSpeech#stop()} * or use {@link TextToSpeech#QUEUE_FLUSH} as an argument in * {@link TextToSpeech#speak} or {@link TextToSpeech#synthesizeToFile} methods. * * @param utteranceId the utterance ID of the utterance. * @param isStarted If true, then utterance was interrupted while being synthesized * and it's output is incomplete. If it's false, then utterance was flushed * before the synthesis started. */ public void onStop(String utteranceId, boolean isStarted) { } /** * Wraps an old deprecated OnUtteranceCompletedListener with a shiny new * progress listener. Loading @@ -83,6 +97,11 @@ public abstract class UtteranceProgressListener { // Left unimplemented, has no equivalent in the old // API. } @Override public void onStop(String utteranceId, boolean isStarted) { listener.onUtteranceCompleted(utteranceId); } }; } } Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -27752,6 +27752,7 @@ package android.speech.tts { method public abstract deprecated void onError(java.lang.String); method public void onError(java.lang.String, int); method public abstract void onStart(java.lang.String); method public void onStop(java.lang.String, boolean); } public class Voice implements android.os.Parcelable {
core/java/android/speech/tts/ITextToSpeechCallback.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ oneway interface ITextToSpeechCallback { * * @param utteranceId Unique id identifying synthesis request. */ void onStop(String utteranceId); void onStop(String utteranceId, boolean isStarted); /** * Tells the client that the synthesis has failed. Loading
core/java/android/speech/tts/TextToSpeech.java +2 −2 Original line number Diff line number Diff line Loading @@ -2066,10 +2066,10 @@ public class TextToSpeech { private boolean mEstablished; private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() { public void onStop(String utteranceId) throws RemoteException { public void onStop(String utteranceId, boolean isStarted) throws RemoteException { UtteranceProgressListener listener = mUtteranceProgressListener; if (listener != null) { listener.onDone(utteranceId); listener.onStop(utteranceId, isStarted); } }; Loading
core/java/android/speech/tts/TextToSpeechService.java +68 −11 Original line number Diff line number Diff line Loading @@ -455,10 +455,37 @@ public abstract class TextToSpeechService extends Service { private class SynthHandler extends Handler { private SpeechItem mCurrentSpeechItem = null; private ArrayList<Object> mFlushedObjects = new ArrayList<Object>(); private boolean mFlushAll; public SynthHandler(Looper looper) { super(looper); } private void startFlushingSpeechItems(Object callerIdentity) { synchronized (mFlushedObjects) { if (callerIdentity == null) { mFlushAll = true; } else { mFlushedObjects.add(callerIdentity); } } } private void endFlushingSpeechItems(Object callerIdentity) { synchronized (mFlushedObjects) { if (callerIdentity == null) { mFlushAll = false; } else { mFlushedObjects.remove(callerIdentity); } } } private boolean isFlushed(SpeechItem speechItem) { synchronized (mFlushedObjects) { return mFlushAll || mFlushedObjects.contains(speechItem.getCallerIdentity()); } } private synchronized SpeechItem getCurrentSpeechItem() { return mCurrentSpeechItem; } Loading Loading @@ -522,10 +549,14 @@ public abstract class TextToSpeechService extends Service { Runnable runnable = new Runnable() { @Override public void run() { if (isFlushed(speechItem)) { speechItem.stop(); } else { setCurrentSpeechItem(speechItem); speechItem.play(); setCurrentSpeechItem(null); } } }; Message msg = Message.obtain(this, runnable); Loading @@ -552,12 +583,14 @@ public abstract class TextToSpeechService extends Service { * * Called on a service binder thread. */ public int stopForApp(Object callerIdentity) { public int stopForApp(final Object callerIdentity) { if (callerIdentity == null) { return TextToSpeech.ERROR; } removeCallbacksAndMessages(callerIdentity); // Flush pending messages from callerIdentity startFlushingSpeechItems(callerIdentity); // This stops writing data to the file / or publishing // items to the audio playback handler. // Loading @@ -573,20 +606,39 @@ public abstract class TextToSpeechService extends Service { // Remove any enqueued audio too. mAudioPlaybackHandler.stopForApp(callerIdentity); // Stop flushing pending messages Runnable runnable = new Runnable() { @Override public void run() { endFlushingSpeechItems(callerIdentity); } }; sendMessage(Message.obtain(this, runnable)); return TextToSpeech.SUCCESS; } public int stopAll() { // Order to flush pending messages startFlushingSpeechItems(null); // Stop the current speech item unconditionally . SpeechItem current = setCurrentSpeechItem(null); if (current != null) { current.stop(); } // Remove all other items from the queue. removeCallbacksAndMessages(null); // Remove all pending playback as well. mAudioPlaybackHandler.stop(); // Message to stop flushing pending messages Runnable runnable = new Runnable() { @Override public void run() { endFlushingSpeechItems(null); } }; sendMessage(Message.obtain(this, runnable)); return TextToSpeech.SUCCESS; } } Loading Loading @@ -698,7 +750,6 @@ public abstract class TextToSpeechService extends Service { return mCallerIdentity; } public int getCallerUid() { return mCallerUid; } Loading Loading @@ -752,6 +803,10 @@ public abstract class TextToSpeechService extends Service { protected synchronized boolean isStopped() { return mStopped; } protected synchronized boolean isStarted() { return mStarted; } } /** Loading @@ -777,7 +832,7 @@ public abstract class TextToSpeechService extends Service { public void dispatchOnStop() { final String utteranceId = getUtteranceId(); if (utteranceId != null) { mCallbacks.dispatchOnStop(getCallerIdentity(), utteranceId); mCallbacks.dispatchOnStop(getCallerIdentity(), utteranceId, isStarted()); } } Loading Loading @@ -940,6 +995,8 @@ public abstract class TextToSpeechService extends Service { // turn implies that synthesis would not have started. synthesisCallback.stop(); TextToSpeechService.this.onStop(); } else { dispatchOnStop(); } } Loading Loading @@ -1345,11 +1402,11 @@ public abstract class TextToSpeechService extends Service { } } public void dispatchOnStop(Object callerIdentity, String utteranceId) { public void dispatchOnStop(Object callerIdentity, String utteranceId, boolean started) { ITextToSpeechCallback cb = getCallbackFor(callerIdentity); if (cb == null) return; try { cb.onStop(utteranceId); cb.onStop(utteranceId, started); } catch (RemoteException e) { Log.e(TAG, "Callback onStop failed: " + e); } Loading
core/java/android/speech/tts/UtteranceProgressListener.java +19 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,20 @@ public abstract class UtteranceProgressListener { onError(utteranceId); } /** * Called when an utterance has been stopped while in progress or flushed from the * synthesis queue. This can happen if client calls {@link TextToSpeech#stop()} * or use {@link TextToSpeech#QUEUE_FLUSH} as an argument in * {@link TextToSpeech#speak} or {@link TextToSpeech#synthesizeToFile} methods. * * @param utteranceId the utterance ID of the utterance. * @param isStarted If true, then utterance was interrupted while being synthesized * and it's output is incomplete. If it's false, then utterance was flushed * before the synthesis started. */ public void onStop(String utteranceId, boolean isStarted) { } /** * Wraps an old deprecated OnUtteranceCompletedListener with a shiny new * progress listener. Loading @@ -83,6 +97,11 @@ public abstract class UtteranceProgressListener { // Left unimplemented, has no equivalent in the old // API. } @Override public void onStop(String utteranceId, boolean isStarted) { listener.onUtteranceCompleted(utteranceId); } }; } }