summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcore/java/android/speech/tts/TextToSpeech.java2
-rwxr-xr-xpackages/TtsService/src/android/tts/TtsService.java97
2 files changed, 80 insertions, 19 deletions
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 04a0ec8..4405a53 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -1032,7 +1032,7 @@ public class TextToSpeech {
}
try {
String[] locStrings = mITts.getLanguage();
- if (locStrings.length == 3) {
+ if ((locStrings != null) && (locStrings.length == 3)) {
return new Locale(locStrings[0], locStrings[1], locStrings[2]);
} else {
return null;
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 1b99d32..cd24727 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -172,10 +172,18 @@ public class TtsService extends Service implements OnCompletionListener {
@Override
public void onDestroy() {
super.onDestroy();
+
+ // TODO replace the call to stopAll() with a method to clear absolutely all upcoming
+ // uses of the native synth, including synthesis to a file, and delete files for which
+ // synthesis was not complete.
+ stopAll("");
+
// Don't hog the media player
cleanUpPlayer();
- sNativeSynth.shutdown();
+ if (sNativeSynth != null) {
+ sNativeSynth.shutdown();
+ }
sNativeSynth = null;
// Unregister all callbacks.
@@ -243,38 +251,70 @@ public class TtsService extends Service implements OnCompletionListener {
private int setSpeechRate(String callingApp, int rate) {
- if (isDefaultEnforced()) {
- return sNativeSynth.setSpeechRate(getDefaultRate());
- } else {
- return sNativeSynth.setSpeechRate(rate);
+ int res = TextToSpeech.ERROR;
+ try {
+ if (isDefaultEnforced()) {
+ res = sNativeSynth.setSpeechRate(getDefaultRate());
+ } else {
+ res = sNativeSynth.setSpeechRate(rate);
+ }
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ res = TextToSpeech.ERROR;
}
+ return res;
}
private int setPitch(String callingApp, int pitch) {
- return sNativeSynth.setPitch(pitch);
+ int res = TextToSpeech.ERROR;
+ try {
+ res = sNativeSynth.setPitch(pitch);
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ res = TextToSpeech.ERROR;
+ }
+ return res;
}
private int isLanguageAvailable(String lang, String country, String variant) {
//Log.v("TtsService", "TtsService.isLanguageAvailable(" + lang + ", " + country + ", " +variant+")");
- return sNativeSynth.isLanguageAvailable(lang, country, variant);
+ int res = TextToSpeech.LANG_NOT_SUPPORTED;
+ try {
+ res = sNativeSynth.isLanguageAvailable(lang, country, variant);
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ res = TextToSpeech.LANG_NOT_SUPPORTED;
+ }
+ return res;
}
private String[] getLanguage() {
- return sNativeSynth.getLanguage();
+ try {
+ return sNativeSynth.getLanguage();
+ } catch (Exception e) {
+ return null;
+ }
}
private int setLanguage(String callingApp, String lang, String country, String variant) {
Log.v("TtsService", "TtsService.setLanguage(" + lang + ", " + country + ", " + variant + ")");
- if (isDefaultEnforced()) {
- return sNativeSynth.setLanguage(getDefaultLanguage(), getDefaultCountry(),
- getDefaultLocVariant());
- } else {
- return sNativeSynth.setLanguage(lang, country, variant);
+ int res = TextToSpeech.ERROR;
+ try {
+ if (isDefaultEnforced()) {
+ res = sNativeSynth.setLanguage(getDefaultLanguage(), getDefaultCountry(),
+ getDefaultLocVariant());
+ } else {
+ res = sNativeSynth.setLanguage(lang, country, variant);
+ }
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ res = TextToSpeech.ERROR;
}
+ return res;
}
@@ -402,7 +442,12 @@ public class TtsService extends Service implements OnCompletionListener {
}
if ((mCurrentSpeechItem != null) &&
mCurrentSpeechItem.mCallingApp.equals(callingApp)) {
- result = sNativeSynth.stop();
+ try {
+ result = sNativeSynth.stop();
+ } catch (NullPointerException e1) {
+ // synth will become null during onDestroy()
+ result = TextToSpeech.ERROR;
+ }
mKillList.put(mCurrentSpeechItem, true);
if (mPlayer != null) {
try {
@@ -434,7 +479,8 @@ public class TtsService extends Service implements OnCompletionListener {
/**
- * Stops all speech output and removes any utterances still in the queue globally.
+ * Stops all speech output and removes any utterances still in the queue globally, except
+ * those intended to be synthesized to file.
*/
private int stopAll(String callingApp) {
int result = TextToSpeech.ERROR;
@@ -451,7 +497,12 @@ public class TtsService extends Service implements OnCompletionListener {
if ((mCurrentSpeechItem != null) &&
((mCurrentSpeechItem.mType != SpeechItem.TEXT_TO_FILE) ||
mCurrentSpeechItem.mCallingApp.equals(callingApp))) {
- result = sNativeSynth.stop();
+ try {
+ result = sNativeSynth.stop();
+ } catch (NullPointerException e1) {
+ // synth will become null during onDestroy()
+ result = TextToSpeech.ERROR;
+ }
mKillList.put(mCurrentSpeechItem, true);
if (mPlayer != null) {
try {
@@ -591,7 +642,12 @@ public class TtsService extends Service implements OnCompletionListener {
if (speechRate.length() > 0){
setSpeechRate("", Integer.parseInt(speechRate));
}
- sNativeSynth.speak(speechItem.mText, streamType);
+ try {
+ sNativeSynth.speak(speechItem.mText, streamType);
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ Log.v("TtsService", " null synth, can't speak");
+ }
}
} catch (InterruptedException e) {
Log.e("TtsService", "TTS speakInternalOnly(): tryLock interrupted");
@@ -660,7 +716,12 @@ public class TtsService extends Service implements OnCompletionListener {
if (speechRate.length() > 0){
setSpeechRate("", Integer.parseInt(speechRate));
}
- sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
+ try {
+ sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
+ } catch (NullPointerException e) {
+ // synth will become null during onDestroy()
+ Log.v("TtsService", " null synth, can't synthesize to file");
+ }
}
} catch (InterruptedException e) {
Log.e("TtsService", "TTS synthToFileInternalOnly(): tryLock interrupted");