Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / speech / extension_api / tts_extension_apitest.cc
blob2fe5f52ef4565a5a1f0380f54b2ca14cdeb6eaee
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/command_line.h"
7 #include "base/memory/weak_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "chrome/browser/extensions/component_loader.h"
10 #include "chrome/browser/extensions/extension_apitest.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/extension_system.h"
13 #include "chrome/browser/speech/extension_api/tts_extension_api.h"
14 #include "chrome/browser/speech/tts_controller.h"
15 #include "chrome/browser/speech/tts_platform.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "net/base/network_change_notifier.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 // Needed for CreateFunctor.
22 #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING
23 #include "testing/gmock_mutant.h"
25 using ::testing::AnyNumber;
26 using ::testing::CreateFunctor;
27 using ::testing::DoAll;
28 using ::testing::InSequence;
29 using ::testing::InvokeWithoutArgs;
30 using ::testing::Return;
31 using ::testing::SaveArg;
32 using ::testing::StrictMock;
33 using ::testing::_;
35 namespace {
36 int g_saved_utterance_id;
39 namespace extensions {
41 class MockTtsPlatformImpl : public TtsPlatformImpl {
42 public:
43 MockTtsPlatformImpl()
44 : ptr_factory_(this) {}
46 virtual bool PlatformImplAvailable() {
47 return true;
50 MOCK_METHOD5(Speak,
51 bool(int utterance_id,
52 const std::string& utterance,
53 const std::string& lang,
54 const VoiceData& voice,
55 const UtteranceContinuousParameters& params));
57 MOCK_METHOD0(StopSpeaking, bool(void));
59 MOCK_METHOD0(Pause, void(void));
61 MOCK_METHOD0(Resume, void(void));
63 MOCK_METHOD0(IsSpeaking, bool(void));
65 MOCK_METHOD1(GetVoices, void(std::vector<VoiceData>*));
67 void SetErrorToEpicFail() {
68 set_error("epic fail");
71 void SendEndEventOnSavedUtteranceId() {
72 base::MessageLoop::current()->PostDelayedTask(
73 FROM_HERE, base::Bind(
74 &MockTtsPlatformImpl::SendEvent,
75 ptr_factory_.GetWeakPtr(),
76 false, g_saved_utterance_id, TTS_EVENT_END, 0, std::string()),
77 base::TimeDelta());
80 void SendEndEvent(int utterance_id,
81 const std::string& utterance,
82 const std::string& lang,
83 const VoiceData& voice,
84 const UtteranceContinuousParameters& params) {
85 base::MessageLoop::current()->PostDelayedTask(
86 FROM_HERE, base::Bind(
87 &MockTtsPlatformImpl::SendEvent,
88 ptr_factory_.GetWeakPtr(),
89 false, utterance_id, TTS_EVENT_END, utterance.size(),
90 std::string()),
91 base::TimeDelta());
94 void SendEndEventWhenQueueNotEmpty(
95 int utterance_id,
96 const std::string& utterance,
97 const std::string& lang,
98 const VoiceData& voice,
99 const UtteranceContinuousParameters& params) {
100 base::MessageLoop::current()->PostDelayedTask(
101 FROM_HERE, base::Bind(
102 &MockTtsPlatformImpl::SendEvent,
103 ptr_factory_.GetWeakPtr(),
104 true, utterance_id, TTS_EVENT_END, utterance.size(), std::string()),
105 base::TimeDelta());
108 void SendWordEvents(int utterance_id,
109 const std::string& utterance,
110 const std::string& lang,
111 const VoiceData& voice,
112 const UtteranceContinuousParameters& params) {
113 for (int i = 0; i < static_cast<int>(utterance.size()); i++) {
114 if (i == 0 || utterance[i - 1] == ' ') {
115 base::MessageLoop::current()->PostDelayedTask(
116 FROM_HERE, base::Bind(
117 &MockTtsPlatformImpl::SendEvent,
118 ptr_factory_.GetWeakPtr(),
119 false, utterance_id, TTS_EVENT_WORD, i,
120 std::string()),
121 base::TimeDelta());
126 void SendEvent(bool wait_for_non_empty_queue,
127 int utterance_id,
128 TtsEventType event_type,
129 int char_index,
130 const std::string& message) {
131 TtsController* controller = TtsController::GetInstance();
132 if (wait_for_non_empty_queue && controller->QueueSize() == 0) {
133 base::MessageLoop::current()->PostDelayedTask(
134 FROM_HERE, base::Bind(
135 &MockTtsPlatformImpl::SendEvent,
136 ptr_factory_.GetWeakPtr(),
137 true, utterance_id, event_type, char_index, message),
138 base::TimeDelta::FromMilliseconds(100));
139 return;
142 controller->OnTtsEvent(utterance_id, event_type, char_index, message);
145 private:
146 base::WeakPtrFactory<MockTtsPlatformImpl> ptr_factory_;
149 class FakeNetworkOnlineStateForTest : public net::NetworkChangeNotifier {
150 public:
151 explicit FakeNetworkOnlineStateForTest(bool online) : online_(online) {}
152 virtual ~FakeNetworkOnlineStateForTest() {}
154 virtual ConnectionType GetCurrentConnectionType() const OVERRIDE {
155 return online_ ?
156 net::NetworkChangeNotifier::CONNECTION_ETHERNET :
157 net::NetworkChangeNotifier::CONNECTION_NONE;
160 private:
161 bool online_;
162 DISALLOW_COPY_AND_ASSIGN(FakeNetworkOnlineStateForTest);
165 class TtsApiTest : public ExtensionApiTest {
166 public:
167 virtual void SetUpInProcessBrowserTestFixture() {
168 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
169 TtsController::GetInstance()->SetPlatformImpl(&mock_platform_impl_);
170 EXPECT_CALL(mock_platform_impl_, GetVoices(_))
171 .Times(AnyNumber());
174 protected:
175 StrictMock<MockTtsPlatformImpl> mock_platform_impl_;
178 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakOptionalArgs) {
179 EXPECT_CALL(mock_platform_impl_, IsSpeaking());
181 InSequence s;
182 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
183 .WillOnce(Return(true));
184 EXPECT_CALL(mock_platform_impl_, Speak(_, "", _, _, _))
185 .WillOnce(Return(true));
186 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
187 .WillOnce(Return(true));
188 EXPECT_CALL(mock_platform_impl_, Speak(_, "Alpha", _, _, _))
189 .WillOnce(Return(true));
190 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
191 .WillOnce(Return(true));
192 EXPECT_CALL(mock_platform_impl_, Speak(_, "Bravo", _, _, _))
193 .WillOnce(Return(true));
194 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
195 .WillOnce(Return(true));
196 EXPECT_CALL(mock_platform_impl_, Speak(_, "Charlie", _, _, _))
197 .WillOnce(Return(true));
198 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
199 .WillOnce(Return(true));
200 EXPECT_CALL(mock_platform_impl_, Speak(_, "Echo", _, _, _))
201 .WillOnce(Return(true));
202 ASSERT_TRUE(RunExtensionTest("tts/optional_args")) << message_;
205 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakFinishesImmediately) {
206 InSequence s;
207 EXPECT_CALL(mock_platform_impl_, IsSpeaking());
208 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
209 .WillOnce(Return(true));
210 EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _))
211 .WillOnce(DoAll(
212 Invoke(&mock_platform_impl_,
213 &MockTtsPlatformImpl::SendEndEvent),
214 Return(true)));
215 ASSERT_TRUE(RunExtensionTest("tts/speak_once")) << message_;
218 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakInterrupt) {
219 EXPECT_CALL(mock_platform_impl_, IsSpeaking());
221 // One utterance starts speaking, and then a second interrupts.
222 InSequence s;
223 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
224 .WillOnce(Return(true));
225 EXPECT_CALL(mock_platform_impl_, Speak(_, "text 1", _, _, _))
226 .WillOnce(Return(true));
227 // Expect the second utterance and allow it to finish.
228 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
229 .WillOnce(Return(true));
230 EXPECT_CALL(mock_platform_impl_, Speak(_, "text 2", _, _, _))
231 .WillOnce(DoAll(
232 Invoke(&mock_platform_impl_,
233 &MockTtsPlatformImpl::SendEndEvent),
234 Return(true)));
235 ASSERT_TRUE(RunExtensionTest("tts/interrupt")) << message_;
238 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakQueueInterrupt) {
239 EXPECT_CALL(mock_platform_impl_, IsSpeaking());
241 // In this test, two utterances are queued, and then a third
242 // interrupts. Speak(, _) never gets called on the second utterance.
243 InSequence s;
244 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
245 .WillOnce(Return(true));
246 EXPECT_CALL(mock_platform_impl_, Speak(_, "text 1", _, _, _))
247 .WillOnce(Return(true));
248 // Don't expect the second utterance, because it's queued up and the
249 // first never finishes.
250 // Expect the third utterance and allow it to finish successfully.
251 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
252 .WillOnce(Return(true));
253 EXPECT_CALL(mock_platform_impl_, Speak(_, "text 3", _, _, _))
254 .WillOnce(DoAll(
255 Invoke(&mock_platform_impl_,
256 &MockTtsPlatformImpl::SendEndEvent),
257 Return(true)));
258 ASSERT_TRUE(RunExtensionTest("tts/queue_interrupt")) << message_;
261 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakEnqueue) {
262 EXPECT_CALL(mock_platform_impl_, IsSpeaking());
264 InSequence s;
265 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
266 .WillOnce(Return(true));
267 EXPECT_CALL(mock_platform_impl_, Speak(_, "text 1", _, _, _))
268 .WillOnce(DoAll(
269 Invoke(&mock_platform_impl_,
270 &MockTtsPlatformImpl::SendEndEventWhenQueueNotEmpty),
271 Return(true)));
272 EXPECT_CALL(mock_platform_impl_, Speak(_, "text 2", _, _, _))
273 .WillOnce(DoAll(
274 Invoke(&mock_platform_impl_,
275 &MockTtsPlatformImpl::SendEndEvent),
276 Return(true)));
277 ASSERT_TRUE(RunExtensionTest("tts/enqueue")) << message_;
280 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakError) {
281 EXPECT_CALL(mock_platform_impl_, IsSpeaking())
282 .Times(AnyNumber());
284 InSequence s;
285 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
286 .WillOnce(Return(true));
287 EXPECT_CALL(mock_platform_impl_, Speak(_, "first try", _, _, _))
288 .WillOnce(DoAll(
289 InvokeWithoutArgs(
290 CreateFunctor(&mock_platform_impl_,
291 &MockTtsPlatformImpl::SetErrorToEpicFail)),
292 Return(false)));
293 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
294 .WillOnce(Return(true));
295 EXPECT_CALL(mock_platform_impl_, Speak(_, "second try", _, _, _))
296 .WillOnce(DoAll(
297 Invoke(&mock_platform_impl_,
298 &MockTtsPlatformImpl::SendEndEvent),
299 Return(true)));
300 ASSERT_TRUE(RunExtensionTest("tts/speak_error")) << message_;
303 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformWordCallbacks) {
304 EXPECT_CALL(mock_platform_impl_, IsSpeaking());
306 InSequence s;
307 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
308 .WillOnce(Return(true));
309 EXPECT_CALL(mock_platform_impl_, Speak(_, "one two three", _, _, _))
310 .WillOnce(DoAll(
311 Invoke(&mock_platform_impl_,
312 &MockTtsPlatformImpl::SendWordEvents),
313 Invoke(&mock_platform_impl_,
314 &MockTtsPlatformImpl::SendEndEvent),
315 Return(true)));
316 ASSERT_TRUE(RunExtensionTest("tts/word_callbacks")) << message_;
319 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformPauseResume) {
320 EXPECT_CALL(mock_platform_impl_, IsSpeaking())
321 .Times(AnyNumber());
323 InSequence s;
324 EXPECT_CALL(mock_platform_impl_, Speak(_, "test 1", _, _, _))
325 .WillOnce(DoAll(
326 Invoke(&mock_platform_impl_,
327 &MockTtsPlatformImpl::SendEndEvent),
328 Return(true)));
329 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
330 .WillOnce(Return(true));
331 EXPECT_CALL(mock_platform_impl_, Speak(_, "test 2", _, _, _))
332 .WillOnce(DoAll(
333 SaveArg<0>(&g_saved_utterance_id),
334 Return(true)));
335 EXPECT_CALL(mock_platform_impl_, Pause());
336 EXPECT_CALL(mock_platform_impl_, Resume())
337 .WillOnce(
338 InvokeWithoutArgs(
339 &mock_platform_impl_,
340 &MockTtsPlatformImpl::SendEndEventOnSavedUtteranceId));
341 ASSERT_TRUE(RunExtensionTest("tts/pause_resume")) << message_;
345 // TTS Engine tests.
348 IN_PROC_BROWSER_TEST_F(TtsApiTest, RegisterEngine) {
349 EXPECT_CALL(mock_platform_impl_, IsSpeaking())
350 .Times(AnyNumber());
351 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
352 .WillRepeatedly(Return(true));
355 InSequence s;
356 EXPECT_CALL(mock_platform_impl_, Speak(_, "native speech", _, _, _))
357 .WillOnce(DoAll(
358 Invoke(&mock_platform_impl_,
359 &MockTtsPlatformImpl::SendEndEvent),
360 Return(true)));
361 EXPECT_CALL(mock_platform_impl_, Speak(_, "native speech 2", _, _, _))
362 .WillOnce(DoAll(
363 Invoke(&mock_platform_impl_,
364 &MockTtsPlatformImpl::SendEndEvent),
365 Return(true)));
366 EXPECT_CALL(mock_platform_impl_, Speak(_, "native speech 3", _, _, _))
367 .WillOnce(DoAll(
368 Invoke(&mock_platform_impl_,
369 &MockTtsPlatformImpl::SendEndEvent),
370 Return(true)));
373 ASSERT_TRUE(RunExtensionTest("tts_engine/register_engine")) << message_;
376 IN_PROC_BROWSER_TEST_F(TtsApiTest, EngineError) {
377 EXPECT_CALL(mock_platform_impl_, IsSpeaking());
378 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
379 .WillRepeatedly(Return(true));
381 ASSERT_TRUE(RunExtensionTest("tts_engine/engine_error")) << message_;
384 IN_PROC_BROWSER_TEST_F(TtsApiTest, EngineWordCallbacks) {
385 EXPECT_CALL(mock_platform_impl_, IsSpeaking());
386 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
387 .WillRepeatedly(Return(true));
389 ASSERT_TRUE(RunExtensionTest("tts_engine/engine_word_callbacks")) << message_;
392 IN_PROC_BROWSER_TEST_F(TtsApiTest, LangMatching) {
393 EXPECT_CALL(mock_platform_impl_, IsSpeaking());
394 EXPECT_CALL(mock_platform_impl_, StopSpeaking())
395 .WillRepeatedly(Return(true));
397 ASSERT_TRUE(RunExtensionTest("tts_engine/lang_matching")) << message_;
400 IN_PROC_BROWSER_TEST_F(TtsApiTest, NetworkSpeechEngine) {
401 // Simulate online network state.
402 net::NetworkChangeNotifier::DisableForTest disable_for_test;
403 FakeNetworkOnlineStateForTest fake_online_state(true);
405 ExtensionService* service = extensions::ExtensionSystem::Get(
406 profile())->extension_service();
407 service->component_loader()->AddNetworkSpeechSynthesisExtension();
408 ASSERT_TRUE(RunExtensionTest("tts_engine/network_speech_engine")) << message_;
411 IN_PROC_BROWSER_TEST_F(TtsApiTest, NoNetworkSpeechEngineWhenOffline) {
412 // Simulate offline network state.
413 net::NetworkChangeNotifier::DisableForTest disable_for_test;
414 FakeNetworkOnlineStateForTest fake_online_state(false);
416 ExtensionService* service = extensions::ExtensionSystem::Get(
417 profile())->extension_service();
418 service->component_loader()->AddNetworkSpeechSynthesisExtension();
419 // Test should fail when offline.
420 ASSERT_FALSE(RunExtensionTest("tts_engine/network_speech_engine"));
423 // http://crbug.com/122474
424 IN_PROC_BROWSER_TEST_F(TtsApiTest, EngineApi) {
425 ASSERT_TRUE(RunExtensionTest("tts_engine/engine_api")) << message_;
428 } // namespace extensions