summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordtseng@chromium.org <dtseng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-27 18:12:07 +0000
committerdtseng@chromium.org <dtseng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-27 18:12:07 +0000
commit7f239f3c052dafe64f3dd415841756c84043a080 (patch)
tree38b6b66552d786bc5a106619631cd24e18604fe6
parent66330032024b94e9d794e76cee72505d4340717e (diff)
downloadchromium_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
-rw-r--r--chrome/browser/speech/extension_api/tts_extension_apitest.cc28
-rw-r--r--chrome/browser/speech/tts_controller.cc34
-rw-r--r--chrome/test/data/extensions/api_test/tts_engine/register_engine/test.js5
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();
});
}