diff options
Diffstat (limited to 'chrome/browser/speech/extension_api')
7 files changed, 141 insertions, 195 deletions
diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_api.cc b/chrome/browser/speech/extension_api/tts_engine_extension_api.cc index de8e24d..4c9b8d5 100644 --- a/chrome/browser/speech/extension_api/tts_engine_extension_api.cc +++ b/chrome/browser/speech/extension_api/tts_engine_extension_api.cc @@ -12,6 +12,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/speech/extension_api/tts_extension_api.h" #include "chrome/browser/speech/extension_api/tts_extension_api_constants.h" #include "chrome/browser/speech/tts_controller.h" #include "chrome/common/extensions/api/speech/tts_engine_manifest_handler.h" @@ -26,17 +27,6 @@ const char kOnSpeak[] = "ttsEngine.onSpeak"; const char kOnStop[] = "ttsEngine.onStop"; }; // namespace tts_engine_events -namespace { -// Given a language/region code of the form 'fr-FR', returns just the basic -// language portion, e.g. 'fr'. -std::string TrimLanguageCode(std::string lang) { - if (lang.size() >= 5 && lang[2] == '-') - return lang.substr(0, 2); - else - return lang; -} -} - void GetExtensionVoices(Profile* profile, std::vector<VoiceData>* out_voices) { ExtensionService* service = profile->GetExtensionService(); DCHECK(service); @@ -67,139 +57,40 @@ void GetExtensionVoices(Profile* profile, std::vector<VoiceData>* out_voices) { out_voices->push_back(VoiceData()); VoiceData& result_voice = out_voices->back(); + result_voice.native = false; result_voice.name = voice.voice_name; result_voice.lang = voice.lang; - result_voice.gender = voice.gender; result_voice.extension_id = extension->id(); + if (voice.gender == constants::kGenderMale) + result_voice.gender = TTS_GENDER_MALE; + else if (voice.gender == constants::kGenderFemale) + result_voice.gender = TTS_GENDER_FEMALE; + else + result_voice.gender = TTS_GENDER_NONE; for (std::set<std::string>::const_iterator iter = voice.event_types.begin(); iter != voice.event_types.end(); ++iter) { - result_voice.events.push_back(*iter); + result_voice.events.insert(TtsEventTypeFromString(*iter)); } // If the extension sends end events, the controller will handle // queueing and send interrupted and cancelled events. if (voice.event_types.find(constants::kEventTypeEnd) != voice.event_types.end()) { - result_voice.events.push_back(constants::kEventTypeCancelled); - result_voice.events.push_back(constants::kEventTypeInterrupted); - } - } - } -} - -bool GetMatchingExtensionVoice( - Utterance* utterance, - const Extension** matching_extension, - size_t* voice_index) { - // This will only happen during unit testing. Otherwise, an utterance - // will always have an associated profile. - if (!utterance->profile()) - return false; - - ExtensionService* service = utterance->profile()->GetExtensionService(); - - // If speech is generated when Chrome OS first starts up, it's possible - // the extension service isn't even available. - if (!service) - return false; - - extensions::EventRouter* event_router = - extensions::ExtensionSystem::Get(utterance->profile())->event_router(); - DCHECK(event_router); - - *matching_extension = NULL; - *voice_index = -1; - const ExtensionSet* extensions = service->extensions(); - ExtensionSet::const_iterator iter; - - // Make two passes: the first time, do strict language matching - // ('fr-FR' does not match 'fr-CA'). The second time, do prefix - // language matching ('fr-FR' matches 'fr' and 'fr-CA') - for (int pass = 0; pass < 2; ++pass) { - for (iter = extensions->begin(); iter != extensions->end(); ++iter) { - const Extension* extension = *iter; - - if (!event_router->ExtensionHasEventListener( - extension->id(), tts_engine_events::kOnSpeak) || - !event_router->ExtensionHasEventListener( - extension->id(), tts_engine_events::kOnStop)) { - continue; - } - - if (!utterance->extension_id().empty() && - utterance->extension_id() != extension->id()) { - continue; - } - - const std::vector<extensions::TtsVoice>* tts_voices = - extensions::TtsVoice::GetTtsVoices(extension); - if (!tts_voices) - continue; - - for (size_t i = 0; i < tts_voices->size(); ++i) { - const extensions::TtsVoice& voice = tts_voices->at(i); - if (!voice.voice_name.empty() && - !utterance->voice_name().empty() && - voice.voice_name != utterance->voice_name()) { - continue; - } - if (!voice.lang.empty() && !utterance->lang().empty()) { - std::string voice_lang = voice.lang; - std::string utterance_lang = utterance->lang(); - if (pass == 1) { - voice_lang = TrimLanguageCode(voice_lang); - utterance_lang = TrimLanguageCode(utterance_lang); - } - if (voice_lang != utterance_lang) - continue; - } - if (!voice.gender.empty() && - !utterance->gender().empty() && - voice.gender != utterance->gender()) { - continue; - } - if (utterance->required_event_types().size() > 0) { - bool has_all_required_event_types = true; - for (std::set<std::string>::const_iterator iter = - utterance->required_event_types().begin(); - iter != utterance->required_event_types().end(); - ++iter) { - if (voice.event_types.find(*iter) == voice.event_types.end()) { - has_all_required_event_types = false; - break; - } - } - if (!has_all_required_event_types) - continue; - } - - *matching_extension = extension; - *voice_index = i; - return true; + result_voice.events.insert(TTS_EVENT_CANCELLED); + result_voice.events.insert(TTS_EVENT_INTERRUPTED); } } } - - return false; } -void ExtensionTtsEngineSpeak(Utterance* utterance, - const Extension* extension, - size_t voice_index) { +void ExtensionTtsEngineSpeak(Utterance* utterance, const VoiceData& voice) { // See if the engine supports the "end" event; if so, we can keep the // utterance around and track it. If not, we're finished with this // utterance now. - const std::vector<extensions::TtsVoice>* tts_voices = - extensions::TtsVoice::GetTtsVoices(extension); - std::set<std::string> event_types; - if (tts_voices) - event_types = tts_voices->at(voice_index).event_types; - - bool sends_end_event = - (event_types.find(constants::kEventTypeEnd) != event_types.end()); + bool sends_end_event = voice.events.find(TTS_EVENT_END) != voice.events.end(); scoped_ptr<ListValue> args(new ListValue()); args->Set(0, Value::CreateStringValue(utterance->text())); diff --git a/chrome/browser/speech/extension_api/tts_engine_extension_api.h b/chrome/browser/speech/extension_api/tts_engine_extension_api.h index 80bb122..b87de3a 100644 --- a/chrome/browser/speech/extension_api/tts_engine_extension_api.h +++ b/chrome/browser/speech/extension_api/tts_engine_extension_api.h @@ -41,8 +41,7 @@ bool GetMatchingExtensionVoice(Utterance* utterance, // Speak the given utterance by sending an event to the given TTS engine // extension voice. void ExtensionTtsEngineSpeak(Utterance* utterance, - const extensions::Extension* extension, - size_t voice_index); + const VoiceData& voice); // Stop speaking the given utterance by sending an event to the extension // associated with this utterance. diff --git a/chrome/browser/speech/extension_api/tts_extension_api.cc b/chrome/browser/speech/extension_api/tts_extension_api.cc index 177bad6..117bf732 100644 --- a/chrome/browser/speech/extension_api/tts_extension_api.cc +++ b/chrome/browser/speech/extension_api/tts_extension_api.cc @@ -22,33 +22,51 @@ namespace events { const char kOnEvent[] = "tts.onEvent"; }; // namespace events -namespace { - const char *TtsEventTypeToString(TtsEventType event_type) { switch (event_type) { - case TTS_EVENT_START: - return constants::kEventTypeStart; - case TTS_EVENT_END: - return constants::kEventTypeEnd; - case TTS_EVENT_WORD: - return constants::kEventTypeWord; - case TTS_EVENT_SENTENCE: - return constants::kEventTypeSentence; - case TTS_EVENT_MARKER: - return constants::kEventTypeMarker; - case TTS_EVENT_INTERRUPTED: - return constants::kEventTypeInterrupted; - case TTS_EVENT_CANCELLED: - return constants::kEventTypeCancelled; - case TTS_EVENT_ERROR: - return constants::kEventTypeError; - default: - NOTREACHED(); - return ""; + case TTS_EVENT_START: + return constants::kEventTypeStart; + case TTS_EVENT_END: + return constants::kEventTypeEnd; + case TTS_EVENT_WORD: + return constants::kEventTypeWord; + case TTS_EVENT_SENTENCE: + return constants::kEventTypeSentence; + case TTS_EVENT_MARKER: + return constants::kEventTypeMarker; + case TTS_EVENT_INTERRUPTED: + return constants::kEventTypeInterrupted; + case TTS_EVENT_CANCELLED: + return constants::kEventTypeCancelled; + case TTS_EVENT_ERROR: + return constants::kEventTypeError; + default: + NOTREACHED(); + return constants::kEventTypeError; } } -} // anonymous namespace +TtsEventType TtsEventTypeFromString(const std::string& str) { + if (str == constants::kEventTypeStart) + return TTS_EVENT_START; + if (str == constants::kEventTypeEnd) + return TTS_EVENT_END; + if (str == constants::kEventTypeWord) + return TTS_EVENT_WORD; + if (str == constants::kEventTypeSentence) + return TTS_EVENT_SENTENCE; + if (str == constants::kEventTypeMarker) + return TTS_EVENT_MARKER; + if (str == constants::kEventTypeInterrupted) + return TTS_EVENT_INTERRUPTED; + if (str == constants::kEventTypeCancelled) + return TTS_EVENT_CANCELLED; + if (str == constants::kEventTypeError) + return TTS_EVENT_ERROR; + + NOTREACHED(); + return TTS_EVENT_ERROR; +} namespace extensions { @@ -69,15 +87,14 @@ void TtsExtensionEventHandler::OnTtsEvent(Utterance* utterance, if (utterance->src_id() < 0) return; - std::string event_type_string = TtsEventTypeToString(event_type); - const std::set<std::string>& desired_event_types = + const std::set<TtsEventType>& desired_event_types = utterance->desired_event_types(); if (desired_event_types.size() > 0 && - desired_event_types.find(event_type_string) == - desired_event_types.end()) { + desired_event_types.find(event_type) == desired_event_types.end()) { return; } + const char *event_type_string = TtsEventTypeToString(event_type); scoped_ptr<DictionaryValue> details(new DictionaryValue()); if (char_index >= 0) details->SetInteger(constants::kCharIndexKey, char_index); @@ -132,13 +149,18 @@ bool TtsSpeakFunction::RunImpl() { return false; } - std::string gender; + std::string gender_str; + TtsGenderType gender; if (options->HasKey(constants::kGenderKey)) EXTENSION_FUNCTION_VALIDATE( - options->GetString(constants::kGenderKey, &gender)); - if (!gender.empty() && - gender != constants::kGenderFemale && - gender != constants::kGenderMale) { + options->GetString(constants::kGenderKey, &gender_str)); + if (gender_str == constants::kGenderMale) { + gender = TTS_GENDER_MALE; + } else if (gender_str == constants::kGenderFemale) { + gender = TTS_GENDER_FEMALE; + } else if (gender_str.empty()) { + gender = TTS_GENDER_NONE; + } else { error_ = constants::kErrorInvalidGender; return false; } @@ -179,27 +201,27 @@ bool TtsSpeakFunction::RunImpl() { options->GetBoolean(constants::kEnqueueKey, &can_enqueue)); } - std::set<std::string> required_event_types; + std::set<TtsEventType> required_event_types; if (options->HasKey(constants::kRequiredEventTypesKey)) { ListValue* list; EXTENSION_FUNCTION_VALIDATE( options->GetList(constants::kRequiredEventTypesKey, &list)); for (size_t i = 0; i < list->GetSize(); ++i) { std::string event_type; - if (!list->GetString(i, &event_type)) - required_event_types.insert(event_type); + if (list->GetString(i, &event_type)) + required_event_types.insert(TtsEventTypeFromString(event_type.c_str())); } } - std::set<std::string> desired_event_types; + std::set<TtsEventType> desired_event_types; if (options->HasKey(constants::kDesiredEventTypesKey)) { ListValue* list; EXTENSION_FUNCTION_VALIDATE( options->GetList(constants::kDesiredEventTypesKey, &list)); for (size_t i = 0; i < list->GetSize(); ++i) { std::string event_type; - if (!list->GetString(i, &event_type)) - desired_event_types.insert(event_type); + if (list->GetString(i, &event_type)) + desired_event_types.insert(TtsEventTypeFromString(event_type.c_str())); } } @@ -269,14 +291,46 @@ bool TtsGetVoicesFunction::RunImpl() { result_voice->SetString(constants::kVoiceNameKey, voice.name); if (!voice.lang.empty()) result_voice->SetString(constants::kLangKey, voice.lang); - if (!voice.gender.empty()) - result_voice->SetString(constants::kGenderKey, voice.gender); + if (voice.gender == TTS_GENDER_MALE) + result_voice->SetString(constants::kGenderKey, constants::kGenderMale); + else if (voice.gender == TTS_GENDER_FEMALE) + result_voice->SetString(constants::kGenderKey, constants::kGenderFemale); if (!voice.extension_id.empty()) result_voice->SetString(constants::kExtensionIdKey, voice.extension_id); ListValue* event_types = new ListValue(); - for (size_t j = 0; j < voice.events.size(); ++j) - event_types->Append(Value::CreateStringValue(voice.events[j])); + for (std::set<TtsEventType>::iterator iter = voice.events.begin(); + iter != voice.events.end(); ++iter) { + const char* event_name_constant = NULL; + switch (*iter) { + case TTS_EVENT_START: + event_name_constant = constants::kEventTypeStart; + break; + case TTS_EVENT_END: + event_name_constant = constants::kEventTypeEnd; + break; + case TTS_EVENT_WORD: + event_name_constant = constants::kEventTypeWord; + break; + case TTS_EVENT_SENTENCE: + event_name_constant = constants::kEventTypeSentence; + break; + case TTS_EVENT_MARKER: + event_name_constant = constants::kEventTypeMarker; + break; + case TTS_EVENT_INTERRUPTED: + event_name_constant = constants::kEventTypeInterrupted; + break; + case TTS_EVENT_CANCELLED: + event_name_constant = constants::kEventTypeCancelled; + break; + case TTS_EVENT_ERROR: + event_name_constant = constants::kEventTypeError; + break; + } + if (event_name_constant) + event_types->Append(Value::CreateStringValue(event_name_constant)); + } result_voice->Set(constants::kEventTypesKey, event_types); result_voices->Append(result_voice); diff --git a/chrome/browser/speech/extension_api/tts_extension_api.h b/chrome/browser/speech/extension_api/tts_extension_api.h index 6d5b4ee..a70d95e 100644 --- a/chrome/browser/speech/extension_api/tts_extension_api.h +++ b/chrome/browser/speech/extension_api/tts_extension_api.h @@ -13,6 +13,9 @@ class Profile; +const char *TtsEventTypeToString(TtsEventType event_type); +TtsEventType TtsEventTypeFromString(const std::string& str); + namespace extensions { class TtsSpeakFunction diff --git a/chrome/browser/speech/extension_api/tts_extension_api_constants.cc b/chrome/browser/speech/extension_api/tts_extension_api_constants.cc index bf6e057..3568a8d 100644 --- a/chrome/browser/speech/extension_api/tts_extension_api_constants.cc +++ b/chrome/browser/speech/extension_api/tts_extension_api_constants.cc @@ -36,8 +36,6 @@ const char kEventTypeInterrupted[] = "interrupted"; const char kEventTypeCancelled[] = "cancelled"; const char kEventTypeError[] = "error"; -const char kNativeVoiceName[] = "native"; - const char kErrorUndeclaredEventType[] = "Cannot send an event type that is not declared in the extension manifest."; const char kErrorUtteranceTooLong[] = "Utterance length is too long."; diff --git a/chrome/browser/speech/extension_api/tts_extension_api_constants.h b/chrome/browser/speech/extension_api/tts_extension_api_constants.h index 760fcf0..3270e97 100644 --- a/chrome/browser/speech/extension_api/tts_extension_api_constants.h +++ b/chrome/browser/speech/extension_api/tts_extension_api_constants.h @@ -41,8 +41,6 @@ extern const char kEventTypeInterrupted[]; extern const char kEventTypeCancelled[]; extern const char kEventTypeError[]; -extern const char kNativeVoiceName[]; - extern const char kErrorUndeclaredEventType[]; extern const char kErrorUtteranceTooLong[]; extern const char kErrorInvalidLang[]; diff --git a/chrome/browser/speech/extension_api/tts_extension_apitest.cc b/chrome/browser/speech/extension_api/tts_extension_apitest.cc index d865190..e704f5d 100644 --- a/chrome/browser/speech/extension_api/tts_extension_apitest.cc +++ b/chrome/browser/speech/extension_api/tts_extension_apitest.cc @@ -36,21 +36,19 @@ class MockTtsPlatformImpl : public TtsPlatformImpl { return true; } - virtual bool SendsEvent(TtsEventType event_type) { - return (event_type == TTS_EVENT_END || - event_type == TTS_EVENT_WORD); - } - - - MOCK_METHOD4(Speak, + MOCK_METHOD5(Speak, bool(int utterance_id, const std::string& utterance, const std::string& lang, + const VoiceData& voice, const UtteranceContinuousParameters& params)); + MOCK_METHOD0(StopSpeaking, bool(void)); MOCK_METHOD0(IsSpeaking, bool(void)); + MOCK_METHOD1(GetVoices, void(std::vector<VoiceData>*)); + void SetErrorToEpicFail() { set_error("epic fail"); } @@ -58,6 +56,7 @@ class MockTtsPlatformImpl : public TtsPlatformImpl { void SendEndEvent(int utterance_id, const std::string& utterance, const std::string& lang, + const VoiceData& voice, const UtteranceContinuousParameters& params) { MessageLoop::current()->PostDelayedTask( FROM_HERE, base::Bind( @@ -72,6 +71,7 @@ class MockTtsPlatformImpl : public TtsPlatformImpl { int utterance_id, const std::string& utterance, const std::string& lang, + const VoiceData& voice, const UtteranceContinuousParameters& params) { MessageLoop::current()->PostDelayedTask( FROM_HERE, base::Bind( @@ -84,6 +84,7 @@ class MockTtsPlatformImpl : public TtsPlatformImpl { void SendWordEvents(int utterance_id, const std::string& utterance, const std::string& lang, + const VoiceData& voice, const UtteranceContinuousParameters& params) { for (int i = 0; i < static_cast<int>(utterance.size()); i++) { if (i == 0 || utterance[i - 1] == ' ') { @@ -126,6 +127,8 @@ class TtsApiTest : public ExtensionApiTest { virtual void SetUpInProcessBrowserTestFixture() { ExtensionApiTest::SetUpInProcessBrowserTestFixture(); TtsController::GetInstance()->SetPlatformImpl(&mock_platform_impl_); + EXPECT_CALL(mock_platform_impl_, GetVoices(_)) + .Times(AnyNumber()); } protected: @@ -138,23 +141,23 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakOptionalArgs) { InSequence s; EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "", _, _, _)) .WillOnce(Return(true)); EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "Alpha", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "Alpha", _, _, _)) .WillOnce(Return(true)); EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "Bravo", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "Bravo", _, _, _)) .WillOnce(Return(true)); EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "Charlie", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "Charlie", _, _, _)) .WillOnce(Return(true)); EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "Echo", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "Echo", _, _, _)) .WillOnce(Return(true)); ASSERT_TRUE(RunExtensionTest("tts/optional_args")) << message_; } @@ -164,7 +167,7 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakFinishesImmediately) { EXPECT_CALL(mock_platform_impl_, IsSpeaking()); EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendEndEvent), @@ -179,12 +182,12 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakInterrupt) { InSequence s; EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "text 1", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "text 1", _, _, _)) .WillOnce(Return(true)); // Expect the second utterance and allow it to finish. EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "text 2", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "text 2", _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendEndEvent), @@ -196,18 +199,18 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakQueueInterrupt) { EXPECT_CALL(mock_platform_impl_, IsSpeaking()); // In this test, two utterances are queued, and then a third - // interrupts. Speak() never gets called on the second utterance. + // interrupts. Speak(, _) never gets called on the second utterance. InSequence s; EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "text 1", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "text 1", _, _, _)) .WillOnce(Return(true)); // Don't expect the second utterance, because it's queued up and the // first never finishes. // Expect the third utterance and allow it to finish successfully. EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "text 3", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "text 3", _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendEndEvent), @@ -221,12 +224,12 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakEnqueue) { InSequence s; EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "text 1", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "text 1", _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendEndEventWhenQueueNotEmpty), Return(true))); - EXPECT_CALL(mock_platform_impl_, Speak(_, "text 2", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "text 2", _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendEndEvent), @@ -241,7 +244,7 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakError) { InSequence s; EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "first try", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "first try", _, _, _)) .WillOnce(DoAll( InvokeWithoutArgs( CreateFunctor(&mock_platform_impl_, @@ -249,7 +252,7 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakError) { Return(false))); EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "second try", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "second try", _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendEndEvent), @@ -263,7 +266,7 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformWordCallbacks) { InSequence s; EXPECT_CALL(mock_platform_impl_, StopSpeaking()) .WillOnce(Return(true)); - EXPECT_CALL(mock_platform_impl_, Speak(_, "one two three", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "one two three", _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendWordEvents), @@ -281,17 +284,17 @@ IN_PROC_BROWSER_TEST_F(TtsApiTest, RegisterEngine) { { InSequence s; - EXPECT_CALL(mock_platform_impl_, Speak(_, "native speech", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "native speech", _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendEndEvent), Return(true))); - EXPECT_CALL(mock_platform_impl_, Speak(_, "native speech 2", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "native speech 2", _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendEndEvent), Return(true))); - EXPECT_CALL(mock_platform_impl_, Speak(_, "native speech 3", _, _)) + EXPECT_CALL(mock_platform_impl_, Speak(_, "native speech 3", _, _, _)) .WillOnce(DoAll( Invoke(&mock_platform_impl_, &MockTtsPlatformImpl::SendEndEvent), |