Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78c9d0d2 authored by Charles Chen's avatar Charles Chen
Browse files

Adding Utterance ID to the TtsService.

parent 334b861e
Loading
Loading
Loading
Loading
+36 −0
Original line number Original line Diff line number Diff line
@@ -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&lt;java.lang.String, java.lang.String&gt;">
</parameter>
</method>
</method>
<method name="setLanguage"
<method name="setLanguage"
 return="int"
 return="int"
@@ -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"
@@ -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"
>
>
+2 −2
Original line number Original line Diff line number Diff line
@@ -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);
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -23,5 +23,5 @@ package android.speech.tts;
 * {@hide}
 * {@hide}
 */
 */
oneway interface ITtsCallback {
oneway interface ITtsCallback {
    void markReached(String mark);
    void utteranceCompleted(String utteranceId);
}
}
+73 −5
Original line number Original line Diff line number Diff line
@@ -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
     *
     *
@@ -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;
@@ -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);
@@ -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);
@@ -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);
@@ -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.
@@ -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)){
@@ -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;
            }
        }
    }

}
}
+43 −23
Original line number Original line Diff line number Diff line
@@ -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) {
@@ -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;
        }
        }


    }
    }
@@ -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;
@@ -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;
@@ -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);
                    }
                    }
                }
                }
@@ -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) {
@@ -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));
@@ -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();
                }
                }
            }
            }
@@ -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);
    }
    }
@@ -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;
@@ -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);
@@ -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;
        }
        }


        /**
        /**