1e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi/*
250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert * Copyright (C) 2009 The Android Open Source Project
3e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
4e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * use this file except in compliance with the License. You may obtain a copy of
6e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * the License at
7e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
8e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0
9e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
10e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
11e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * License for the specific language governing permissions and limitations under
14e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi * the License.
15e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi */
1621a6a6d26baf32593d63226f9728ddd66f0bd571Jean-Michel Trivipackage android.speech.tts;
1721a6a6d26baf32593d63226f9728ddd66f0bd571Jean-Michel Trivi
18ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Triviimport android.annotation.SdkConstant;
19ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Triviimport android.annotation.SdkConstant.SdkConstantType;
20e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.content.ComponentName;
2150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringertimport android.content.ContentResolver;
22e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.content.Context;
23e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.content.Intent;
24e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.content.ServiceConnection;
25672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniakimport android.media.AudioAttributes;
26a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Triviimport android.media.AudioManager;
2750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringertimport android.net.Uri;
288f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniakimport android.os.AsyncTask;
2950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringertimport android.os.Bundle;
30e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.os.IBinder;
315acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniakimport android.os.ParcelFileDescriptor;
32e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.os.RemoteException;
3350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringertimport android.provider.Settings;
3450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringertimport android.text.TextUtils;
35e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Triviimport android.util.Log;
36e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
375acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniakimport java.io.File;
385acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniakimport java.io.FileNotFoundException;
395acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniakimport java.io.IOException;
40ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniakimport java.util.ArrayList;
41748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamathimport java.util.Collections;
42a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Triviimport java.util.HashMap;
43748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamathimport java.util.HashSet;
4450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringertimport java.util.List;
45679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Triviimport java.util.Locale;
4650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringertimport java.util.Map;
47d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniakimport java.util.MissingResourceException;
48748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamathimport java.util.Set;
49a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi
50e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi/**
51e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi *
5262788e9b48f884a35b89c88911b581daa6a14e08Jean-Michel Trivi * Synthesizes speech from text for immediate playback or to create a sound file.
53a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi * <p>A TextToSpeech instance can only be used to synthesize text once it has completed its
54a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi * initialization. Implement the {@link TextToSpeech.OnInitListener} to be
55a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi * notified of the completion of the initialization.<br>
56a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi * When you are done using the TextToSpeech instance, call the {@link #shutdown()} method
57a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi * to release the native resources used by the TextToSpeech engine.
58e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi */
59a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivipublic class TextToSpeech {
60e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
612cad2cc15345d8623049a17712068e813d305a25Bjorn Bringert    private static final String TAG = "TextToSpeech";
622cad2cc15345d8623049a17712068e813d305a25Bjorn Bringert
6391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    /**
6491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * Denotes a successful operation.
6591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     */
6650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public static final int SUCCESS = 0;
6791bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    /**
6891bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * Denotes a generic operation failure.
6991bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     */
7050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public static final int ERROR = -1;
7191bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi
72679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    /**
73fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     * Denotes a stop requested by a client. It's used only on the service side of the API,
74fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     * client should never expect to see this result code.
75fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     */
76fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    public static final int STOPPED = -2;
77fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak
78fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    /**
79fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     * Denotes a failure of a TTS engine to synthesize the given input.
80fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     */
81fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    public static final int ERROR_SYNTHESIS = -3;
82fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak
83fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    /**
84fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     * Denotes a failure of a TTS service.
85fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     */
86fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    public static final int ERROR_SERVICE = -4;
87fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak
88fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    /**
89fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     * Denotes a failure related to the output (audio device or a file).
90fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     */
91fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    public static final int ERROR_OUTPUT = -5;
92fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak
93fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    /**
94fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     * Denotes a failure caused by a network connectivity problems.
95fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     */
96fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    public static final int ERROR_NETWORK = -6;
97fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak
98fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    /**
99fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     * Denotes a failure caused by network timeout.
100fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     */
101fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    public static final int ERROR_NETWORK_TIMEOUT = -7;
102fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak
103fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    /**
104fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     * Denotes a failure caused by an invalid request.
105fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak     */
106fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    public static final int ERROR_INVALID_REQUEST = -8;
107fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak
108fc4b2890378eb1b6e0b11d60d703eb6854268064Przemyslaw Szczepaniak    /**
109ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * Denotes a failure caused by an unfinished download of the voice data.
110ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @see Engine#KEY_FEATURE_NOT_INSTALLED
111ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     */
112ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    public static final int ERROR_NOT_INSTALLED_YET = -9;
113ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
114ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    /**
115679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Queue mode where all entries in the playback queue (media to be played
116679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * and text to be synthesized) are dropped and replaced by the new entry.
117abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath     * Queues are flushed with respect to a given calling app. Entries in the queue
118abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath     * from other callees are not discarded.
119679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     */
120ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    public static final int QUEUE_FLUSH = 0;
121679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi    /**
122679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * Queue mode where the new entry is added at the end of the playback queue.
123679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     */
124ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    public static final int QUEUE_ADD = 1;
125abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath    /**
126abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath     * Queue mode where the entire playback queue is purged. This is different
127abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath     * from {@link #QUEUE_FLUSH} in that all entries are purged, not just entries
128abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath     * from a given caller.
129abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath     *
130abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath     * @hide
131abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath     */
132abc63fbddab2477a2954bc804aba2826e1f11084Narayan Kamath    static final int QUEUE_DESTROY = 2;
133e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
134aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
1359f5eadd2eed8b95c077a15d9e3e3c66fd151c215Jean-Michel Trivi     * Denotes the language is available exactly as specified by the locale.
136aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
137ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    public static final int LANG_COUNTRY_VAR_AVAILABLE = 2;
138aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
139aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
140b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     * Denotes the language is available for the language and country specified
141aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * by the locale, but not the variant.
142aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
143ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    public static final int LANG_COUNTRY_AVAILABLE = 1;
144aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
145aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
146b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     * Denotes the language is available for the language by the locale,
147aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * but not the country and variant.
148aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
149ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    public static final int LANG_AVAILABLE = 0;
150aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
151aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
152aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     * Denotes the language data is missing.
153aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
154ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    public static final int LANG_MISSING_DATA = -1;
155aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
156aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
157a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * Denotes the language is not supported.
158aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
159ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    public static final int LANG_NOT_SUPPORTED = -2;
160ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi
161ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    /**
162ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     * Broadcast Action: The TextToSpeech synthesizer has completed processing
163ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     * of all the text in the speech queue.
164c34f76fe89b5a31d01d63067c2f24b9a6a76df18Narayan Kamath     *
165c34f76fe89b5a31d01d63067c2f24b9a6a76df18Narayan Kamath     * Note that this notifies callers when the <b>engine</b> has finished has
166c34f76fe89b5a31d01d63067c2f24b9a6a76df18Narayan Kamath     * processing text data. Audio playback might not have completed (or even started)
167c34f76fe89b5a31d01d63067c2f24b9a6a76df18Narayan Kamath     * at this point. If you wish to be notified when this happens, see
168c34f76fe89b5a31d01d63067c2f24b9a6a76df18Narayan Kamath     * {@link OnUtteranceCompletedListener}.
169ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     */
170ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
171ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi    public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED =
172ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi            "android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED";
173aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
174e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
175a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * Interface definition of a callback to be invoked indicating the completion of the
176a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * TextToSpeech engine initialization.
177e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
178e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public interface OnInitListener {
179a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi        /**
180a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * Called to signal the completion of the TextToSpeech engine initialization.
18150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         *
182a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * @param status {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
183a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         */
18491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        public void onInit(int status);
185e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
186e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
187e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
18850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * Listener that will be called when the TTS service has
18950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * completed synthesizing an utterance. This is only called if the utterance
19050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * has an utterance ID (see {@link TextToSpeech.Engine#KEY_PARAM_UTTERANCE_ID}).
191647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak     *
192647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak     * @deprecated Use {@link UtteranceProgressListener} instead.
19378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     */
194647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak    @Deprecated
195a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi    public interface OnUtteranceCompletedListener {
196a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi        /**
19750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Called when an utterance has been synthesized.
19850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         *
199a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * @param utteranceId the identifier of the utterance.
20060dd360640a400d9b4a602160733281d284aaee5Charles Chen         */
20160dd360640a400d9b4a602160733281d284aaee5Charles Chen        public void onUtteranceCompleted(String utteranceId);
20278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    }
20378c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen
20478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    /**
205748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * Constants and parameter names for controlling text-to-speech. These include:
206748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *
207748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * <ul>
208748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *     <li>
209748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *         Intents to ask engine to install data or check its data and
210748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *         extras for a TTS engine's check data activity.
211748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *     </li>
212748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *     <li>
213748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *         Keys for the parameters passed with speak commands, e.g.
214748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *         {@link Engine#KEY_PARAM_UTTERANCE_ID}, {@link Engine#KEY_PARAM_STREAM}.
215748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *     </li>
216748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *     <li>
217748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *         A list of feature strings that engines might support, e.g
218748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *         {@link Engine#KEY_FEATURE_NETWORK_SYNTHESIS}). These values may be passed in to
219748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *         {@link TextToSpeech#speak} and {@link TextToSpeech#synthesizeToFile} to modify
220748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *         engine behaviour. The engine can be queried for the set of features it supports
221748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *         through {@link TextToSpeech#getFeatures(java.util.Locale)}.
222748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *     </li>
223748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * </ul>
224d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi     */
225d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi    public class Engine {
22650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
22762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
22850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Default speech rate.
22950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
23062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
23150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public static final int DEFAULT_RATE = 100;
23250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
23362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
23450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Default pitch.
23550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
23662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
23750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public static final int DEFAULT_PITCH = 100;
23850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
23962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
24050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Default volume.
24150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
24262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
2439d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi        public static final float DEFAULT_VOLUME = 1.0f;
24450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
2459d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi        /**
24650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Default pan (centered).
24750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
2489d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         */
2499d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi        public static final float DEFAULT_PAN = 0.0f;
2509d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi
2519d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi        /**
25250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Default value for {@link Settings.Secure#TTS_USE_DEFAULTS}.
25350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
2549d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         */
255ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final int USE_DEFAULTS = 0; // false
25650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
25762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
25850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Package name of the default TTS engine.
25950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         *
26050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
26122302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         * @deprecated No longer in use, the default engine is determined by
262b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath         *         the sort order defined in {@link TtsEngines}. Note that
26322302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         *         this doesn't "break" anything because there is no guarantee that
26422302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         *         the engine specified below is installed on a given build, let
26522302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         *         alone be the default.
26662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
26722302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath        @Deprecated
26850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public static final String DEFAULT_ENGINE = "com.svox.pico";
269d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi
270a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi        /**
271a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * Default audio stream used when playing synthesized speech.
272a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         */
273ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final int DEFAULT_STREAM = AudioManager.STREAM_MUSIC;
274a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi
27562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
27662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates success when checking the installation status of the resources used by the
277a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
27862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
279d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_PASS = 1;
28050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
28162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
28262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates failure when checking the installation status of the resources used by the
283a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
28462253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
285d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_FAIL = 0;
28650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
28762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
28862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates erroneous data when checking the installation status of the resources used by
289a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
290647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
291647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @deprecated Use CHECK_VOICE_DATA_FAIL instead.
29262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
293647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        @Deprecated
294d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_BAD_DATA = -1;
29550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
29662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
29762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates missing resources when checking the installation status of the resources used
298a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * by the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
299647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
300647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @deprecated Use CHECK_VOICE_DATA_FAIL instead.
30162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
302647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        @Deprecated
303d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_MISSING_DATA = -2;
30450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
30562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
30662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Indicates missing storage volume when checking the installation status of the resources
307a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * used by the TextToSpeech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
308647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
309647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @deprecated Use CHECK_VOICE_DATA_FAIL instead.
31062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
311647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        @Deprecated
31262253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3;
31399a0feecd0f0aad314d7a4637d329b8a9e8c1150Charles Chen
31450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        /**
31550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Intent for starting a TTS service. Services that handle this intent must
31650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * extend {@link TextToSpeechService}. Normal applications should not use this intent
31750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * directly, instead they should talk to the TTS service using the the methods in this
31850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * class.
31950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         */
32050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        @SdkConstant(SdkConstantType.SERVICE_ACTION)
32150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public static final String INTENT_ACTION_TTS_SERVICE =
32250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                "android.intent.action.TTS_SERVICE";
32350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
3244d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath        /**
3254d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath         * Name under which a text to speech engine publishes information about itself.
3264d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath         * This meta-data should reference an XML resource containing a
3274d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath         * <code>&lt;{@link android.R.styleable#TextToSpeechEngine tts-engine}&gt;</code>
3284d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath         * tag.
3294d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath         */
3304d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath        public static final String SERVICE_META_DATA = "android.speech.tts";
3314d03462b374dfc080f0c7c78d458c102a26be5c6Narayan Kamath
332ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        // intents to ask engine to install data or check its data
333ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        /**
334a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * Activity Action: Triggers the platform TextToSpeech engine to
335ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * start the activity that installs the resource files on the device
336ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * that are required for TTS to be operational. Since the installation
337ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * of the data can be interrupted or declined by the user, the application
338ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * shouldn't expect successful installation upon return from that intent,
339ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * and if need be, should check installation status with
340ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * {@link #ACTION_CHECK_TTS_DATA}.
341ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         */
3429f5eadd2eed8b95c077a15d9e3e3c66fd151c215Jean-Michel Trivi        @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
343ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final String ACTION_INSTALL_TTS_DATA =
344ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi                "android.speech.tts.engine.INSTALL_TTS_DATA";
345ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi
346ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        /**
347647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Broadcast Action: broadcast to signal the change in the list of available
348647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * languages or/and their features.
34977a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi         */
35077a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi        @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
35177a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi        public static final String ACTION_TTS_DATA_INSTALLED =
35277a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi                "android.speech.tts.engine.TTS_DATA_INSTALLED";
35350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
35477a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi        /**
355a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * Activity Action: Starts the activity from the platform TextToSpeech
356ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * engine to verify the proper installation and availability of the
357ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * resource files on the system. Upon completion, the activity will
358ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * return one of the following codes:
359ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * {@link #CHECK_VOICE_DATA_PASS},
360ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * {@link #CHECK_VOICE_DATA_FAIL},
361ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * <p> Moreover, the data received in the activity result will contain the following
362ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * fields:
363ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * <ul>
364647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   <li>{@link #EXTRA_AVAILABLE_VOICES} which contains an ArrayList<String> of all the
365647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   available voices. The format of each voice is: lang-COUNTRY-variant where COUNTRY and
366647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   variant are optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE").</li>
367647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   <li>{@link #EXTRA_UNAVAILABLE_VOICES} which contains an ArrayList<String> of all the
368647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   unavailable voices (ones that user can install). The format of each voice is:
369647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   lang-COUNTRY-variant where COUNTRY and variant are optional (ie, "eng" or
370647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   "eng-USA" or "eng-USA-FEMALE").</li>
371ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         * </ul>
372ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi         */
3739f5eadd2eed8b95c077a15d9e3e3c66fd151c215Jean-Michel Trivi        @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
374ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final String ACTION_CHECK_TTS_DATA =
375ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi                "android.speech.tts.engine.CHECK_TTS_DATA";
376ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi
37750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        /**
378647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Activity intent for getting some sample text to use for demonstrating TTS. Specific
379647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * locale have to be requested by passing following extra parameters:
380647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * <ul>
381647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   <li>language</li>
382647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   <li>country</li>
383647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   <li>variant</li>
384647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * </ul>
38550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         *
386647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Upon completion, the activity result may contain the following fields:
387647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * <ul>
388647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *   <li>{@link #EXTRA_SAMPLE_TEXT} which contains an String with sample text.</li>
389647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * </ul>
39050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         */
39150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
39250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public static final String ACTION_GET_SAMPLE_TEXT =
39350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                "android.speech.tts.engine.GET_SAMPLE_TEXT";
39450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
39562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
396647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Extra information received with the {@link #ACTION_GET_SAMPLE_TEXT} intent result where
397647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * the TextToSpeech engine returns an String with sample text for requested voice
39862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
399647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        public static final String EXTRA_SAMPLE_TEXT = "sampleText";
40050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
40150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
402647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        // extras for a TTS engine's check data activity
40376d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen        /**
404647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent result where
40576d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * the TextToSpeech engine returns an ArrayList<String> of all the available voices.
40676d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are
40776d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE").
40876d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         */
40976d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen        public static final String EXTRA_AVAILABLE_VOICES = "availableVoices";
41050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
41176d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen        /**
412647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent result where
41376d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * the TextToSpeech engine returns an ArrayList<String> of all the unavailable voices.
41476d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are
41576d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE").
41676d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         */
41776d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen        public static final String EXTRA_UNAVAILABLE_VOICES = "unavailableVoices";
41850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
41976d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen        /**
420647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent result where
421647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * the TextToSpeech engine specifies the path to its resources.
422647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
423647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * It may be used by language packages to find out where to put their data.
424647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
425647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @deprecated TTS engine implementation detail, this information has no use for
426647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * text-to-speech API client.
427647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         */
428647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        @Deprecated
429647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        public static final String EXTRA_VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
430647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak
431647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        /**
432647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent result where
433647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * the TextToSpeech engine specifies the file names of its resources under the
434647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * resource path.
435647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
436647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @deprecated TTS engine implementation detail, this information has no use for
437647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * text-to-speech API client.
438647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         */
439647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        @Deprecated
440647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        public static final String EXTRA_VOICE_DATA_FILES = "dataFiles";
441647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak
442647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        /**
443647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent result where
444647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * the TextToSpeech engine specifies the locale associated with each resource file.
445647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
446647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @deprecated TTS engine implementation detail, this information has no use for
447647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * text-to-speech API client.
448647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         */
449647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        @Deprecated
450647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        public static final String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo";
451647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak
452647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        /**
45376d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * Extra information sent with the {@link #ACTION_CHECK_TTS_DATA} intent where the
45476d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * caller indicates to the TextToSpeech engine which specific sets of voice data to
45576d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * check for by sending an ArrayList<String> of the voices that are of interest.
45676d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are
45776d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE").
458647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
459647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @deprecated Redundant functionality, checking for existence of specific sets of voice
460647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * data can be done on client side.
46176d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen         */
462647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        @Deprecated
46376d9c3cb4f6f8c027959d2951e35a8b37762a1f3Charles Chen        public static final String EXTRA_CHECK_VOICE_DATA_FOR = "checkVoiceDataFor";
46499a0feecd0f0aad314d7a4637d329b8a9e8c1150Charles Chen
46577a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi        // extras for a TTS engine's data installation
46677a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi        /**
467647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * Extra information received with the {@link #ACTION_TTS_DATA_INSTALLED} intent result.
4689f5eadd2eed8b95c077a15d9e3e3c66fd151c215Jean-Michel Trivi         * It indicates whether the data files for the synthesis engine were successfully
4699f5eadd2eed8b95c077a15d9e3e3c66fd151c215Jean-Michel Trivi         * installed. The installation was initiated with the  {@link #ACTION_INSTALL_TTS_DATA}
4709f5eadd2eed8b95c077a15d9e3e3c66fd151c215Jean-Michel Trivi         * intent. The possible values for this extra are
4719f5eadd2eed8b95c077a15d9e3e3c66fd151c215Jean-Michel Trivi         * {@link TextToSpeech#SUCCESS} and {@link TextToSpeech#ERROR}.
472647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
473647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @deprecated No longer in use. If client ise interested in information about what
474647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * changed, is should send ACTION_CHECK_TTS_DATA intent to discover available voices.
47577a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi         */
476647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak        @Deprecated
47777a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi        public static final String EXTRA_TTS_DATA_INSTALLED = "dataInstalled";
47877a5d39343760d9950ca15a87db0ae778afb4f2bJean-Michel Trivi
47962253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        // keys for the parameters passed with speak commands. Hidden keys are used internally
48062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        // to maintain engine state for each TextToSpeech instance.
48162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
48250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
48362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
484ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final String KEY_PARAM_RATE = "rate";
48550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
48662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
48750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
48862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
489ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        public static final String KEY_PARAM_VOICE_NAME = "voiceName";
490ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
491ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        /**
492ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * @hide
493ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         */
494ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final String KEY_PARAM_LANGUAGE = "language";
49550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
49662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
49750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
49862253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
499ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final String KEY_PARAM_COUNTRY = "country";
50050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
50162253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
50250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
50362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
504ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final String KEY_PARAM_VARIANT = "variant";
50550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
50662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
50750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
50860dd360640a400d9b4a602160733281d284aaee5Charles Chen         */
50960dd360640a400d9b4a602160733281d284aaee5Charles Chen        public static final String KEY_PARAM_ENGINE = "engine";
51050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
51160dd360640a400d9b4a602160733281d284aaee5Charles Chen        /**
51250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * @hide
5131a2712ce2a18eba6809d984d2f7443fbdccaa7edCharles Chen         */
5141a2712ce2a18eba6809d984d2f7443fbdccaa7edCharles Chen        public static final String KEY_PARAM_PITCH = "pitch";
51550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
5161a2712ce2a18eba6809d984d2f7443fbdccaa7edCharles Chen        /**
51762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * Parameter key to specify the audio stream type to be used when speaking text
51850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * or playing back a file. The value should be one of the STREAM_ constants
51950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * defined in {@link AudioManager}.
52050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         *
521a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * @see TextToSpeech#speak(String, int, HashMap)
522a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * @see TextToSpeech#playEarcon(String, int, HashMap)
52362253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
524ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final String KEY_PARAM_STREAM = "streamType";
52550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
52662253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi        /**
527672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak         * Parameter key to specify the audio attributes to be used when
528672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak         * speaking text or playing back a file. The value should be set
529672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak         * using {@link TextToSpeech#setAudioAttributes(AudioAttributes)}.
530672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak         *
531672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak         * @see TextToSpeech#speak(String, int, HashMap)
532672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak         * @see TextToSpeech#playEarcon(String, int, HashMap)
533672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak         * @hide
534672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak         */
535672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak        public static final String KEY_PARAM_AUDIO_ATTRIBUTES = "audioAttributes";
536672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak
537672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak        /**
538a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * Parameter key to identify an utterance in the
539a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * {@link TextToSpeech.OnUtteranceCompletedListener} after text has been
54062253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         * spoken, a file has been played back or a silence duration has elapsed.
54150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         *
542a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * @see TextToSpeech#speak(String, int, HashMap)
543a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * @see TextToSpeech#playEarcon(String, int, HashMap)
544a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi         * @see TextToSpeech#synthesizeToFile(String, HashMap, String)
54562253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi         */
546ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi        public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId";
54750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
5489d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi        /**
5499d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         * Parameter key to specify the speech volume relative to the current stream type
5509d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         * volume used when speaking text. Volume is specified as a float ranging from 0 to 1
5519011ec832d78982d017b1cef55a54af44ba2a447Jean-Michel Trivi         * where 0 is silence, and 1 is the maximum volume (the default behavior).
55250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         *
5539d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         * @see TextToSpeech#speak(String, int, HashMap)
5549d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         * @see TextToSpeech#playEarcon(String, int, HashMap)
5559d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         */
5569d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi        public static final String KEY_PARAM_VOLUME = "volume";
55750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
5589d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi        /**
5599d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         * Parameter key to specify how the speech is panned from left to right when speaking text.
5609d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         * Pan is specified as a float ranging from -1 to +1 where -1 maps to a hard-left pan,
5619011ec832d78982d017b1cef55a54af44ba2a447Jean-Michel Trivi         * 0 to center (the default behavior), and +1 to hard-right.
56250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         *
5639d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         * @see TextToSpeech#speak(String, int, HashMap)
5649d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         * @see TextToSpeech#playEarcon(String, int, HashMap)
5659d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi         */
5669d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi        public static final String KEY_PARAM_PAN = "pan";
56762253a319d6359ce71c547d0b0aa36ba17789ab4Jean-Michel Trivi
568748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath        /**
569748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * Feature key for network synthesis. See {@link TextToSpeech#getFeatures(Locale)}
570748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * for a description of how feature keys work. If set (and supported by the engine
571748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * as per {@link TextToSpeech#getFeatures(Locale)}, the engine must
572748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * use network based synthesis.
573748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         *
574748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * @see TextToSpeech#speak(String, int, java.util.HashMap)
575748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * @see TextToSpeech#synthesizeToFile(String, java.util.HashMap, String)
576748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * @see TextToSpeech#getFeatures(java.util.Locale)
577ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         *
5786ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak         * @deprecated Starting from API level 21, to select network synthesis, call
579ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * ({@link TextToSpeech#getVoices()}, find a suitable network voice
58035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak         * ({@link Voice#isNetworkConnectionRequired()}) and pass it
581ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * to {@link TextToSpeech#setVoice(Voice)}).
582748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         */
583ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        @Deprecated
584748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath        public static final String KEY_FEATURE_NETWORK_SYNTHESIS = "networkTts";
585748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath
586748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath        /**
587748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * Feature key for embedded synthesis. See {@link TextToSpeech#getFeatures(Locale)}
588748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * for a description of how feature keys work. If set and supported by the engine
589748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * as per {@link TextToSpeech#getFeatures(Locale)}, the engine must synthesize
590748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         * text on-device (without making network requests).
591647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         *
592647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @see TextToSpeech#speak(String, int, java.util.HashMap)
593647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @see TextToSpeech#synthesizeToFile(String, java.util.HashMap, String)
594647abce570f3afdd667e06e9ad71738efff0e8a8Przemyslaw Szczepaniak         * @see TextToSpeech#getFeatures(java.util.Locale)
595ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
5966ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak         * @deprecated Starting from API level 21, to select embedded synthesis, call
597ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * ({@link TextToSpeech#getVoices()}, find a suitable embedded voice
59835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak         * ({@link Voice#isNetworkConnectionRequired()}) and pass it
599ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * to {@link TextToSpeech#setVoice(Voice)}).
600748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath         */
601ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        @Deprecated
602748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath        public static final String KEY_FEATURE_EMBEDDED_SYNTHESIS = "embeddedTts";
6035cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak
6045cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak        /**
6055cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak         * Parameter key to specify an audio session identifier (obtained from
606289cc8e887f786f557faab226a1e01abb9a632a6Jean-Michel Trivi         * {@link AudioManager#generateAudioSessionId()}) that will be used by the request audio
6075cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak         * output. It can be used to associate one of the {@link android.media.audiofx.AudioEffect}
6085cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak         * objects with the synthesis (or earcon) output.
6095cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak         *
6105cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak         * @see TextToSpeech#speak(String, int, HashMap)
6115cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak         * @see TextToSpeech#playEarcon(String, int, HashMap)
6125cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak         */
6135cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak        public static final String KEY_PARAM_SESSION_ID = "sessionId";
614ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
615ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        /**
616ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * Feature key that indicates that the voice may need to download additional data to be fully
617ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * functional. The download will be triggered by calling
618ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * {@link TextToSpeech#setVoice(Voice)} or {@link TextToSpeech#setLanguage(Locale)}.
619ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * Until download is complete, each synthesis request will either report
620ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * {@link TextToSpeech#ERROR_NOT_INSTALLED_YET} error, or use a different voice to synthesize
621ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * the request. This feature should NOT be used as a key of a request parameter.
622ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         *
623ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * @see TextToSpeech#getFeatures(java.util.Locale)
624ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * @see Voice#getFeatures()
625ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         */
626ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        public static final String KEY_FEATURE_NOT_INSTALLED = "notInstalled";
627ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
628ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        /**
629ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * Feature key that indicate that a network timeout can be set for the request. If set and
630ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * supported as per {@link TextToSpeech#getFeatures(Locale)} or {@link Voice#getFeatures()},
631ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * it can be used as request parameter to set the maximum allowed time for a single
632ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * request attempt, in milliseconds, before synthesis fails. When used as a key of
633ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * a request parameter, its value should be a string with an integer value.
634ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         *
635ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * @see TextToSpeech#getFeatures(java.util.Locale)
636ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * @see Voice#getFeatures()
637ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         */
638ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        public static final String KEY_FEATURE_NETWORK_TIMEOUT_MS = "networkTimeoutMs";
639ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
640ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        /**
641ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * Feature key that indicates that network request retries count can be set for the request.
642ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * If set and supported as per {@link TextToSpeech#getFeatures(Locale)} or
643ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * {@link Voice#getFeatures()}, it can be used as a request parameter to set the
644ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * number of network request retries that are attempted in case of failure. When used as
645ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * a key of a request parameter, its value should be a string with an integer value.
646ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         *
647ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * @see TextToSpeech#getFeatures(java.util.Locale)
648ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         * @see Voice#getFeatures()
649ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak         */
650ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        public static final String KEY_FEATURE_NETWORK_RETRIES_COUNT = "networkRetriesCount";
651d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi    }
652d146874d7341bc9602c93719582b4209e7b81f01Jean-Michel Trivi
65350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private final Context mContext;
6549c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak    private Connection mConnectingServiceConnection;
65550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private Connection mServiceConnection;
65650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private OnInitListener mInitListener;
657a57f23837ad172c1b046d5e9cc8eb3d2e41a69f4Narayan Kamath    // Written from an unspecified application thread, read from
658a57f23837ad172c1b046d5e9cc8eb3d2e41a69f4Narayan Kamath    // a binder thread.
659754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath    private volatile UtteranceProgressListener mUtteranceProgressListener;
66091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    private final Object mStartLock = new Object();
66150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
66250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private String mRequestedEngine;
663c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath    // Whether to initialize this TTS object with the default engine,
664c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath    // if the requested engine is not available. Valid only if mRequestedEngine
665c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath    // is not null. Used only for testing, though potentially useful API wise
666c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath    // too.
667c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath    private final boolean mUseFallback;
66850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private final Map<String, Uri> mEarcons;
669df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    private final Map<CharSequence, Uri> mUtterances;
67050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private final Bundle mParams = new Bundle();
671d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath    private final TtsEngines mEnginesHelper;
672bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath    private volatile String mCurrentEngine = null;
673e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
674e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
6754bbca889df9ca76c398f3a11e871fc6ad4a4514dBjorn Bringert     * The constructor for the TextToSpeech class, using the default TTS engine.
676a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * This will also initialize the associated TextToSpeech engine if it isn't already running.
677e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
678e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param context
679a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            The context this instance is running in.
68091bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi     * @param listener
681a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            The {@link TextToSpeech.OnInitListener} that will be called when the
682e86a936afddaa823d8454c09ed43c2d864ac77ebPrzemyslaw Szczepaniak     *            TextToSpeech engine has initialized. In a case of a failure the listener
683e86a936afddaa823d8454c09ed43c2d864ac77ebPrzemyslaw Szczepaniak     *            may be called immediately, before TextToSpeech instance is fully constructed.
684e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
68591bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi    public TextToSpeech(Context context, OnInitListener listener) {
68650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        this(context, listener, null);
68750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
68850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
68950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    /**
6904bbca889df9ca76c398f3a11e871fc6ad4a4514dBjorn Bringert     * The constructor for the TextToSpeech class, using the given TTS engine.
6914bbca889df9ca76c398f3a11e871fc6ad4a4514dBjorn Bringert     * This will also initialize the associated TextToSpeech engine if it isn't already running.
6924bbca889df9ca76c398f3a11e871fc6ad4a4514dBjorn Bringert     *
6934bbca889df9ca76c398f3a11e871fc6ad4a4514dBjorn Bringert     * @param context
6944bbca889df9ca76c398f3a11e871fc6ad4a4514dBjorn Bringert     *            The context this instance is running in.
6954bbca889df9ca76c398f3a11e871fc6ad4a4514dBjorn Bringert     * @param listener
6964bbca889df9ca76c398f3a11e871fc6ad4a4514dBjorn Bringert     *            The {@link TextToSpeech.OnInitListener} that will be called when the
697e86a936afddaa823d8454c09ed43c2d864ac77ebPrzemyslaw Szczepaniak     *            TextToSpeech engine has initialized. In a case of a failure the listener
698e86a936afddaa823d8454c09ed43c2d864ac77ebPrzemyslaw Szczepaniak     *            may be called immediately, before TextToSpeech instance is fully constructed.
6994bbca889df9ca76c398f3a11e871fc6ad4a4514dBjorn Bringert     * @param engine Package name of the TTS engine to use.
70050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     */
70150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public TextToSpeech(Context context, OnInitListener listener, String engine) {
702c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath        this(context, listener, engine, null, true);
70368e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath    }
70468e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath
70568e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath    /**
70668e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath     * Used by the framework to instantiate TextToSpeech objects with a supplied
70768e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath     * package name, instead of using {@link android.content.Context#getPackageName()}
70868e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath     *
70968e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath     * @hide
71068e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath     */
71168e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath    public TextToSpeech(Context context, OnInitListener listener, String engine,
712c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath            String packageName, boolean useFallback) {
71391bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        mContext = context;
71491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        mInitListener = listener;
71550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        mRequestedEngine = engine;
716c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath        mUseFallback = useFallback;
71787c9684fd0fa31fd6ad7f7e9f4cfedddc4fdc4b0Jean-Michel Trivi
71850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        mEarcons = new HashMap<String, Uri>();
719df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts        mUtterances = new HashMap<CharSequence, Uri>();
72068e2af55d65d2e61fbf8096eccaa2e4ca02b6c5aNarayan Kamath        mUtteranceProgressListener = null;
721a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi
722d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        mEnginesHelper = new TtsEngines(mContext);
723da7681e7b61dd450be72f2b4a80e6d1c86342e05Jean-Michel Trivi        initTts();
724e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
725e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
7269c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak    private <R> R runActionNoReconnect(Action<R> action, R errorResult, String method,
7279c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak            boolean onlyEstablishedConnection) {
7289c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        return runAction(action, errorResult, method, false, onlyEstablishedConnection);
72950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
73050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
73150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private <R> R runAction(Action<R> action, R errorResult, String method) {
7329c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        return runAction(action, errorResult, method, true, true);
73350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
73450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
7359c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak    private <R> R runAction(Action<R> action, R errorResult, String method,
7369c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak            boolean reconnect, boolean onlyEstablishedConnection) {
73750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        synchronized (mStartLock) {
73850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            if (mServiceConnection == null) {
73950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                Log.w(TAG, method + " failed: not bound to TTS engine");
74050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                return errorResult;
741e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
7429c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak            return mServiceConnection.runAction(action, errorResult, method, reconnect,
7439c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                    onlyEstablishedConnection);
74450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
74550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
746e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
74750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private int initTts() {
748b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        // Step 1: Try connecting to the engine that was requested.
749c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath        if (mRequestedEngine != null) {
750c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath            if (mEnginesHelper.isEngineInstalled(mRequestedEngine)) {
751c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                if (connectToEngine(mRequestedEngine)) {
752c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                    mCurrentEngine = mRequestedEngine;
753c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                    return SUCCESS;
754c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                } else if (!mUseFallback) {
755c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                    mCurrentEngine = null;
756c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                    dispatchOnInit(ERROR);
757c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                    return ERROR;
758c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                }
759c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath            } else if (!mUseFallback) {
760c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                Log.i(TAG, "Requested engine not installed: " + mRequestedEngine);
761c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                mCurrentEngine = null;
762c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                dispatchOnInit(ERROR);
763c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath                return ERROR;
764b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath            }
76550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
76650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
767b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        // Step 2: Try connecting to the user's default engine.
768b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        final String defaultEngine = getDefaultEngine();
769b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        if (defaultEngine != null && !defaultEngine.equals(mRequestedEngine)) {
77050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            if (connectToEngine(defaultEngine)) {
771b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath                mCurrentEngine = defaultEngine;
77250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                return SUCCESS;
773e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
77450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
775e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
776b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        // Step 3: Try connecting to the highest ranked engine in the
777b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        // system.
778d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        final String highestRanked = mEnginesHelper.getHighestRankedEngineName();
779b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        if (highestRanked != null && !highestRanked.equals(mRequestedEngine) &&
780b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath                !highestRanked.equals(defaultEngine)) {
78122302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath            if (connectToEngine(highestRanked)) {
782b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath                mCurrentEngine = highestRanked;
78350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                return SUCCESS;
7841e13a02320aa165c22172d43b2b3c3cd8ad35cf7Jean-Michel Trivi            }
78550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
78650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
787b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        // NOTE: The API currently does not allow the caller to query whether
788b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        // they are actually connected to any engine. This might fail for various
789b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        // reasons like if the user disables all her TTS engines.
790b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath
791b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath        mCurrentEngine = null;
7920e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath        dispatchOnInit(ERROR);
79350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return ERROR;
79450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
79550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
79650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private boolean connectToEngine(String engine) {
79750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        Connection connection = new Connection();
79850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        Intent intent = new Intent(Engine.INTENT_ACTION_TTS_SERVICE);
79950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        intent.setPackage(engine);
80050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        boolean bound = mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
80150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        if (!bound) {
80250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            Log.e(TAG, "Failed to bind to " + engine);
80350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            return false;
8041e13a02320aa165c22172d43b2b3c3cd8ad35cf7Jean-Michel Trivi        } else {
8050e20fe5bab7dc3aff488d133961acfe0239f5240Narayan Kamath            Log.i(TAG, "Sucessfully bound to " + engine);
8069c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak            mConnectingServiceConnection = connection;
80750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            return true;
8081e13a02320aa165c22172d43b2b3c3cd8ad35cf7Jean-Michel Trivi        }
809e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
810e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
81150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private void dispatchOnInit(int result) {
81250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        synchronized (mStartLock) {
81350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            if (mInitListener != null) {
81450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                mInitListener.onInit(result);
81550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                mInitListener = null;
81650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            }
81750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
81850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
819e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
820492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath    private IBinder getCallerIdentity() {
821492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath        return mServiceConnection.getCallerIdentity();
822492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath    }
823492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath
824e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
825a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * Releases the resources used by the TextToSpeech engine.
826a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * It is good practice for instance to call this method in the onDestroy() method of an Activity
827a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * so the TextToSpeech engine can be cleanly stopped.
828e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
829e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public void shutdown() {
8309c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        // Special case, we are asked to shutdown connection that did finalize its connection.
8319c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        synchronized (mStartLock) {
8329c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak            if (mConnectingServiceConnection != null) {
8339c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                mContext.unbindService(mConnectingServiceConnection);
8349c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                mConnectingServiceConnection = null;
8359c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                return;
8369c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak            }
8379c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        }
8389c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak
8399c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        // Post connection case
84050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        runActionNoReconnect(new Action<Void>() {
84150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
84250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            public Void run(ITextToSpeechService service) throws RemoteException {
843492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath                service.setCallback(getCallerIdentity(), null);
844492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath                service.stop(getCallerIdentity());
84550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                mServiceConnection.disconnect();
84690e5650f96dabadaaf141beae20a646855073ae1Narayan Kamath                // Context#unbindService does not result in a call to
84790e5650f96dabadaaf141beae20a646855073ae1Narayan Kamath                // ServiceConnection#onServiceDisconnected. As a result, the
84890e5650f96dabadaaf141beae20a646855073ae1Narayan Kamath                // service ends up being destroyed (if there are no other open
84990e5650f96dabadaaf141beae20a646855073ae1Narayan Kamath                // connections to it) but the process lives on and the
85090e5650f96dabadaaf141beae20a646855073ae1Narayan Kamath                // ServiceConnection continues to refer to the destroyed service.
85190e5650f96dabadaaf141beae20a646855073ae1Narayan Kamath                //
85290e5650f96dabadaaf141beae20a646855073ae1Narayan Kamath                // This leads to tons of log spam about SynthThread being dead.
85390e5650f96dabadaaf141beae20a646855073ae1Narayan Kamath                mServiceConnection = null;
854bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath                mCurrentEngine = null;
85550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                return null;
85650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            }
8579c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        }, null, "shutdown", false);
858e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
859e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
860e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
861e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Adds a mapping between a string of text and a sound resource in a
862a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * package. After a call to this method, subsequent calls to
863a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * {@link #speak(String, int, HashMap)} will play the specified sound resource
864a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * if it is available, or synthesize the text it is missing.
865e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
866e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
867a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            The string of text. Example: <code>"south_south_east"</code>
868e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
869e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param packagename
870e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Pass the packagename of the application that contains the
871e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            resource. If the resource is in your own application (this is
872e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            the most common case), then put the packagename of your
873e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            application here.<br/>
874e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            Example: <b>"com.google.marvin.compass"</b><br/>
875e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The packagename can be found in the AndroidManifest.xml of
876e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            your application.
877e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            <p>
878e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            <code>&lt;manifest xmlns:android=&quot;...&quot;
879e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *      package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
880e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            </p>
881e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
882e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param resourceId
883a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            Example: <code>R.raw.south_south_east</code>
8845c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
885ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
886e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
8875c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int addSpeech(String text, String packagename, int resourceId) {
88850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        synchronized (mStartLock) {
88950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            mUtterances.put(text, makeResourceUri(packagename, resourceId));
89050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            return SUCCESS;
891e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
892e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
893e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
894e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
895df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * Adds a mapping between a CharSequence (may be spanned with TtsSpans) of text
896df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * and a sound resource in a package. After a call to this method, subsequent calls to
897df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link #speak(String, int, HashMap)} will play the specified sound resource
898df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * if it is available, or synthesize the text it is missing.
899df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
900df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param text
901df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            The string of text. Example: <code>"south_south_east"</code>
902df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
903df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param packagename
904df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Pass the packagename of the application that contains the
905df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            resource. If the resource is in your own application (this is
906df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            the most common case), then put the packagename of your
907df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            application here.<br/>
908df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Example: <b>"com.google.marvin.compass"</b><br/>
909df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            The packagename can be found in the AndroidManifest.xml of
910df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            your application.
911df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            <p>
912df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            <code>&lt;manifest xmlns:android=&quot;...&quot;
913df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *      package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
914df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            </p>
915df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
916df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param resourceId
917df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Example: <code>R.raw.south_south_east</code>
918df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
919df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
920df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     */
921df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    public int addSpeech(CharSequence text, String packagename, int resourceId) {
922df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts        synchronized (mStartLock) {
923df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts            mUtterances.put(text, makeResourceUri(packagename, resourceId));
924df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts            return SUCCESS;
925df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts        }
926df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    }
927df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts
928df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    /**
929e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Adds a mapping between a string of text and a sound file. Using this, it
930a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * is possible to add custom pronounciations for a string of text.
931a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * After a call to this method, subsequent calls to {@link #speak(String, int, HashMap)}
932a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * will play the specified sound resource if it is available, or synthesize the text it is
933a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * missing.
934e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
935e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param text
936a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            The string of text. Example: <code>"south_south_east"</code>
937e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * @param filename
938e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            The full path to the sound file (for example:
939e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *            "/sdcard/mysounds/hello.wav")
9405c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
941ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
942e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
9435c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int addSpeech(String text, String filename) {
94491bf30a4779146a14b2c9c5ce168d641cd31cb8eJean-Michel Trivi        synchronized (mStartLock) {
94550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            mUtterances.put(text, Uri.parse(filename));
94650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            return SUCCESS;
947e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
948e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
949e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
950df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    /**
951df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * Adds a mapping between a CharSequence (may be spanned with TtsSpans and a sound file.
952df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * Using this, it is possible to add custom pronounciations for a string of text.
953df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * After a call to this method, subsequent calls to {@link #speak(String, int, HashMap)}
954df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * will play the specified sound resource if it is available, or synthesize the text it is
955df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * missing.
956df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
957df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param text
958df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            The string of text. Example: <code>"south_south_east"</code>
95935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     * @param file
96035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *            File object pointing to the sound file.
961df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
962df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
963df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     */
96435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    public int addSpeech(CharSequence text, File file) {
965df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts        synchronized (mStartLock) {
96635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            mUtterances.put(text, Uri.fromFile(file));
967df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts            return SUCCESS;
968df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts        }
969df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    }
970df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts
971e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
972904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     * Adds a mapping between a string of text and a sound resource in a
973a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * package. Use this to add custom earcons.
974904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *
975ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     * @see #playEarcon(String, int, HashMap)
976904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *
977a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * @param earcon The name of the earcon.
978a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            Example: <code>"[tick]"</code><br/>
979904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *
980904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     * @param packagename
981a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            the package name of the application that contains the
982a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            resource. This can for instance be the package name of your own application.
983904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *            Example: <b>"com.google.marvin.compass"</b><br/>
984a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            The package name can be found in the AndroidManifest.xml of
985a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            the application containing the resource.
986904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *            <p>
987904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *            <code>&lt;manifest xmlns:android=&quot;...&quot;
988904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *      package=&quot;<b>com.google.marvin.compass</b>&quot;&gt;</code>
989904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *            </p>
990904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *
991904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     * @param resourceId
992a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            Example: <code>R.raw.tick_snd</code>
993904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *
994ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
995904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     */
996904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen    public int addEarcon(String earcon, String packagename, int resourceId) {
997904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen        synchronized(mStartLock) {
99850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            mEarcons.put(earcon, makeResourceUri(packagename, resourceId));
99950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            return SUCCESS;
1000904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen        }
1001904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen    }
1002904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen
1003904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen    /**
1004a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * Adds a mapping between a string of text and a sound file.
1005a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * Use this to add custom earcons.
1006a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *
1007a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * @see #playEarcon(String, int, HashMap)
1008904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *
1009904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     * @param earcon
1010a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            The name of the earcon.
1011a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     *            Example: <code>"[tick]"</code>
1012904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     * @param filename
1013904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *            The full path to the sound file (for example:
1014904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *            "/sdcard/mysounds/tick.wav")
1015904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     *
1016ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
101735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *
10186ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     * @deprecated As of API level 21, replaced by
101935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *         {@link #addEarcon(String, File)}.
1020904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen     */
102135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    @Deprecated
1022904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen    public int addEarcon(String earcon, String filename) {
102350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        synchronized(mStartLock) {
102450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            mEarcons.put(earcon, Uri.parse(filename));
102550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            return SUCCESS;
1026904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen        }
1027904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen    }
1028904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen
102935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    /**
103035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     * Adds a mapping between a string of text and a sound file.
103135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     * Use this to add custom earcons.
103235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *
103335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     * @see #playEarcon(String, int, HashMap)
103435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *
103535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     * @param earcon
103635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *            The name of the earcon.
103735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *            Example: <code>"[tick]"</code>
103835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     * @param file
103935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *            File object pointing to the sound file.
104035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *
104135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
104235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     */
104335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    public int addEarcon(String earcon, File file) {
104435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        synchronized(mStartLock) {
104535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            mEarcons.put(earcon, Uri.fromFile(file));
104635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            return SUCCESS;
104735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        }
104835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    }
104935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
105050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private Uri makeResourceUri(String packageName, int resourceId) {
105150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return new Uri.Builder()
105250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
105350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                .encodedAuthority(packageName)
105450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                .appendEncodedPath(String.valueOf(resourceId))
105550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                .build();
105650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
1057904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen
1058904dfa588431ff7c99c337d7797f5bef9ac12ce3Charles Chen    /**
1059df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * Speaks the text using the specified queuing strategy and speech parameters, the text may
1060df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * be spanned with TtsSpans.
1061442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
1062442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * requests and then returns. The synthesis might not have finished (or even started!) at the
1063442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * time when this method returns. In order to reliably detect errors during synthesis,
1064442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * we recommend setting an utterance progress listener (see
1065442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * {@link #setOnUtteranceProgressListener}) and using the
1066442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * {@link Engine#KEY_PARAM_UTTERANCE_ID} parameter.
1067e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
10682d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak     * @param text The string of text to be spoken. No longer than
10692d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak     *            {@link #getMaxSpeechInputLength()} characters.
107050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param queueMode The queuing strategy to use, {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
107150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param params Parameters for the request. Can be null.
107250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *            Supported parameter names:
107350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *            {@link Engine#KEY_PARAM_STREAM},
107450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *            {@link Engine#KEY_PARAM_VOLUME},
107550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *            {@link Engine#KEY_PARAM_PAN}.
1076b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            Engine specific parameters may be passed in but the parameter keys
1077b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            must be prefixed by the name of the engine they are intended for. For example
1078b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            the keys "com.svox.pico_foo" and "com.svox.pico:bar" will be passed to the
1079b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            engine named "com.svox.pico" if it is being used.
1080df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param utteranceId An unique identifier for this request.
10815c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
1082442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the speak operation.
1083e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
1084df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    public int speak(final CharSequence text,
1085df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts                     final int queueMode,
108635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                     final Bundle params,
1087df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts                     final String utteranceId) {
108850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return runAction(new Action<Integer>() {
108950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
109050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            public Integer run(ITextToSpeechService service) throws RemoteException {
109150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                Uri utteranceUri = mUtterances.get(text);
109250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                if (utteranceUri != null) {
1093492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath                    return service.playAudio(getCallerIdentity(), utteranceUri, queueMode,
1094df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts                            getParams(params), utteranceId);
109550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                } else {
1096df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts                    return service.speak(getCallerIdentity(), text, queueMode, getParams(params),
1097df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts                            utteranceId);
1098a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                }
1099e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
110050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }, ERROR, "speak");
1101e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
1102e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
1103e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
1104df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * Speaks the string using the specified queuing strategy and speech parameters.
1105df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
1106df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * requests and then returns. The synthesis might not have finished (or even started!) at the
1107df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * time when this method returns. In order to reliably detect errors during synthesis,
1108df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * we recommend setting an utterance progress listener (see
1109df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link #setOnUtteranceProgressListener}) and using the
1110df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link Engine#KEY_PARAM_UTTERANCE_ID} parameter.
1111df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
1112df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param text The string of text to be spoken. No longer than
1113df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link #getMaxSpeechInputLength()} characters.
1114df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param queueMode The queuing strategy to use, {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
1115df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param params Parameters for the request. Can be null.
1116df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Supported parameter names:
1117df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link Engine#KEY_PARAM_STREAM},
1118df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link Engine#KEY_PARAM_UTTERANCE_ID},
1119df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link Engine#KEY_PARAM_VOLUME},
1120df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link Engine#KEY_PARAM_PAN}.
1121df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Engine specific parameters may be passed in but the parameter keys
1122df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            must be prefixed by the name of the engine they are intended for. For example
1123df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            the keys "com.svox.pico_foo" and "com.svox.pico:bar" will be passed to the
1124df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            engine named "com.svox.pico" if it is being used.
1125df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
1126df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the speak operation.
11276ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     * @deprecated As of API level 21, replaced by
112835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *         {@link #speak(CharSequence, int, Bundle, String)}.
1129df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     */
1130df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    @Deprecated
1131df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    public int speak(final String text, final int queueMode, final HashMap<String, String> params) {
113235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        return speak(text, queueMode, convertParamsHashMaptoBundle(params),
1133795d777ee13405d8b6ba6c889ea3ef49713892a8Niels Egberts                     params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
1134df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    }
1135df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts
1136df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    /**
1137e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     * Plays the earcon using the specified queueing mode and parameters.
113850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * The earcon must already have been added with {@link #addEarcon(String, String)} or
113950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * {@link #addEarcon(String, String, int)}.
1140442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
1141442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * requests and then returns. The synthesis might not have finished (or even started!) at the
1142442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * time when this method returns. In order to reliably detect errors during synthesis,
1143442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * we recommend setting an utterance progress listener (see
1144442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * {@link #setOnUtteranceProgressListener}) and using the
1145442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * {@link Engine#KEY_PARAM_UTTERANCE_ID} parameter.
1146e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
114750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param earcon The earcon that should be played
114850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param queueMode {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
114950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param params Parameters for the request. Can be null.
115050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *            Supported parameter names:
115150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *            {@link Engine#KEY_PARAM_STREAM},
1152b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            Engine specific parameters may be passed in but the parameter keys
1153b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            must be prefixed by the name of the engine they are intended for. For example
1154b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            the keys "com.svox.pico_foo" and "com.svox.pico:bar" will be passed to the
1155b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            engine named "com.svox.pico" if it is being used.
11565c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
1157442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playEarcon operation.
1158e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
115950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public int playEarcon(final String earcon, final int queueMode,
116035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            final Bundle params, final String utteranceId) {
116150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return runAction(new Action<Integer>() {
116250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
116350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            public Integer run(ITextToSpeechService service) throws RemoteException {
116450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                Uri earconUri = mEarcons.get(earcon);
116550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                if (earconUri == null) {
116650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    return ERROR;
1167a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi                }
1168492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath                return service.playAudio(getCallerIdentity(), earconUri, queueMode,
1169df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts                        getParams(params), utteranceId);
1170e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
117150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }, ERROR, "playEarcon");
1172e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
1173679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi
11745c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    /**
1175df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * Plays the earcon using the specified queueing mode and parameters.
1176df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * The earcon must already have been added with {@link #addEarcon(String, String)} or
1177df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link #addEarcon(String, String, int)}.
1178df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
1179df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * requests and then returns. The synthesis might not have finished (or even started!) at the
1180df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * time when this method returns. In order to reliably detect errors during synthesis,
1181df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * we recommend setting an utterance progress listener (see
1182df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link #setOnUtteranceProgressListener}) and using the
1183df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link Engine#KEY_PARAM_UTTERANCE_ID} parameter.
1184df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
1185df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param earcon The earcon that should be played
1186df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param queueMode {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
1187df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param params Parameters for the request. Can be null.
1188df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Supported parameter names:
1189df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link Engine#KEY_PARAM_STREAM},
1190df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link Engine#KEY_PARAM_UTTERANCE_ID}.
1191df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Engine specific parameters may be passed in but the parameter keys
1192df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            must be prefixed by the name of the engine they are intended for. For example
1193df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            the keys "com.svox.pico_foo" and "com.svox.pico:bar" will be passed to the
1194df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            engine named "com.svox.pico" if it is being used.
1195df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
1196df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playEarcon operation.
11976ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     * @deprecated As of API level 21, replaced by
119835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *         {@link #playEarcon(String, int, Bundle, String)}.
1199df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     */
1200df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    @Deprecated
1201df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    public int playEarcon(final String earcon, final int queueMode,
1202df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts            final HashMap<String, String> params) {
120335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        return playEarcon(earcon, queueMode, convertParamsHashMaptoBundle(params),
1204795d777ee13405d8b6ba6c889ea3ef49713892a8Niels Egberts                          params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
1205df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    }
1206df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts
1207df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    /**
12085c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * Plays silence for the specified amount of time using the specified
12095c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     * queue mode.
1210442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
1211442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * requests and then returns. The synthesis might not have finished (or even started!) at the
1212442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * time when this method returns. In order to reliably detect errors during synthesis,
1213442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * we recommend setting an utterance progress listener (see
1214442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * {@link #setOnUtteranceProgressListener}) and using the
1215442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * {@link Engine#KEY_PARAM_UTTERANCE_ID} parameter.
12165c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
121750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param durationInMs The duration of the silence.
121850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param queueMode {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
1219df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param utteranceId An unique identifier for this request.
12205c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
12216ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playSilentUtterance operation.
12225c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     */
12236ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak    public int playSilentUtterance(final long durationInMs, final int queueMode,
1224f9ba548f210b0ed071ff7d597ddf2209af817294Przemyslaw Szczepaniak            final String utteranceId) {
122550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return runAction(new Action<Integer>() {
122650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
122750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            public Integer run(ITextToSpeechService service) throws RemoteException {
1228795d777ee13405d8b6ba6c889ea3ef49713892a8Niels Egberts                return service.playSilence(getCallerIdentity(), durationInMs,
1229795d777ee13405d8b6ba6c889ea3ef49713892a8Niels Egberts                                           queueMode, utteranceId);
1230f032bc7da536774a0b6a1c77632c65b935eee6faCharles Chen            }
12316ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak        }, ERROR, "playSilentUtterance");
1232a8518c169bb34e540b7542ad5bd3891053d01a9fJean-Michel Trivi    }
1233e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
1234e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
1235df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * Plays silence for the specified amount of time using the specified
1236df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * queue mode.
1237df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
1238df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * requests and then returns. The synthesis might not have finished (or even started!) at the
1239df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * time when this method returns. In order to reliably detect errors during synthesis,
1240df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * we recommend setting an utterance progress listener (see
1241df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link #setOnUtteranceProgressListener}) and using the
1242df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link Engine#KEY_PARAM_UTTERANCE_ID} parameter.
1243df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
1244df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param durationInMs The duration of the silence.
1245df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param queueMode {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
1246df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param params Parameters for the request. Can be null.
1247df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Supported parameter names:
1248df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link Engine#KEY_PARAM_UTTERANCE_ID}.
1249df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Engine specific parameters may be passed in but the parameter keys
1250df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            must be prefixed by the name of the engine they are intended for. For example
1251df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            the keys "com.svox.pico_foo" and "com.svox.pico:bar" will be passed to the
1252df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            engine named "com.svox.pico" if it is being used.
1253df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
1254df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playSilence operation.
12556ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     * @deprecated As of API level 21, replaced by
12566ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     *         {@link #playSilentUtterance(long, int, String)}.
1257df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     */
1258df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    @Deprecated
1259df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    public int playSilence(final long durationInMs, final int queueMode,
1260df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts            final HashMap<String, String> params) {
12616ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak        return playSilentUtterance(durationInMs, queueMode,
1262795d777ee13405d8b6ba6c889ea3ef49713892a8Niels Egberts                           params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
1263df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    }
1264df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts
1265df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    /**
1266748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * Queries the engine for the set of features it supports for a given locale.
1267748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * Features can either be framework defined, e.g.
1268748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * {@link TextToSpeech.Engine#KEY_FEATURE_NETWORK_SYNTHESIS} or engine specific.
1269748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * Engine specific keys must be prefixed by the name of the engine they
1270748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * are intended for. These keys can be used as parameters to
1271748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * {@link TextToSpeech#speak(String, int, java.util.HashMap)} and
1272748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * {@link TextToSpeech#synthesizeToFile(String, java.util.HashMap, String)}.
1273748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *
1274ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * Features values are strings and their values must meet restrictions described in their
1275ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * documentation.
1276748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     *
1277748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     * @param locale The locale to query features for.
1278a1788af3440fef04d16067223a31e9dced3500b9Przemyslaw Szczepaniak     * @return Set instance. May return {@code null} on error.
12796ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     * @deprecated As of API level 21, please use voices. In order to query features of the voice,
1280ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * call {@link #getVoices()} to retrieve the list of available voices and
1281ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * {@link Voice#getFeatures()} to retrieve the set of features.
1282748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath     */
1283ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    @Deprecated
1284748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath    public Set<String> getFeatures(final Locale locale) {
1285748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath        return runAction(new Action<Set<String>>() {
1286748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath            @Override
1287748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath            public Set<String> run(ITextToSpeechService service) throws RemoteException {
128858f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak                String[] features = null;
128958f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak                try {
129058f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak                    features = service.getFeaturesForLanguage(
1291748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath                        locale.getISO3Language(), locale.getISO3Country(), locale.getVariant());
129258f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak                } catch(MissingResourceException e) {
129358f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak                    Log.w(TAG, "Couldn't retrieve 3 letter ISO 639-2/T language and/or ISO 3166 " +
129458f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak                            "country code for locale: " + locale, e);
129558f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak                    return null;
129658f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak                }
129758f16653728417100c61b5cb63298e0e3bb528dcPrzemyslaw Szczepaniak
1298748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath                if (features != null) {
1299748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath                    final Set<String> featureSet = new HashSet<String>();
1300748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath                    Collections.addAll(featureSet, features);
1301748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath                    return featureSet;
1302748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath                }
1303748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath                return null;
1304748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath            }
1305748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath        }, null, "getFeatures");
1306748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath    }
1307748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath
1308748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath    /**
1309c34f76fe89b5a31d01d63067c2f24b9a6a76df18Narayan Kamath     * Checks whether the TTS engine is busy speaking. Note that a speech item is
1310c34f76fe89b5a31d01d63067c2f24b9a6a76df18Narayan Kamath     * considered complete once it's audio data has been sent to the audio mixer, or
1311c34f76fe89b5a31d01d63067c2f24b9a6a76df18Narayan Kamath     * written to a file. There might be a finite lag between this point, and when
1312c34f76fe89b5a31d01d63067c2f24b9a6a76df18Narayan Kamath     * the audio hardware completes playback.
1313e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
131450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @return {@code true} if the TTS engine is speaking.
1315e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
1316e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    public boolean isSpeaking() {
131750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return runAction(new Action<Boolean>() {
131850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
131950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            public Boolean run(ITextToSpeechService service) throws RemoteException {
132050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                return service.isSpeaking();
1321e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
132250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }, false, "isSpeaking");
1323e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
1324e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
1325e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
1326a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * Interrupts the current utterance (whether played or rendered to file) and discards other
1327a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * utterances in the queue.
13285c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
132950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @return {@link #ERROR} or {@link #SUCCESS}.
1330e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
13315c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int stop() {
133250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return runAction(new Action<Integer>() {
133350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
133450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            public Integer run(ITextToSpeechService service) throws RemoteException {
1335492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath                return service.stop(getCallerIdentity());
1336e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
133750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }, ERROR, "stop");
1338e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
1339e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
1340e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
134150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * Sets the speech rate.
1342e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
1343679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi     * This has no effect on any pre-recorded speech.
1344e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
134550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param speechRate Speech rate. {@code 1.0} is the normal speech rate,
134650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *            lower values slow down the speech ({@code 0.5} is half the normal speech rate),
134750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *            greater values accelerate it ({@code 2.0} is twice the normal speech rate).
13485c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
134950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @return {@link #ERROR} or {@link #SUCCESS}.
1350e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
13515c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int setSpeechRate(float speechRate) {
135250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        if (speechRate > 0.0f) {
135350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            int intRate = (int)(speechRate * 100);
135450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            if (intRate > 0) {
135550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                synchronized (mStartLock) {
135650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    mParams.putInt(Engine.KEY_PARAM_RATE, intRate);
1357679d728f09eeab2f8b882e42f6e081db1ac74996Jean-Michel Trivi                }
135850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                return SUCCESS;
1359e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
1360e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
136150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return ERROR;
1362e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
1363e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
1364e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
1365a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * Sets the speech pitch for the TextToSpeech engine.
13662ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     *
13672ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     * This has no effect on any pre-recorded speech.
13682ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     *
136950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param pitch Speech pitch. {@code 1.0} is the normal pitch,
13702ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     *            lower values lower the tone of the synthesized voice,
13712ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     *            greater values increase it.
13725c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
137350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @return {@link #ERROR} or {@link #SUCCESS}.
13742ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi     */
13755c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen    public int setPitch(float pitch) {
137650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        if (pitch > 0.0f) {
137750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            int intPitch = (int)(pitch * 100);
137850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            if (intPitch > 0) {
137950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                synchronized (mStartLock) {
138050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    mParams.putInt(Engine.KEY_PARAM_PITCH, intPitch);
13812ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi                }
138250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                return SUCCESS;
13832ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi            }
13842ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi        }
138550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return ERROR;
13862ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi    }
13872ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi
13882ea5349583de4a505501530d04133524bb6d5d38Jean-Michel Trivi    /**
1389672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak     * Sets the audio attributes to be used when speaking text or playing
1390672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak     * back a file.
1391672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak     *
1392672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak     * @param audioAttributes Valid AudioAttributes instance.
1393672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak     *
1394672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak     * @return {@link #ERROR} or {@link #SUCCESS}.
1395672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak     */
1396672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak    public int setAudioAttributes(AudioAttributes audioAttributes) {
1397672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak        if (audioAttributes != null) {
1398672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak            synchronized (mStartLock) {
1399672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak                mParams.putParcelable(Engine.KEY_PARAM_AUDIO_ATTRIBUTES,
1400672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak                    audioAttributes);
1401672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak            }
1402672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak            return SUCCESS;
1403672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak        }
1404672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak        return ERROR;
1405672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak    }
1406672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak
1407672695e42387a024083d198f3d665f354ef1d27cPrzemyslaw Szczepaniak    /**
1408bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath     * @return the engine currently in use by this TextToSpeech instance.
1409bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath     * @hide
1410bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath     */
1411bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath    public String getCurrentEngine() {
1412bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath        return mCurrentEngine;
1413bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath    }
1414bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath
1415bd2492e14ee9db9139cc0ff0bd29fc9864b0126cNarayan Kamath    /**
1416b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak     * Returns a Locale instance describing the language currently being used as the default
1417b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak     * Text-to-speech language.
1418b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak     *
1419ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * The locale object returned by this method is NOT a valid one. It has identical form to the
1420ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * one in {@link #getLanguage()}. Please refer to {@link #getLanguage()} for more information.
1421ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1422b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak     * @return language, country (if any) and variant (if any) used by the client stored in a
1423b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak     *     Locale instance, or {@code null} on error.
14246ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     * @deprecated As of API level 21, use <code>getDefaultVoice().getLocale()</code> ({@link
1425ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *   #getDefaultVoice()})
1426b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak     */
1427ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    @Deprecated
1428b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak    public Locale getDefaultLanguage() {
1429b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak        return runAction(new Action<Locale>() {
1430b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak            @Override
1431b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak            public Locale run(ITextToSpeechService service) throws RemoteException {
1432b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak                String[] defaultLanguage = service.getClientDefaultLanguage();
1433b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak
1434b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak                return new Locale(defaultLanguage[0], defaultLanguage[1], defaultLanguage[2]);
1435b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak            }
1436b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak        }, null, "getDefaultLanguage");
1437b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak    }
1438b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak
1439b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak    /**
144050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * Sets the text-to-speech language.
144150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * The TTS engine will try to use the closest match to the specified
1442a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * language as represented by the Locale, but there is no guarantee that the exact same Locale
1443a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * will be used. Use {@link #isLanguageAvailable(Locale)} to check the level of support
1444a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * before choosing the language to use for the next utterances.
1445e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
1446ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * This method sets the current voice to the default one for the given Locale;
1447ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * {@link #getVoice()} can be used to retrieve it.
1448ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
144950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param loc The locale describing the language to be used.
14505c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
145150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @return Code indicating the support status for the locale. See {@link #LANG_AVAILABLE},
1452ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     *         {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE},
1453ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     *         {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}.
1454e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
145550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public int setLanguage(final Locale loc) {
145650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return runAction(new Action<Integer>() {
145750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
145850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            public Integer run(ITextToSpeechService service) throws RemoteException {
145950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                if (loc == null) {
146050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    return LANG_NOT_SUPPORTED;
146150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                }
1462d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                String language = null, country = null;
1463d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                try {
1464d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    language = loc.getISO3Language();
1465d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                } catch (MissingResourceException e) {
1466d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    Log.w(TAG, "Couldn't retrieve ISO 639-2/T language code for locale: " + loc, e);
1467d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    return LANG_NOT_SUPPORTED;
1468d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                }
1469d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak
1470d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                try {
1471d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    country = loc.getISO3Country();
1472d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                } catch (MissingResourceException e) {
1473d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    Log.w(TAG, "Couldn't retrieve ISO 3166 country code for locale: " + loc, e);
1474d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    return LANG_NOT_SUPPORTED;
1475d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                }
1476d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak
14771a2712ce2a18eba6809d984d2f7443fbdccaa7edCharles Chen                String variant = loc.getVariant();
1478d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak
14796ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak                // As of API level 21, setLanguage is implemented using setVoice.
1480ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                // (which, in the default implementation, will call loadLanguage on the service
1481ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                // interface).
148213896b74194b07c821d5d89713e4e747b9b77d73Przemyslaw Szczepaniak
1483ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                // Sanitize locale using isLanguageAvailable.
1484ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                int result = service.isLanguageAvailable( language, country, variant);
14851a2712ce2a18eba6809d984d2f7443fbdccaa7edCharles Chen                if (result >= LANG_AVAILABLE){
148650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    if (result < LANG_COUNTRY_VAR_AVAILABLE) {
148750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                        variant = "";
148850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                        if (result < LANG_COUNTRY_AVAILABLE) {
148950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                            country = "";
149050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                        }
14911a2712ce2a18eba6809d984d2f7443fbdccaa7edCharles Chen                    }
1492ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    // Get the default voice for the locale.
1493ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    String voiceName = service.getDefaultVoiceNameFor(language, country, variant);
1494ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    if (TextUtils.isEmpty(voiceName)) {
1495ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        Log.w(TAG, "Couldn't find the default voice for " + language + "/" +
1496ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                                country + "/" + variant);
1497ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        return LANG_NOT_SUPPORTED;
1498ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    }
1499ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1500ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    // Load it.
1501ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    if (service.loadVoice(getCallerIdentity(), voiceName) == TextToSpeech.ERROR) {
1502ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        return LANG_NOT_SUPPORTED;
1503ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    }
1504ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1505ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    mParams.putString(Engine.KEY_PARAM_VOICE_NAME, voiceName);
150650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    mParams.putString(Engine.KEY_PARAM_LANGUAGE, language);
150750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    mParams.putString(Engine.KEY_PARAM_COUNTRY, country);
150850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    mParams.putString(Engine.KEY_PARAM_VARIANT, variant);
15091a2712ce2a18eba6809d984d2f7443fbdccaa7edCharles Chen                }
151050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                return result;
1511e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
151250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }, LANG_NOT_SUPPORTED, "setLanguage");
1513e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
1514e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
1515aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    /**
1516228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     * Returns a Locale instance describing the language currently being used for synthesis
1517228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     * requests sent to the TextToSpeech engine.
151850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *
1519228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     * In Android 4.2 and before (API <= 17) this function returns the language that is currently
1520228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     * being used by the TTS engine. That is the last language set by this or any other
1521228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     * client by a {@link TextToSpeech#setLanguage} call to the same engine.
1522228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     *
1523228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     * In Android versions after 4.2 this function returns the language that is currently being
1524228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     * used for the synthesis requests sent from this client. That is the last language set
1525228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     * by a {@link TextToSpeech#setLanguage} call on this instance.
1526228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     *
1527ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * If a voice is set (by {@link #setVoice(Voice)}), getLanguage will return the language of
1528ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * the currently set voice.
1529ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1530ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * Please note that the Locale object returned by this method is NOT a valid Locale object. Its
1531ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * language field contains a three-letter ISO 639-2/T code (where a proper Locale would use
1532ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * a two-letter ISO 639-1 code), and the country field contains a three-letter ISO 3166 country
1533ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * code (where a proper Locale would use a two-letter ISO 3166-1 code).
1534ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1535228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     * @return language, country (if any) and variant (if any) used by the client stored in a
1536228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak     *     Locale instance, or {@code null} on error.
1537ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
15386ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     * @deprecated As of API level 21, please use <code>getVoice().getLocale()</code>
1539ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * ({@link #getVoice()}).
1540ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi     */
1541ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    @Deprecated
1542ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi    public Locale getLanguage() {
154350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return runAction(new Action<Locale>() {
154450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
1545228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak            public Locale run(ITextToSpeechService service) {
1546228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak                /* No service call, but we're accessing mParams, hence need for
1547228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak                   wrapping it as an Action instance */
1548228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak                String lang = mParams.getString(Engine.KEY_PARAM_LANGUAGE, "");
1549228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak                String country = mParams.getString(Engine.KEY_PARAM_COUNTRY, "");
1550228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak                String variant = mParams.getString(Engine.KEY_PARAM_VARIANT, "");
1551228323e759445398e2d723de9365da71099ec58bPrzemyslaw Szczepaniak                return new Locale(lang, country, variant);
1552ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            }
155350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }, null, "getLanguage");
1554ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi    }
1555ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi
1556ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi    /**
1557ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * Query the engine about the set of available languages.
1558ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     */
1559ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    public Set<Locale> getAvailableLanguages() {
1560ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        return runAction(new Action<Set<Locale>>() {
1561ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            @Override
1562ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            public Set<Locale> run(ITextToSpeechService service) throws RemoteException {
1563ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                List<Voice> voices = service.getVoices();
15643786bc549891592335be0f454609d9c626d69ef4Przemyslaw Szczepaniak                if (voices == null) {
15653786bc549891592335be0f454609d9c626d69ef4Przemyslaw Szczepaniak                    return new HashSet<Locale>();
1566ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
15673786bc549891592335be0f454609d9c626d69ef4Przemyslaw Szczepaniak                HashSet<Locale> locales = new HashSet<Locale>();
1568ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                for (Voice voice : voices) {
1569ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    locales.add(voice.getLocale());
1570ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1571ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                return locales;
1572ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            }
1573ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        }, null, "getAvailableLanguages");
1574ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    }
1575ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1576ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    /**
1577ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * Query the engine about the set of available voices.
1578ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1579ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * Each TTS Engine can expose multiple voices for each locale, each with a different set of
1580ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * features.
1581ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1582ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @see #setVoice(Voice)
1583ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @see Voice
1584ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     */
1585ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    public Set<Voice> getVoices() {
1586ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        return runAction(new Action<Set<Voice>>() {
1587ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            @Override
1588ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            public Set<Voice> run(ITextToSpeechService service) throws RemoteException {
1589ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                List<Voice> voices = service.getVoices();
15903786bc549891592335be0f454609d9c626d69ef4Przemyslaw Szczepaniak                return (voices != null)  ? new HashSet<Voice>(voices) : new HashSet<Voice>();
1591ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            }
1592ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        }, null, "getVoices");
1593ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    }
1594ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1595ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    /**
1596ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * Sets the text-to-speech voice.
1597ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1598ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @param voice One of objects returned by {@link #getVoices()}.
1599ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1600ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @return {@link #ERROR} or {@link #SUCCESS}.
1601ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1602ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @see #getVoices
1603ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @see Voice
1604ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     */
1605ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    public int setVoice(final Voice voice) {
1606ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        return runAction(new Action<Integer>() {
1607ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            @Override
1608ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            public Integer run(ITextToSpeechService service) throws RemoteException {
1609ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                int result = service.loadVoice(getCallerIdentity(), voice.getName());
1610ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                if (result == SUCCESS) {
1611ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    mParams.putString(Engine.KEY_PARAM_VOICE_NAME, voice.getName());
1612ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1613ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    // Set the language/country/variant, so #getLanguage will return the voice
1614ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    // locale when called.
1615ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    String language = "";
1616ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    try {
1617ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        language = voice.getLocale().getISO3Language();
1618ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    } catch (MissingResourceException e) {
1619ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        Log.w(TAG, "Couldn't retrieve ISO 639-2/T language code for locale: " +
1620ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                                voice.getLocale(), e);
1621ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    }
1622ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1623ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    String country = "";
1624ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    try {
1625ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        country = voice.getLocale().getISO3Country();
1626ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    } catch (MissingResourceException e) {
1627ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        Log.w(TAG, "Couldn't retrieve ISO 3166 country code for locale: " +
1628ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                                voice.getLocale(), e);
1629ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    }
1630ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    mParams.putString(Engine.KEY_PARAM_LANGUAGE, language);
1631ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    mParams.putString(Engine.KEY_PARAM_COUNTRY, country);
1632ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    mParams.putString(Engine.KEY_PARAM_VARIANT, voice.getLocale().getVariant());
1633ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1634ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                return result;
1635ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            }
1636ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        }, LANG_NOT_SUPPORTED, "setVoice");
1637ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    }
1638ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1639ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    /**
1640ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * Returns a Voice instance describing the voice currently being used for synthesis
1641ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * requests sent to the TextToSpeech engine.
1642ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1643ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @return Voice instance used by the client, or {@code null} if not set or on error.
1644ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *
1645ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @see #getVoices
1646ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @see #setVoice
1647ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @see Voice
1648ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     */
1649ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    public Voice getVoice() {
1650ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        return runAction(new Action<Voice>() {
1651ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            @Override
1652ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            public Voice run(ITextToSpeechService service) throws RemoteException {
1653ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                String voiceName = mParams.getString(Engine.KEY_PARAM_VOICE_NAME, "");
1654ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                if (TextUtils.isEmpty(voiceName)) {
1655ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    return null;
1656ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1657ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                List<Voice> voices = service.getVoices();
1658ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                if (voices == null) {
1659ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    return null;
1660ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1661ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                for (Voice voice : voices) {
1662ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    if (voice.getName().equals(voiceName)) {
1663ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        return voice;
1664ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    }
1665ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1666ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                return null;
1667ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            }
1668ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        }, null, "getVoice");
1669ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    }
1670ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1671ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    /**
1672ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * Returns a Voice instance that's the default voice for the default Text-to-speech language.
1673ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     * @return The default voice instance for the default language, or {@code null} if not set or
1674ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     *     on error.
1675ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak     */
1676ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    public Voice getDefaultVoice() {
1677ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        return runAction(new Action<Voice>() {
1678ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            @Override
1679ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            public Voice run(ITextToSpeechService service) throws RemoteException {
1680ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1681ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                String[] defaultLanguage = service.getClientDefaultLanguage();
1682ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1683ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                if (defaultLanguage == null || defaultLanguage.length == 0) {
1684ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    Log.e(TAG, "service.getClientDefaultLanguage() returned empty array");
1685ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    return null;
1686ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1687ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                String language = defaultLanguage[0];
1688ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                String country = (defaultLanguage.length > 1) ? defaultLanguage[1] : "";
1689ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                String variant = (defaultLanguage.length > 2) ? defaultLanguage[2] : "";
1690ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1691ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                // Sanitize the locale using isLanguageAvailable.
1692ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                int result = service.isLanguageAvailable(language, country, variant);
1693ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                if (result >= LANG_AVAILABLE){
1694ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    if (result < LANG_COUNTRY_VAR_AVAILABLE) {
1695ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        variant = "";
1696ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        if (result < LANG_COUNTRY_AVAILABLE) {
1697ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                            country = "";
1698ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        }
1699ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    }
1700ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                } else {
1701ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    // The default language is not supported.
1702ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    return null;
1703ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1704ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1705ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                // Get the default voice name
1706ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                String voiceName = service.getDefaultVoiceNameFor(language, country, variant);
1707ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                if (TextUtils.isEmpty(voiceName)) {
1708ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    return null;
1709ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1710ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1711ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                // Find it
1712ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                List<Voice> voices = service.getVoices();
1713ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                if (voices == null) {
1714ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    return null;
1715ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1716ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                for (Voice voice : voices) {
1717ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    if (voice.getName().equals(voiceName)) {
1718ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                        return voice;
1719ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                    }
1720ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                }
1721ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak                return null;
1722ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            }
1723ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak        }, null, "getDefaultVoice");
1724ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    }
1725ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1726ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1727ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak
1728ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    /**
1729a9b417e9bfea3da908884c726ffc9bf4f64691cfJean-Michel Trivi     * Checks if the specified language as represented by the Locale is available and supported.
1730aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     *
173150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param loc The Locale describing the language to be used.
17325c22f516be7753859f62ca3ff5327c453ee26faaCharles Chen     *
173350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @return Code indicating the support status for the locale. See {@link #LANG_AVAILABLE},
1734ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     *         {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE},
1735ed06578eddde07abe325fa4c92910bb7246cd49fJean-Michel Trivi     *         {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}.
1736aaf842edbfe76990413d4c002acb394f855321b5Charles Chen     */
173750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public int isLanguageAvailable(final Locale loc) {
173850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return runAction(new Action<Integer>() {
173950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
174050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            public Integer run(ITextToSpeechService service) throws RemoteException {
1741d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                String language = null, country = null;
1742d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak
1743d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                try {
1744d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    language = loc.getISO3Language();
1745d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                } catch (MissingResourceException e) {
1746d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    Log.w(TAG, "Couldn't retrieve ISO 639-2/T language code for locale: " + loc, e);
1747d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    return LANG_NOT_SUPPORTED;
1748d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                }
1749d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak
1750d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                try {
1751d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    country = loc.getISO3Country();
1752d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                } catch (MissingResourceException e) {
1753d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    Log.w(TAG, "Couldn't retrieve ISO 3166 country code for locale: " + loc, e);
1754d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                    return LANG_NOT_SUPPORTED;
1755d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                }
1756d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak
1757d0b927948ec06ab90da639fe0a7bf1ec862301a0Przemyslaw Szczepaniak                return service.isLanguageAvailable(language, country, loc.getVariant());
1758ddb0a803fd353fbaf0139cc8804499bc9dce7403Jean-Michel Trivi            }
175950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }, LANG_NOT_SUPPORTED, "isLanguageAvailable");
1760aaf842edbfe76990413d4c002acb394f855321b5Charles Chen    }
1761aaf842edbfe76990413d4c002acb394f855321b5Charles Chen
1762e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    /**
1763d4989093ed708ddf9c799655ea0af7afda726426Charles Chen     * Synthesizes the given text to a file using the specified parameters.
1764442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
1765442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * requests and then returns. The synthesis might not have finished (or even started!) at the
1766442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * time when this method returns. In order to reliably detect errors during synthesis,
1767442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * we recommend setting an utterance progress listener (see
1768df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link #setOnUtteranceProgressListener}).
1769e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     *
17702d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak     * @param text The text that should be synthesized. No longer than
17712d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak     *            {@link #getMaxSpeechInputLength()} characters.
177250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param params Parameters for the request. Can be null.
1773b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            Engine specific parameters may be passed in but the parameter keys
1774b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            must be prefixed by the name of the engine they are intended for. For example
1775b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            the keys "com.svox.pico_foo" and "com.svox.pico:bar" will be passed to the
1776b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath     *            engine named "com.svox.pico" if it is being used.
177735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     * @param file File to write the generated audio data to.
1778df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param utteranceId An unique identifier for this request.
1779442f1786b243923a11d7c15a32e96c7962d4b50aPrzemyslaw Szczepaniak     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the synthesizeToFile operation.
1780e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi     */
178135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    public int synthesizeToFile(final CharSequence text, final Bundle params,
178235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            final File file, final String utteranceId) {
178350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return runAction(new Action<Integer>() {
178450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            @Override
178550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            public Integer run(ITextToSpeechService service) throws RemoteException {
17865acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                ParcelFileDescriptor fileDescriptor;
17875acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                int returnValue;
17885acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                try {
17895acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                    if(file.exists() && !file.canWrite()) {
179035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                        Log.e(TAG, "Can't write to " + file);
17915acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                        return ERROR;
17925acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                    }
17935acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                    fileDescriptor = ParcelFileDescriptor.open(file,
17945acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                            ParcelFileDescriptor.MODE_WRITE_ONLY |
17955acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                            ParcelFileDescriptor.MODE_CREATE |
17965acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                            ParcelFileDescriptor.MODE_TRUNCATE);
17975acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                    returnValue = service.synthesizeToFileDescriptor(getCallerIdentity(), text,
1798df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts                            fileDescriptor, getParams(params), utteranceId);
17995acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                    fileDescriptor.close();
18005acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                    return returnValue;
18015acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                } catch (FileNotFoundException e) {
180235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                    Log.e(TAG, "Opening file " + file + " failed", e);
18035acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                    return ERROR;
18045acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                } catch (IOException e) {
180535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                    Log.e(TAG, "Closing file " + file + " failed", e);
18065acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                    return ERROR;
18075acb33af357b56fffb055997718b1e4aa97f53fcPrzemyslaw Szczepaniak                }
1808e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi            }
180950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }, ERROR, "synthesizeToFile");
181050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
181150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
1812df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    /**
1813df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * Synthesizes the given text to a file using the specified parameters.
1814df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
1815df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * requests and then returns. The synthesis might not have finished (or even started!) at the
1816df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * time when this method returns. In order to reliably detect errors during synthesis,
1817df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * we recommend setting an utterance progress listener (see
1818df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link #setOnUtteranceProgressListener}) and using the
1819df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * {@link Engine#KEY_PARAM_UTTERANCE_ID} parameter.
1820df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
1821df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param text The text that should be synthesized. No longer than
1822df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link #getMaxSpeechInputLength()} characters.
1823df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param params Parameters for the request. Can be null.
1824df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Supported parameter names:
1825df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            {@link Engine#KEY_PARAM_UTTERANCE_ID}.
1826df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            Engine specific parameters may be passed in but the parameter keys
1827df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            must be prefixed by the name of the engine they are intended for. For example
1828df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            the keys "com.svox.pico_foo" and "com.svox.pico:bar" will be passed to the
1829df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            engine named "com.svox.pico" if it is being used.
1830df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @param filename Absolute file filename to write the generated audio data to.It should be
1831df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *            something like "/sdcard/myappsounds/mysound.wav".
1832df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     *
1833df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the synthesizeToFile operation.
18346ddd9c29b376fda27c4df3b18d6a67de14a633caPrzemyslaw Szczepaniak     * @deprecated As of API level 21, replaced by
183535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak     *         {@link #synthesizeToFile(CharSequence, Bundle, File, String)}.
1836df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts     */
183735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    @Deprecated
1838df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    public int synthesizeToFile(final String text, final HashMap<String, String> params,
1839df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts            final String filename) {
184035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        return synthesizeToFile(text, convertParamsHashMaptoBundle(params),
184135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                new File(filename), params.get(Engine.KEY_PARAM_UTTERANCE_ID));
1842df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts    }
1843df7deefe8ebcbd619f27e2d394d7e5d0d7af33d1Niels Egberts
184435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    private Bundle convertParamsHashMaptoBundle(HashMap<String, String> params) {
184550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        if (params != null && !params.isEmpty()) {
184635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            Bundle bundle = new Bundle();
184750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            copyIntParam(bundle, params, Engine.KEY_PARAM_STREAM);
18485cbf17ca053b09beadd0b031a46ce193ab27a0f8Przemyslaw Szczepaniak            copyIntParam(bundle, params, Engine.KEY_PARAM_SESSION_ID);
184950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            copyStringParam(bundle, params, Engine.KEY_PARAM_UTTERANCE_ID);
185050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            copyFloatParam(bundle, params, Engine.KEY_PARAM_VOLUME);
185150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            copyFloatParam(bundle, params, Engine.KEY_PARAM_PAN);
1852b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath
1853748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath            // Copy feature strings defined by the framework.
1854748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath            copyStringParam(bundle, params, Engine.KEY_FEATURE_NETWORK_SYNTHESIS);
18556c07a2028505e28abd601870f05d4752e92a4b7bNarayan Kamath            copyStringParam(bundle, params, Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
1856ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            copyIntParam(bundle, params, Engine.KEY_FEATURE_NETWORK_TIMEOUT_MS);
1857ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak            copyIntParam(bundle, params, Engine.KEY_FEATURE_NETWORK_RETRIES_COUNT);
1858748af66ca27d3afe2e16ccc80b147d447635292aNarayan Kamath
1859b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath            // Copy over all parameters that start with the name of the
1860b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath            // engine that we are currently connected to. The engine is
1861b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath            // free to interpret them as it chooses.
1862b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath            if (!TextUtils.isEmpty(mCurrentEngine)) {
1863b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath                for (Map.Entry<String, String> entry : params.entrySet()) {
1864b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath                    final String key = entry.getKey();
1865b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath                    if (key != null && key.startsWith(mCurrentEngine)) {
1866b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath                        bundle.putString(key, entry.getValue());
1867b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath                    }
1868b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath                }
1869b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath            }
1870b956f37e375bb2588208d4b5e8a40fae6fae5f86Narayan Kamath
187150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            return bundle;
187235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        }
187335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        return null;
187435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    }
187535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
187635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    private Bundle getParams(Bundle params) {
187735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        if (params != null && !params.isEmpty()) {
187835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            Bundle bundle = new Bundle(mParams);
187935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            bundle.putAll(params);
188035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
188135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            verifyIntegerBundleParam(bundle, Engine.KEY_PARAM_STREAM);
188235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            verifyIntegerBundleParam(bundle, Engine.KEY_PARAM_SESSION_ID);
188335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            verifyStringBundleParam(bundle, Engine.KEY_PARAM_UTTERANCE_ID);
188435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            verifyFloatBundleParam(bundle, Engine.KEY_PARAM_VOLUME);
188535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            verifyFloatBundleParam(bundle, Engine.KEY_PARAM_PAN);
188635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
188735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            // Copy feature strings defined by the framework.
188835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            verifyBooleanBundleParam(bundle, Engine.KEY_FEATURE_NETWORK_SYNTHESIS);
188935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            verifyBooleanBundleParam(bundle, Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
189035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            verifyIntegerBundleParam(bundle, Engine.KEY_FEATURE_NETWORK_TIMEOUT_MS);
189135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            verifyIntegerBundleParam(bundle, Engine.KEY_FEATURE_NETWORK_RETRIES_COUNT);
189235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
189335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            return bundle;
189450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        } else {
189550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            return mParams;
1896e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi        }
1897e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi    }
1898e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi
189935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    private static boolean verifyIntegerBundleParam(Bundle bundle, String key) {
190035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        if (bundle.containsKey(key)) {
190135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            if (!(bundle.get(key) instanceof Integer ||
190235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                    bundle.get(key) instanceof Long)) {
190335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                bundle.remove(key);
190435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                Log.w(TAG, "Synthesis request paramter " + key + " containst value "
190535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                        + " with invalid type. Should be an Integer or a Long");
190635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                return false;
190735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            }
190835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        }
190935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        return true;
191035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    }
191135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
191235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    private static boolean verifyStringBundleParam(Bundle bundle, String key) {
191335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        if (bundle.containsKey(key)) {
191435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            if (!(bundle.get(key) instanceof String)) {
191535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                bundle.remove(key);
191635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                Log.w(TAG, "Synthesis request paramter " + key + " containst value "
191735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                        + " with invalid type. Should be a String");
191835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                return false;
191935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            }
192035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        }
192135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        return true;
192235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    }
192335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
192435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    private static boolean verifyBooleanBundleParam(Bundle bundle, String key) {
192535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        if (bundle.containsKey(key)) {
192635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            if (!(bundle.get(key) instanceof Boolean ||
192735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                    bundle.get(key) instanceof String)) {
192835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                bundle.remove(key);
192935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                Log.w(TAG, "Synthesis request paramter " + key + " containst value "
193035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                        + " with invalid type. Should be a Boolean or String");
193135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                return false;
193235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            }
193335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        }
193435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        return true;
193535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    }
193635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
193735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
193835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    private static boolean verifyFloatBundleParam(Bundle bundle, String key) {
193935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        if (bundle.containsKey(key)) {
194035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            if (!(bundle.get(key) instanceof Float ||
194135c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                    bundle.get(key) instanceof Double)) {
194235c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                bundle.remove(key);
194335c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                Log.w(TAG, "Synthesis request paramter " + key + " containst value "
194435c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                        + " with invalid type. Should be a Float or a Double");
194535c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak                return false;
194635c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak            }
194735c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        }
194835c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak        return true;
194935c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak    }
195035c7698a1b17c3e4ca0eae753e68bf069a463d70Przemyslaw Szczepaniak
195150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private void copyStringParam(Bundle bundle, HashMap<String, String> params, String key) {
195250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        String value = params.get(key);
195350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        if (value != null) {
195450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            bundle.putString(key, value);
195550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
195650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
1957a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi
195850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private void copyIntParam(Bundle bundle, HashMap<String, String> params, String key) {
195950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        String valueString = params.get(key);
196050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        if (!TextUtils.isEmpty(valueString)) {
196150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            try {
196250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                int value = Integer.parseInt(valueString);
196350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                bundle.putInt(key, value);
196450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            } catch (NumberFormatException ex) {
196550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                // don't set the value in the bundle
196650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            }
196750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
19689d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi    }
19699d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi
197050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private void copyFloatParam(Bundle bundle, HashMap<String, String> params, String key) {
197150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        String valueString = params.get(key);
197250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        if (!TextUtils.isEmpty(valueString)) {
197350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            try {
197450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                float value = Float.parseFloat(valueString);
197550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                bundle.putFloat(key, value);
197650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            } catch (NumberFormatException ex) {
197750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                // don't set the value in the bundle
197850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            }
19799d2d26af2e1111251f5a21213a071eb4fdc1224fJean-Michel Trivi        }
1980a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi    }
1981a981013aa7315e13c6c5f6aad489813c419031eaJean-Michel Trivi
198278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    /**
198350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * Sets the listener that will be notified when synthesis of an utterance completes.
198478c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     *
198550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param listener The listener to use.
198678c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     *
198750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @return {@link #ERROR} or {@link #SUCCESS}.
1988754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     *
1989754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     * @deprecated Use {@link #setOnUtteranceProgressListener(UtteranceProgressListener)}
1990754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     *        instead.
199178c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen     */
1992754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath    @Deprecated
199350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public int setOnUtteranceCompletedListener(final OnUtteranceCompletedListener listener) {
1994754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath        mUtteranceProgressListener = UtteranceProgressListener.from(listener);
1995754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath        return TextToSpeech.SUCCESS;
1996754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath    }
1997754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath
1998754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath    /**
1999754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     * Sets the listener that will be notified of various events related to the
2000754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     * synthesis of a given utterance.
2001754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     *
2002754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     * See {@link UtteranceProgressListener} and
2003754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     * {@link TextToSpeech.Engine#KEY_PARAM_UTTERANCE_ID}.
2004754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     *
2005754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     * @param listener the listener to use.
2006754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     * @return {@link #ERROR} or {@link #SUCCESS}
2007754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath     */
2008754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath    public int setOnUtteranceProgressListener(UtteranceProgressListener listener) {
2009754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath        mUtteranceProgressListener = listener;
2010a57f23837ad172c1b046d5e9cc8eb3d2e41a69f4Narayan Kamath        return TextToSpeech.SUCCESS;
201178c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen    }
201278c9d0d2c5eb4d5687ae7cbe41155159329ad68fCharles Chen
2013b4fbe768f8bfb2550dec100e29d0edc09b8a051aCharles Chen    /**
201450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * Sets the TTS engine to use.
2015b4fbe768f8bfb2550dec100e29d0edc09b8a051aCharles Chen     *
20163f0363bb4b9fab9799ac308dd48baf8830e30647Narayan Kamath     * @deprecated This doesn't inform callers when the TTS engine has been
20173f0363bb4b9fab9799ac308dd48baf8830e30647Narayan Kamath     *        initialized. {@link #TextToSpeech(Context, OnInitListener, String)}
2018b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath     *        can be used with the appropriate engine name. Also, there is no
2019b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath     *        guarantee that the engine specified will be loaded. If it isn't
2020b9db1fb9de483f35f0189dae240b38e8a9cea8c9Narayan Kamath     *        installed or disabled, the user / system wide defaults will apply.
20213f0363bb4b9fab9799ac308dd48baf8830e30647Narayan Kamath     *
202250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @param enginePackageName The package name for the synthesis engine (e.g. "com.svox.pico")
2023b4fbe768f8bfb2550dec100e29d0edc09b8a051aCharles Chen     *
202450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @return {@link #ERROR} or {@link #SUCCESS}.
2025b4fbe768f8bfb2550dec100e29d0edc09b8a051aCharles Chen     */
20263f0363bb4b9fab9799ac308dd48baf8830e30647Narayan Kamath    @Deprecated
202760dd360640a400d9b4a602160733281d284aaee5Charles Chen    public int setEngineByPackageName(String enginePackageName) {
202850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        mRequestedEngine = enginePackageName;
202950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        return initTts();
2030b4fbe768f8bfb2550dec100e29d0edc09b8a051aCharles Chen    }
2031b4fbe768f8bfb2550dec100e29d0edc09b8a051aCharles Chen
2032def7185cf19d48c95b50c2b83503d5cd21a613bfCharles Chen    /**
203350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * Gets the package name of the default speech synthesis engine.
2034def7185cf19d48c95b50c2b83503d5cd21a613bfCharles Chen     *
203522302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath     * @return Package name of the TTS engine that the user has chosen
203622302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath     *        as their default.
2037def7185cf19d48c95b50c2b83503d5cd21a613bfCharles Chen     */
2038def7185cf19d48c95b50c2b83503d5cd21a613bfCharles Chen    public String getDefaultEngine() {
2039d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        return mEnginesHelper.getDefaultEngine();
204050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
204150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
204250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    /**
2043c3edf2a01a2cf2123a3de17ec1da11a3b6c459f0Narayan Kamath     * Checks whether the user's settings should override settings requested
2044c3edf2a01a2cf2123a3de17ec1da11a3b6c459f0Narayan Kamath     * by the calling application. As of the Ice cream sandwich release,
2045c3edf2a01a2cf2123a3de17ec1da11a3b6c459f0Narayan Kamath     * user settings never forcibly override the app's settings.
204650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     */
2047ad6df74ada7c478257425b746588f22eeec199a6Przemyslaw Szczepaniak    @Deprecated
204850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public boolean areDefaultsEnforced() {
2049c3edf2a01a2cf2123a3de17ec1da11a3b6c459f0Narayan Kamath        return false;
205050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
205150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
205242229259a6fca8851db74dc1c0ecbab2d3fb788dCharles Chen    /**
205350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * Gets a list of all installed TTS engines.
205442229259a6fca8851db74dc1c0ecbab2d3fb788dCharles Chen     *
205522302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath     * @return A list of engine info objects. The list can be empty, but never {@code null}.
205642229259a6fca8851db74dc1c0ecbab2d3fb788dCharles Chen     */
205750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public List<EngineInfo> getEngines() {
2058d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        return mEnginesHelper.getEngines();
205922302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath    }
206022302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath
206150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private class Connection implements ServiceConnection {
206250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        private ITextToSpeechService mService;
20638f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
20649c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        private SetupConnectionAsyncTask mOnSetupConnectionAsyncTask;
20659c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak
20669c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        private boolean mEstablished;
20678f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
2068a57f23837ad172c1b046d5e9cc8eb3d2e41a69f4Narayan Kamath        private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
206990d15d2371ad85f22254be6985455aa2baa5d15dPrzemyslaw Szczepaniak            public void onStop(String utteranceId) throws RemoteException {
2070cafd15216ee66a302ee69c0ea0c6c63b07a2f68cPrzemyslaw Szczepaniak                UtteranceProgressListener listener = mUtteranceProgressListener;
2071cafd15216ee66a302ee69c0ea0c6c63b07a2f68cPrzemyslaw Szczepaniak                if (listener != null) {
2072cafd15216ee66a302ee69c0ea0c6c63b07a2f68cPrzemyslaw Szczepaniak                    listener.onDone(utteranceId);
2073cafd15216ee66a302ee69c0ea0c6c63b07a2f68cPrzemyslaw Szczepaniak                }
207490d15d2371ad85f22254be6985455aa2baa5d15dPrzemyslaw Szczepaniak            };
207590d15d2371ad85f22254be6985455aa2baa5d15dPrzemyslaw Szczepaniak
207690d15d2371ad85f22254be6985455aa2baa5d15dPrzemyslaw Szczepaniak            @Override
207790d15d2371ad85f22254be6985455aa2baa5d15dPrzemyslaw Szczepaniak            public void onSuccess(String utteranceId) {
2078754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                UtteranceProgressListener listener = mUtteranceProgressListener;
2079754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                if (listener != null) {
2080754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                    listener.onDone(utteranceId);
2081754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                }
2082754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath            }
2083754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath
2084754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath            @Override
208590d15d2371ad85f22254be6985455aa2baa5d15dPrzemyslaw Szczepaniak            public void onError(String utteranceId, int errorCode) {
2086754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                UtteranceProgressListener listener = mUtteranceProgressListener;
2087754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                if (listener != null) {
2088754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                    listener.onError(utteranceId);
2089754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                }
2090754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath            }
2091754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath
2092754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath            @Override
2093754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath            public void onStart(String utteranceId) {
2094754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                UtteranceProgressListener listener = mUtteranceProgressListener;
2095a57f23837ad172c1b046d5e9cc8eb3d2e41a69f4Narayan Kamath                if (listener != null) {
2096754c72ed9e8e83e5a913aa7552fc2e1b1b5277e0Narayan Kamath                    listener.onStart(utteranceId);
2097a57f23837ad172c1b046d5e9cc8eb3d2e41a69f4Narayan Kamath                }
2098a57f23837ad172c1b046d5e9cc8eb3d2e41a69f4Narayan Kamath            }
2099a57f23837ad172c1b046d5e9cc8eb3d2e41a69f4Narayan Kamath        };
210050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
21019c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        private class SetupConnectionAsyncTask extends AsyncTask<Void, Void, Integer> {
21028f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            private final ComponentName mName;
21038f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
21049c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak            public SetupConnectionAsyncTask(ComponentName name) {
21058f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                mName = name;
21068f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            }
21078f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
21088f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            @Override
21098f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            protected Integer doInBackground(Void... params) {
21108f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                synchronized(mStartLock) {
21118f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                    if (isCancelled()) {
21128f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                        return null;
21138f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                    }
21148f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
21158f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                    try {
21169c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                        mService.setCallback(getCallerIdentity(), mCallback);
2117b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak
2118952c0fd7bc6bb3ec9e0252f0799bbeabcf70dc1aPrzemyslaw Szczepaniak                        if (mParams.getString(Engine.KEY_PARAM_LANGUAGE) == null) {
2119952c0fd7bc6bb3ec9e0252f0799bbeabcf70dc1aPrzemyslaw Szczepaniak                            String[] defaultLanguage = mService.getClientDefaultLanguage();
2120952c0fd7bc6bb3ec9e0252f0799bbeabcf70dc1aPrzemyslaw Szczepaniak                            mParams.putString(Engine.KEY_PARAM_LANGUAGE, defaultLanguage[0]);
2121952c0fd7bc6bb3ec9e0252f0799bbeabcf70dc1aPrzemyslaw Szczepaniak                            mParams.putString(Engine.KEY_PARAM_COUNTRY, defaultLanguage[1]);
2122952c0fd7bc6bb3ec9e0252f0799bbeabcf70dc1aPrzemyslaw Szczepaniak                            mParams.putString(Engine.KEY_PARAM_VARIANT, defaultLanguage[2]);
2123fd80746bb9d67be3a9f87dcb9264785a53631b74Przemyslaw Szczepaniak
2124fd80746bb9d67be3a9f87dcb9264785a53631b74Przemyslaw Szczepaniak                            // Get the default voice for the locale.
2125fd80746bb9d67be3a9f87dcb9264785a53631b74Przemyslaw Szczepaniak                            String defaultVoiceName = mService.getDefaultVoiceNameFor(
2126fd80746bb9d67be3a9f87dcb9264785a53631b74Przemyslaw Szczepaniak                                defaultLanguage[0], defaultLanguage[1], defaultLanguage[2]);
2127fd80746bb9d67be3a9f87dcb9264785a53631b74Przemyslaw Szczepaniak                            mParams.putString(Engine.KEY_PARAM_VOICE_NAME, defaultVoiceName);
2128952c0fd7bc6bb3ec9e0252f0799bbeabcf70dc1aPrzemyslaw Szczepaniak                        }
2129b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak
2130b46533732c40c6aa4d0d7357176835a33d863234Przemyslaw Szczepaniak                        Log.i(TAG, "Set up connection to " + mName);
21318f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                        return SUCCESS;
21328f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                    } catch (RemoteException re) {
21338f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                        Log.e(TAG, "Error connecting to service, setCallback() failed");
21348f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                        return ERROR;
21358f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                    }
21368f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                }
21378f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            }
21388f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
21398f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            @Override
21408f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            protected void onPostExecute(Integer result) {
21418f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                synchronized(mStartLock) {
21429c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                    if (mOnSetupConnectionAsyncTask == this) {
21439c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                        mOnSetupConnectionAsyncTask = null;
21448f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                    }
21459c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                    mEstablished = true;
21468f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                    dispatchOnInit(result);
21478f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                }
21488f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            }
21498f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak        }
21508f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
2151091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak        @Override
215250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public void onServiceConnected(ComponentName name, IBinder service) {
215350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            synchronized(mStartLock) {
21549c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                mConnectingServiceConnection = null;
21559c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak
21568f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                Log.i(TAG, "Connected to " + name);
21578f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
21589c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                if (mOnSetupConnectionAsyncTask != null) {
21599c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                    mOnSetupConnectionAsyncTask.cancel(false);
2160a57f23837ad172c1b046d5e9cc8eb3d2e41a69f4Narayan Kamath                }
21618f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
21629c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                mService = ITextToSpeechService.Stub.asInterface(service);
21639c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                mServiceConnection = Connection.this;
21649c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak
21659c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                mEstablished = false;
21669c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                mOnSetupConnectionAsyncTask = new SetupConnectionAsyncTask(name);
21679c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                mOnSetupConnectionAsyncTask.execute();
216850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            }
216950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
217050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
2171492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath        public IBinder getCallerIdentity() {
2172492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath            return mCallback;
2173492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath        }
2174492b7f0d51f53164aa6eb974cd7ab6a7889af677Narayan Kamath
21758f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak        /**
21768f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak         * Clear connection related fields and cancel mOnServiceConnectedAsyncTask if set.
21778f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak         *
21789c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak         * @return true if we cancel mOnSetupConnectionAsyncTask in progress.
21798f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak         */
21808f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak        private boolean clearServiceConnection() {
218150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            synchronized(mStartLock) {
21828f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                boolean result = false;
21839c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                if (mOnSetupConnectionAsyncTask != null) {
21849c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                    result = mOnSetupConnectionAsyncTask.cancel(false);
21859c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                    mOnSetupConnectionAsyncTask = null;
21868f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                }
21878f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
218850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                mService = null;
218950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                // If this is the active connection, clear it
219050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                if (mServiceConnection == this) {
219150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    mServiceConnection = null;
219250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                }
21938f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                return result;
21948f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            }
21958f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak        }
21968f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak
21978f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak        @Override
21988f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak        public void onServiceDisconnected(ComponentName name) {
21998f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            Log.i(TAG, "Asked to disconnect from " + name);
22008f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            if (clearServiceConnection()) {
22018f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                /* We need to protect against a rare case where engine
22028f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                 * dies just after successful connection - and we process onServiceDisconnected
22038f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                 * before OnServiceConnectedAsyncTask.onPostExecute. onServiceDisconnected cancels
22048f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                 * OnServiceConnectedAsyncTask.onPostExecute and we don't call dispatchOnInit
22058f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                 * with ERROR as argument.
22068f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                 */
22078f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak                dispatchOnInit(ERROR);
220850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            }
220950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
221050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
221150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public void disconnect() {
221250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            mContext.unbindService(this);
22138f3957cb91a9e1465fa11aaf4d4286d4c5a59ba7Przemyslaw Szczepaniak            clearServiceConnection();
221450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
221550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
22169c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        public boolean isEstablished() {
22179c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak            return mService != null && mEstablished;
22189c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        }
22199c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak
22209c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak        public <R> R runAction(Action<R> action, R errorResult, String method,
22219c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                boolean reconnect, boolean onlyEstablishedConnection) {
2222091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak            synchronized (mStartLock) {
2223091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak                try {
222450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    if (mService == null) {
222550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                        Log.w(TAG, method + " failed: not connected to TTS engine");
222650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                        return errorResult;
222750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    }
22281c2df38242c29cd7f359a6fb13dc13b387264310Fergus Henderson                    if (onlyEstablishedConnection && !isEstablished()) {
22291c2df38242c29cd7f359a6fb13dc13b387264310Fergus Henderson                        Log.w(TAG, method + " failed: TTS engine connection not fully set up");
22309c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                        return errorResult;
22319c4012b31b0c09cb14689bd96a71aae42c8a00cdPrzemyslaw Szczepaniak                    }
223250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                    return action.run(mService);
2233091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak                } catch (RemoteException ex) {
2234091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak                    Log.e(TAG, method + " failed", ex);
2235091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak                    if (reconnect) {
2236091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak                        disconnect();
2237091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak                        initTts();
2238091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak                    }
2239091d56cab8f6f6a3460fbb596f99b1a262948e96Przemyslaw Szczepaniak                    return errorResult;
224050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert                }
224142229259a6fca8851db74dc1c0ecbab2d3fb788dCharles Chen            }
224242229259a6fca8851db74dc1c0ecbab2d3fb788dCharles Chen        }
224342229259a6fca8851db74dc1c0ecbab2d3fb788dCharles Chen    }
22442cad2cc15345d8623049a17712068e813d305a25Bjorn Bringert
224550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    private interface Action<R> {
224650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        R run(ITextToSpeechService service) throws RemoteException;
224750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    }
224850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
22492cad2cc15345d8623049a17712068e813d305a25Bjorn Bringert    /**
225050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * Information about an installed text-to-speech engine.
225150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     *
225250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert     * @see TextToSpeech#getEngines
22532cad2cc15345d8623049a17712068e813d305a25Bjorn Bringert     */
225450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert    public static class EngineInfo {
225550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        /**
225650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Engine package name..
225750e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         */
225850e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public String name;
225950e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        /**
226050e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Localized label for the engine.
226150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         */
226250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public String label;
226350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        /**
226450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         * Icon for the engine.
226550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert         */
226650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public int icon;
226722302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath        /**
226822302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         * Whether this engine is a part of the system
226922302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         * image.
2270d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath         *
2271d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath         * @hide
227222302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         */
2273d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        public boolean system;
227422302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath        /**
227522302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         * The priority the engine declares for the the intent filter
227622302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         * {@code android.intent.action.TTS_SERVICE}
2277d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath         *
2278d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath         * @hide
227922302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath         */
2280d3ee2fa18464fb7e4d7f6d27610fbf60b6d1ffceNarayan Kamath        public int priority;
228150e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
228250e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        @Override
228350e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        public String toString() {
228450e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert            return "EngineInfo{name=" + name + "}";
228550e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert        }
228650e657bb2d005568f5dd8bc1d904d07b0d94018fBjorn Bringert
22872cad2cc15345d8623049a17712068e813d305a25Bjorn Bringert    }
228822302fb7ba11f75234f8a268f5932973dd080bf9Narayan Kamath
22892d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak    /**
22902d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak     * Limit of length of input string passed to speak and synthesizeToFile.
22912d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak     *
22922d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak     * @see #speak
22932d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak     * @see #synthesizeToFile
22942d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak     */
22952d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak    public static int getMaxSpeechInputLength() {
22962d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak        return 4000;
22972d940bcbd1c472f8b11ce1495354f340604b4f2cPrzemyslaw Szczepaniak    }
2298e74d507d171de60cc028e6176fe08cc9cdd8b701Jean-Michel Trivi}
2299