diff options
author | dtseng@chromium.org <dtseng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-27 18:12:07 +0000 |
---|---|---|
committer | dtseng@chromium.org <dtseng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-27 18:12:07 +0000 |
commit | 7f239f3c052dafe64f3dd415841756c84043a080 (patch) | |
tree | 38b6b66552d786bc5a106619631cd24e18604fe6 | |
parent | 66330032024b94e9d794e76cee72505d4340717e (diff) | |
download | chromium_src-7f239f3c052dafe64f3dd415841756c84043a080.zip chromium_src-7f239f3c052dafe64f3dd415841756c84043a080.tar.gz chromium_src-7f239f3c052dafe64f3dd415841756c84043a080.tar.bz2 |
Gracefully fall back to a reasonable voice when a non-existent voice name is supplied.
BUG=346709
Review URL: https://codereview.chromium.org/176923014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253863 0039d316-1c4b-4281-b951-d872f2087c98
3 files changed, 55 insertions, 12 deletions
diff --git a/chrome/browser/speech/extension_api/tts_extension_apitest.cc b/chrome/browser/speech/extension_api/tts_extension_apitest.cc index 381117c..480a2f0 100644 --- a/chrome/browser/speech/extension_api/tts_extension_apitest.cc +++ b/chrome/browser/speech/extension_api/tts_extension_apitest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <vector> + #include "base/bind.h" #include "base/command_line.h" #include "base/memory/weak_ptr.h" @@ -25,10 +27,12 @@ using ::testing::AnyNumber; using ::testing::CreateFunctor; using ::testing::DoAll; +using ::testing::Invoke; using ::testing::InSequence; using ::testing::InvokeWithoutArgs; using ::testing::Return; using ::testing::SaveArg; +using ::testing::SetArgPointee; using ::testing::StrictMock; using ::testing::_; @@ -41,7 +45,8 @@ namespace extensions { class MockTtsPlatformImpl : public TtsPlatformImpl { public: MockTtsPlatformImpl() - : ptr_factory_(this) {} + : ptr_factory_(this), + should_fake_get_voices_(false) {} virtual bool PlatformImplAvailable() { return true; @@ -62,7 +67,21 @@ class MockTtsPlatformImpl : public TtsPlatformImpl { MOCK_METHOD0(IsSpeaking, bool(void)); - MOCK_METHOD1(GetVoices, void(std::vector<VoiceData>*)); + // Fake this method to add a native voice. + void GetVoices(std::vector<VoiceData>* voices) { + if (!should_fake_get_voices_) + return; + + VoiceData voice; + voice.name = "TestNativeVoice"; + voice.native = true; + voice.lang = "en-GB"; + voice.events.insert(TTS_EVENT_START); + voice.events.insert(TTS_EVENT_END); + voices->push_back(voice); + } + + void set_should_fake_get_voices(bool val) { should_fake_get_voices_ = val; } void SetErrorToEpicFail() { set_error("epic fail"); @@ -144,6 +163,7 @@ class MockTtsPlatformImpl : public TtsPlatformImpl { private: base::WeakPtrFactory<MockTtsPlatformImpl> ptr_factory_; + bool should_fake_get_voices_; }; class FakeNetworkOnlineStateForTest : public net::NetworkChangeNotifier { @@ -167,8 +187,6 @@ class TtsApiTest : public ExtensionApiTest { virtual void SetUpInProcessBrowserTestFixture() { ExtensionApiTest::SetUpInProcessBrowserTestFixture(); TtsController::GetInstance()->SetPlatformImpl(&mock_platform_impl_); - EXPECT_CALL(mock_platform_impl_, GetVoices(_)) - .Times(AnyNumber()); } protected: @@ -346,6 +364,8 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformPauseResume) { // IN_PROC_BROWSER_TEST_F(TtsApiTest, RegisterEngine) { + mock_platform_impl_.set_should_fake_get_voices(true); + EXPECT_CALL(mock_platform_impl_, IsSpeaking()) .Times(AnyNumber()); EXPECT_CALL(mock_platform_impl_, StopSpeaking()) diff --git a/chrome/browser/speech/tts_controller.cc b/chrome/browser/speech/tts_controller.cc index 503786d..6d749f3 100644 --- a/chrome/browser/speech/tts_controller.cc +++ b/chrome/browser/speech/tts_controller.cc @@ -9,6 +9,7 @@ #include "base/float_util.h" #include "base/values.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/speech/extension_api/tts_engine_extension_api.h" #include "chrome/browser/speech/extension_api/tts_extension_api.h" @@ -155,15 +156,34 @@ void TtsController::SpeakNow(Utterance* utterance) { GetVoices(utterance->profile(), &voices); int index = GetMatchingVoice(utterance, voices); - // Select the matching voice, but if none was found, initialize an - // empty VoiceData with native = true, which will give the native - // speech synthesizer a chance to try to synthesize the utterance - // anyway. VoiceData voice; - if (index >= 0 && index < static_cast<int>(voices.size())) + if (index != -1) { + // Select the matching voice. voice = voices[index]; - else - voice.native = true; + } else { + // However, if no match was found on a platform without native tts voices, + // attempt to get a voice based only on the current locale without respect + // to any supplied voice names. + std::vector<VoiceData> native_voices; + + if (GetPlatformImpl()->PlatformImplAvailable()) + GetPlatformImpl()->GetVoices(&native_voices); + + if (native_voices.empty() && !voices.empty()) { + // TODO(dtseng): Notify extension caller of an error. + utterance->set_voice_name(""); + utterance->set_lang(g_browser_process->GetApplicationLocale()); + index = GetMatchingVoice(utterance, voices); + + // If even that fails, just take the first available voice. + if (index == -1) + index = 0; + voice = voices[index]; + } else { + // Otherwise, simply give native voices a chance to handle this utterance. + voice.native = true; + } + } GetPlatformImpl()->WillSpeakUtteranceWithVoice(utterance, voice); diff --git a/chrome/test/data/extensions/api_test/tts_engine/register_engine/test.js b/chrome/test/data/extensions/api_test/tts_engine/register_engine/test.js index 99f1bd9..cd40303 100644 --- a/chrome/test/data/extensions/api_test/tts_engine/register_engine/test.js +++ b/chrome/test/data/extensions/api_test/tts_engine/register_engine/test.js @@ -146,7 +146,7 @@ chrome.test.runTests([ chrome.ttsEngine.onStop.addListener(stopListener); chrome.tts.getVoices(function(voices) { - chrome.test.assertEq(2, voices.length); + chrome.test.assertEq(3, voices.length); chrome.test.assertEq('Alice', voices[0].voiceName); chrome.test.assertEq('en-US', voices[0].lang); @@ -154,6 +154,9 @@ chrome.test.runTests([ chrome.test.assertEq('Pat', voices[1].voiceName); chrome.test.assertEq('en-US', voices[1].lang); + + chrome.test.assertEq('TestNativeVoice', voices[2].voiceName); + chrome.test.assertEq('en-GB', voices[2].lang); chrome.test.succeed(); }); } |