Browse Source

Fix a Parcel `collection == null` exception.

This is caused by the Voice features being set to null. The fix in
Android Marshmallow is to make onGetFeaturesForLanguage return an
empty HashSet object. This does not work for eSpeak because:

  1.  eSpeak was overriding onGetVoices and initializing each Voice's
      features to null;

  2.  the bug is still present on Lollipop.

Thus, the fix here is two-fold:

  1.  make onGetVoices use onGetFeaturesForLanguage;

  2.  make onGetFeaturesForLanguage return an empty HashSet, so that
      eSpeak does not crash on Lollipop either.
master
Reece H. Dunn 9 years ago
parent
commit
c094f4840b

+ 9
- 0
android/eSpeakTests/src/com/reecedunn/espeak/test/TextToSpeechServiceTest.java View File

@@ -26,6 +26,7 @@ import com.reecedunn.espeak.TtsService;
import com.reecedunn.espeak.Voice;

import java.util.Locale;
import java.util.Set;

import static com.reecedunn.espeak.test.TtsMatcher.isTtsLangCode;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -52,6 +53,10 @@ public class TextToSpeechServiceTest extends AndroidTestCase
return super.onLoadLanguage(language, country, variant);
}

public Set<String> onGetFeaturesForLanguage(String language, String country, String variant) {
return super.onGetFeaturesForLanguage(language, country, variant);
}

public Voice getActiveVoice() {
return mMatchingVoice;
}
@@ -242,6 +247,10 @@ public class TextToSpeechServiceTest extends AndroidTestCase
assertThat(locale.getISO3Language(), is(data.javaLanguage));
assertThat(locale.getISO3Country(), is(data.javaCountry));
assertThat(locale.getVariant(), is(data.variant));

Set<String> features = mService.onGetFeaturesForLanguage(data.javaLanguage, data.javaCountry, data.variant);
assertThat(features, is(notNullValue()));
assertThat(features.size(), is(0));
}
}
}

+ 4
- 2
android/eSpeakTests/src/com/reecedunn/espeak/test/TextToSpeechTest.java View File

@@ -126,7 +126,8 @@ public class TextToSpeechTest extends TextToSpeechTestCase
assertThat(voice.getLocale().getLanguage(), is(data.javaLanguage));
assertThat(voice.getLocale().getCountry(), is(data.javaCountry));
assertThat(voice.getLocale().getVariant(), is(data.variant));
assertThat(voice.getFeatures(), is(nullValue()));
assertThat(voice.getFeatures(), is(notNullValue()));
assertThat(voice.getFeatures().size(), is(0));
assertThat(voice.getLatency(), is(android.speech.tts.Voice.LATENCY_VERY_LOW));
assertThat(voice.getQuality(), is(android.speech.tts.Voice.QUALITY_NORMAL));

@@ -141,7 +142,8 @@ public class TextToSpeechTest extends TextToSpeechTestCase
assertThat(voice2.getLocale().getLanguage(), is(data.javaLanguage));
assertThat(voice2.getLocale().getCountry(), is(data.javaCountry));
assertThat(voice2.getLocale().getVariant(), is(data.variant));
assertThat(voice2.getFeatures(), is(nullValue()));
assertThat(voice2.getFeatures(), is(notNullValue()));
assertThat(voice2.getFeatures().size(), is(0));
assertThat(voice2.getLatency(), is(android.speech.tts.Voice.LATENCY_VERY_LOW));
assertThat(voice2.getQuality(), is(android.speech.tts.Voice.QUALITY_NORMAL));
}

+ 10
- 1
android/src/com/reecedunn/espeak/TtsService.java View File

@@ -44,9 +44,11 @@ import com.reecedunn.espeak.SpeechSynthesis.SynthReadyCallback;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/**
* Implements the eSpeak engine as a {@link TextToSpeechService}.
@@ -199,6 +201,11 @@ public class TtsService extends TextToSpeechService {
return match.second;
}

@Override
protected Set<String> onGetFeaturesForLanguage(String lang, String country, String variant) {
return new HashSet<String>();
}

@Override
public String onGetDefaultVoiceNameFor(String language, String country, String variant) {
final Voice match = getDefaultVoiceFor(language, country, variant).first;
@@ -211,7 +218,9 @@ public class TtsService extends TextToSpeechService {
for (Voice voice : mAvailableVoices.values()) {
int quality = android.speech.tts.Voice.QUALITY_NORMAL;
int latency = android.speech.tts.Voice.LATENCY_VERY_LOW;
voices.add(new android.speech.tts.Voice(voice.name, new Locale(voice.locale.getISO3Language(), voice.locale.getISO3Country(), voice.locale.getVariant()), quality, latency, false, null));
Locale locale = new Locale(voice.locale.getISO3Language(), voice.locale.getISO3Country(), voice.locale.getVariant());
Set<String> features = onGetFeaturesForLanguage(locale.getLanguage(), locale.getCountry(), locale.getVariant());
voices.add(new android.speech.tts.Voice(voice.name, locale, quality, latency, false, features));
}
return voices;
}

Loading…
Cancel
Save