Merge change 3949 into donut
* changes: TextToSpeech class cleanups - harmonized private member variable names - added success / failure codes (used for now in initialization) - synchronized access to speech completed listener.
This commit is contained in:
@@ -39,17 +39,28 @@ import java.util.HashMap;
|
|||||||
//TODO #TTS# review + complete javadoc
|
//TODO #TTS# review + complete javadoc
|
||||||
public class TextToSpeech {
|
public class TextToSpeech {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Denotes a successful operation.
|
||||||
|
*/
|
||||||
|
public static final int TTS_SUCCESS = 0;
|
||||||
|
/**
|
||||||
|
* Denotes a generic operation failure.
|
||||||
|
*/
|
||||||
|
public static final int TTS_ERROR = -1;
|
||||||
|
/**
|
||||||
|
* Denotes a failure due to a missing resource.
|
||||||
|
*/
|
||||||
|
public static final int TTS_ERROR_MISSING_RESOURCE = -2;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the TTS has initialized
|
* Called when the TTS has initialized
|
||||||
*
|
*
|
||||||
* The InitListener must implement the onInit function. onInit is passed the
|
* The InitListener must implement the onInit function. onInit is passed a
|
||||||
* version number of the TTS library that the user has installed; since this
|
* status code indicating the result of the TTS initialization.
|
||||||
* is called when the TTS has started, it is a good time to make sure that
|
|
||||||
* the user's TTS library is up to date.
|
|
||||||
*/
|
*/
|
||||||
public interface OnInitListener {
|
public interface OnInitListener {
|
||||||
public void onInit(int version);
|
public void onInit(int status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,15 +77,14 @@ public class TextToSpeech {
|
|||||||
*/
|
*/
|
||||||
private ServiceConnection serviceConnection;
|
private ServiceConnection serviceConnection;
|
||||||
|
|
||||||
private ITts itts = null;
|
private ITts mITts = null;
|
||||||
private Context ctx = null;
|
private Context mContext = null;
|
||||||
private OnInitListener cb = null;
|
private OnInitListener mInitListener = null;
|
||||||
private int version = -1;
|
private boolean mStarted = false;
|
||||||
private boolean started = false;
|
private final Object mStartLock = new Object();
|
||||||
private final Object startLock = new Object();
|
private ITtsCallback mITtsCallback;
|
||||||
private boolean showInstaller = false;
|
private OnSpeechCompletedListener mSpeechCompListener = null;
|
||||||
private ITtsCallback ittscallback;
|
private final Object mSpeechCompListenerLock = new Object();
|
||||||
private OnSpeechCompletedListener speechCompletedCallback = null;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -83,23 +93,22 @@ public class TextToSpeech {
|
|||||||
*
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* The context
|
* The context
|
||||||
* @param callback
|
* @param listener
|
||||||
* The InitListener that should be called when the TTS has
|
* The InitListener that will be called when the TTS has
|
||||||
* initialized successfully.
|
* initialized successfully.
|
||||||
*/
|
*/
|
||||||
public TextToSpeech(Context context, OnInitListener callback) {
|
public TextToSpeech(Context context, OnInitListener listener) {
|
||||||
// TODO #TTS# support TtsVersionAlert
|
mContext = context;
|
||||||
// showInstaller = true;
|
mInitListener = listener;
|
||||||
// versionAlert = alert;
|
|
||||||
ctx = context;
|
|
||||||
cb = callback;
|
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setOnSpeechCompletedListener(
|
public void setOnSpeechCompletedListener(
|
||||||
final OnSpeechCompletedListener listener) {
|
final OnSpeechCompletedListener listener) {
|
||||||
speechCompletedCallback = listener;
|
synchronized(mSpeechCompListenerLock) {
|
||||||
|
mSpeechCompListener = listener;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -114,54 +123,61 @@ public class TextToSpeech {
|
|||||||
|
|
||||||
|
|
||||||
private void initTts() {
|
private void initTts() {
|
||||||
started = false;
|
mStarted = false;
|
||||||
|
|
||||||
// Initialize the TTS, run the callback after the binding is successful
|
// Initialize the TTS, run the callback after the binding is successful
|
||||||
serviceConnection = new ServiceConnection() {
|
serviceConnection = new ServiceConnection() {
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
synchronized(startLock) {
|
synchronized(mStartLock) {
|
||||||
itts = ITts.Stub.asInterface(service);
|
mITts = ITts.Stub.asInterface(service);
|
||||||
try {
|
try {
|
||||||
ittscallback = new ITtsCallback.Stub() {
|
mITtsCallback = new ITtsCallback.Stub() {
|
||||||
//@Override
|
|
||||||
public void markReached(String mark)
|
public void markReached(String mark)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
if (speechCompletedCallback != null) {
|
// call the listener of that event, but not
|
||||||
speechCompletedCallback.onSpeechCompleted();
|
// while locked.
|
||||||
|
OnSpeechCompletedListener listener = null;
|
||||||
|
synchronized(mSpeechCompListenerLock) {
|
||||||
|
listener = mSpeechCompListener;
|
||||||
|
}
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onSpeechCompleted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
itts.registerCallback(ittscallback);
|
mITts.registerCallback(mITtsCallback);
|
||||||
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
initTts();
|
initTts();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
started = true;
|
mStarted = true;
|
||||||
// The callback can become null if the Android OS decides to
|
// The callback can become null if the Android OS decides to
|
||||||
// restart the TTS process as well as whatever is using it.
|
// restart the TTS process as well as whatever is using it.
|
||||||
// In such cases, do nothing - the error handling from the
|
// In such cases, do nothing - the error handling from the
|
||||||
// speaking calls will kick in and force a proper restart of
|
// speaking calls will kick in and force a proper restart of
|
||||||
// the TTS.
|
// the TTS.
|
||||||
if (cb != null) {
|
if (mInitListener != null) {
|
||||||
cb.onInit(version);
|
// TODO manage failures and missing resources
|
||||||
|
mInitListener.onInit(TTS_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
synchronized(startLock) {
|
synchronized(mStartLock) {
|
||||||
itts = null;
|
mITts = null;
|
||||||
cb = null;
|
mInitListener = null;
|
||||||
started = false;
|
mStarted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Intent intent = new Intent("android.intent.action.USE_TTS");
|
Intent intent = new Intent("android.intent.action.USE_TTS");
|
||||||
intent.addCategory("android.intent.category.TTS");
|
intent.addCategory("android.intent.category.TTS");
|
||||||
ctx.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
|
mContext.bindService(intent, serviceConnection,
|
||||||
|
Context.BIND_AUTO_CREATE);
|
||||||
// TODO handle case where the binding works (should always work) but
|
// TODO handle case where the binding works (should always work) but
|
||||||
// the plugin fails
|
// the plugin fails
|
||||||
}
|
}
|
||||||
@@ -174,7 +190,7 @@ public class TextToSpeech {
|
|||||||
*/
|
*/
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
try {
|
try {
|
||||||
ctx.unbindService(serviceConnection);
|
mContext.unbindService(serviceConnection);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// Do nothing and fail silently since an error here indicates that
|
// Do nothing and fail silently since an error here indicates that
|
||||||
// binding never succeeded in the first place.
|
// binding never succeeded in the first place.
|
||||||
@@ -208,23 +224,23 @@ public class TextToSpeech {
|
|||||||
* Example: <b><code>R.raw.south_south_east</code></b>
|
* Example: <b><code>R.raw.south_south_east</code></b>
|
||||||
*/
|
*/
|
||||||
public void addSpeech(String text, String packagename, int resourceId) {
|
public void addSpeech(String text, String packagename, int resourceId) {
|
||||||
synchronized(startLock) {
|
synchronized(mStartLock) {
|
||||||
if (!started) {
|
if (!mStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
itts.addSpeech(text, packagename, resourceId);
|
mITts.addSpeech(text, packagename, resourceId);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,23 +258,23 @@ public class TextToSpeech {
|
|||||||
* "/sdcard/mysounds/hello.wav")
|
* "/sdcard/mysounds/hello.wav")
|
||||||
*/
|
*/
|
||||||
public void addSpeech(String text, String filename) {
|
public void addSpeech(String text, String filename) {
|
||||||
synchronized (startLock) {
|
synchronized (mStartLock) {
|
||||||
if (!started) {
|
if (!mStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
itts.addSpeechFile(text, filename);
|
mITts.addSpeechFile(text, filename);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,25 +298,25 @@ public class TextToSpeech {
|
|||||||
*/
|
*/
|
||||||
public void speak(String text, int queueMode, HashMap<String,String> params)
|
public void speak(String text, int queueMode, HashMap<String,String> params)
|
||||||
{
|
{
|
||||||
synchronized (startLock) {
|
synchronized (mStartLock) {
|
||||||
Log.i("TTS received: ", text);
|
Log.i("TTS received: ", text);
|
||||||
if (!started) {
|
if (!mStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// TODO support extra parameters, passing null for the moment
|
// TODO support extra parameters, passing null for the moment
|
||||||
itts.speak(text, queueMode, null);
|
mITts.speak(text, queueMode, null);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,24 +336,24 @@ public class TextToSpeech {
|
|||||||
*/
|
*/
|
||||||
public void playEarcon(String earcon, int queueMode,
|
public void playEarcon(String earcon, int queueMode,
|
||||||
HashMap<String,String> params) {
|
HashMap<String,String> params) {
|
||||||
synchronized (startLock) {
|
synchronized (mStartLock) {
|
||||||
if (!started) {
|
if (!mStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// TODO support extra parameters, passing null for the moment
|
// TODO support extra parameters, passing null for the moment
|
||||||
itts.playEarcon(earcon, queueMode, null);
|
mITts.playEarcon(earcon, queueMode, null);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -355,23 +371,23 @@ public class TextToSpeech {
|
|||||||
* @return Whether or not the TTS is busy speaking.
|
* @return Whether or not the TTS is busy speaking.
|
||||||
*/
|
*/
|
||||||
public boolean isSpeaking() {
|
public boolean isSpeaking() {
|
||||||
synchronized (startLock) {
|
synchronized (mStartLock) {
|
||||||
if (!started) {
|
if (!mStarted) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return itts.isSpeaking();
|
return mITts.isSpeaking();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -383,23 +399,23 @@ public class TextToSpeech {
|
|||||||
* Stops speech from the TTS.
|
* Stops speech from the TTS.
|
||||||
*/
|
*/
|
||||||
public void stop() {
|
public void stop() {
|
||||||
synchronized (startLock) {
|
synchronized (mStartLock) {
|
||||||
if (!started) {
|
if (!mStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
itts.stop();
|
mITts.stop();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,15 +437,15 @@ public class TextToSpeech {
|
|||||||
* The speech rate for the TTS engine.
|
* The speech rate for the TTS engine.
|
||||||
*/
|
*/
|
||||||
public void setSpeechRate(int speechRate) {
|
public void setSpeechRate(int speechRate) {
|
||||||
synchronized (startLock) {
|
synchronized (mStartLock) {
|
||||||
if (!started) {
|
if (!mStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
itts.setSpeechRate(speechRate);
|
mITts.setSpeechRate(speechRate);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -453,15 +469,15 @@ public class TextToSpeech {
|
|||||||
* http://en.wikipedia.org/wiki/IETF_language_tag
|
* http://en.wikipedia.org/wiki/IETF_language_tag
|
||||||
*/
|
*/
|
||||||
public void setLanguage(String language) {
|
public void setLanguage(String language) {
|
||||||
synchronized (startLock) {
|
synchronized (mStartLock) {
|
||||||
if (!started) {
|
if (!mStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
itts.setLanguage(language);
|
mITts.setLanguage(language);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -482,24 +498,24 @@ public class TextToSpeech {
|
|||||||
*/
|
*/
|
||||||
public boolean synthesizeToFile(String text, HashMap<String,String> params,
|
public boolean synthesizeToFile(String text, HashMap<String,String> params,
|
||||||
String filename) {
|
String filename) {
|
||||||
synchronized (startLock) {
|
synchronized (mStartLock) {
|
||||||
if (!started) {
|
if (!mStarted) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// TODO support extra parameters, passing null for the moment
|
// TODO support extra parameters, passing null for the moment
|
||||||
return itts.synthesizeToFile(text, null, filename);
|
return mITts.synthesizeToFile(text, null, filename);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// TTS died; restart it.
|
// TTS died; restart it.
|
||||||
started = false;
|
mStarted = false;
|
||||||
initTts();
|
initTts();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user