OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
22 #include "content/public/common/speech_recognition_error.h" | 22 #include "content/public/common/speech_recognition_error.h" |
23 #include "content/public/common/speech_recognition_result.h" | 23 #include "content/public/common/speech_recognition_result.h" |
24 #include "content/public/common/url_constants.h" | 24 #include "content/public/common/url_constants.h" |
25 #include "content/public/test/test_utils.h" | 25 #include "content/public/test/test_utils.h" |
26 #include "content/shell/shell.h" | 26 #include "content/shell/shell.h" |
27 #include "content/test/content_browser_test.h" | 27 #include "content/test/content_browser_test.h" |
28 #include "content/test/content_browser_test_utils.h" | 28 #include "content/test/content_browser_test_utils.h" |
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | 29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" |
30 | 30 |
31 using content::NavigationController; | 31 namespace content { |
32 using content::SpeechRecognitionEventListener; | |
33 using content::SpeechRecognitionSessionConfig; | |
34 using content::SpeechRecognitionSessionContext; | |
35 using content::WebContents; | |
36 | |
37 namespace speech { | |
38 class FakeSpeechRecognitionManager; | |
39 } | |
40 | |
41 namespace speech { | |
42 | 32 |
43 const char kTestResult[] = "Pictures of the moon"; | 33 const char kTestResult[] = "Pictures of the moon"; |
44 | 34 |
45 class FakeSpeechRecognitionManager : public content::SpeechRecognitionManager { | 35 class FakeSpeechRecognitionManager : public SpeechRecognitionManager { |
46 public: | 36 public: |
47 FakeSpeechRecognitionManager() | 37 FakeSpeechRecognitionManager() |
48 : session_id_(0), | 38 : session_id_(0), |
49 listener_(NULL), | 39 listener_(NULL), |
50 did_cancel_all_(false), | 40 did_cancel_all_(false), |
51 should_send_fake_response_(true), | 41 should_send_fake_response_(true), |
52 recognition_started_event_(false, false) { | 42 recognition_started_event_(false, false) { |
53 } | 43 } |
54 | 44 |
55 std::string grammar() { | 45 std::string grammar() { |
(...skipping 11 matching lines...) Expand all Loading... |
67 bool should_send_fake_response() { | 57 bool should_send_fake_response() { |
68 return should_send_fake_response_; | 58 return should_send_fake_response_; |
69 } | 59 } |
70 | 60 |
71 base::WaitableEvent& recognition_started_event() { | 61 base::WaitableEvent& recognition_started_event() { |
72 return recognition_started_event_; | 62 return recognition_started_event_; |
73 } | 63 } |
74 | 64 |
75 // SpeechRecognitionManager methods. | 65 // SpeechRecognitionManager methods. |
76 virtual int CreateSession( | 66 virtual int CreateSession( |
77 const content::SpeechRecognitionSessionConfig& config) OVERRIDE { | 67 const SpeechRecognitionSessionConfig& config) OVERRIDE { |
78 VLOG(1) << "FAKE CreateSession invoked."; | 68 VLOG(1) << "FAKE CreateSession invoked."; |
79 EXPECT_EQ(0, session_id_); | 69 EXPECT_EQ(0, session_id_); |
80 EXPECT_EQ(NULL, listener_); | 70 EXPECT_EQ(NULL, listener_); |
81 listener_ = config.event_listener; | 71 listener_ = config.event_listener; |
82 if (config.grammars.size() > 0) | 72 if (config.grammars.size() > 0) |
83 grammar_ = config.grammars[0].url; | 73 grammar_ = config.grammars[0].url; |
84 session_ctx_ = config.initial_context; | 74 session_ctx_ = config.initial_context; |
85 session_config_ = config; | 75 session_config_ = config; |
86 session_id_ = 1; | 76 session_id_ = 1; |
87 return session_id_; | 77 return session_id_; |
(...skipping 25 matching lines...) Expand all Loading... |
113 listener_ = NULL; | 103 listener_ = NULL; |
114 } | 104 } |
115 | 105 |
116 virtual void StopAudioCaptureForSession(int session_id) OVERRIDE { | 106 virtual void StopAudioCaptureForSession(int session_id) OVERRIDE { |
117 VLOG(1) << "StopRecording invoked."; | 107 VLOG(1) << "StopRecording invoked."; |
118 EXPECT_EQ(session_id_, session_id); | 108 EXPECT_EQ(session_id_, session_id); |
119 // Nothing to do here since we aren't really recording. | 109 // Nothing to do here since we aren't really recording. |
120 } | 110 } |
121 | 111 |
122 virtual void AbortAllSessionsForListener( | 112 virtual void AbortAllSessionsForListener( |
123 content::SpeechRecognitionEventListener* listener) OVERRIDE { | 113 SpeechRecognitionEventListener* listener) OVERRIDE { |
124 VLOG(1) << "CancelAllRequestsWithDelegate invoked."; | 114 VLOG(1) << "CancelAllRequestsWithDelegate invoked."; |
125 // listener_ is set to NULL if a fake result was received (see below), so | 115 // listener_ is set to NULL if a fake result was received (see below), so |
126 // check that listener_ matches the incoming parameter only when there is | 116 // check that listener_ matches the incoming parameter only when there is |
127 // no fake result sent. | 117 // no fake result sent. |
128 EXPECT_TRUE(should_send_fake_response_ || listener_ == listener); | 118 EXPECT_TRUE(should_send_fake_response_ || listener_ == listener); |
129 did_cancel_all_ = true; | 119 did_cancel_all_ = true; |
130 } | 120 } |
131 | 121 |
132 virtual void AbortAllSessionsForRenderView(int render_process_id, | 122 virtual void AbortAllSessionsForRenderView(int render_process_id, |
133 int render_view_id) OVERRIDE { | 123 int render_view_id) OVERRIDE { |
(...skipping 11 matching lines...) Expand all Loading... |
145 session_ctx_.render_view_id == render_view_id && | 135 session_ctx_.render_view_id == render_view_id && |
146 session_ctx_.request_id == request_id; | 136 session_ctx_.request_id == request_id; |
147 } | 137 } |
148 | 138 |
149 virtual const SpeechRecognitionSessionConfig& GetSessionConfig( | 139 virtual const SpeechRecognitionSessionConfig& GetSessionConfig( |
150 int session_id) const OVERRIDE { | 140 int session_id) const OVERRIDE { |
151 EXPECT_EQ(session_id, session_id_); | 141 EXPECT_EQ(session_id, session_id_); |
152 return session_config_; | 142 return session_config_; |
153 } | 143 } |
154 | 144 |
155 virtual content::SpeechRecognitionSessionContext GetSessionContext( | 145 virtual SpeechRecognitionSessionContext GetSessionContext( |
156 int session_id) const OVERRIDE { | 146 int session_id) const OVERRIDE { |
157 EXPECT_EQ(session_id, session_id_); | 147 EXPECT_EQ(session_id, session_id_); |
158 return session_ctx_; | 148 return session_ctx_; |
159 } | 149 } |
160 | 150 |
161 private: | 151 private: |
162 void SetFakeRecognitionResult() { | 152 void SetFakeRecognitionResult() { |
163 if (session_id_) { // Do a check in case we were cancelled.. | 153 if (session_id_) { // Do a check in case we were cancelled.. |
164 VLOG(1) << "Setting fake recognition result."; | 154 VLOG(1) << "Setting fake recognition result."; |
165 listener_->OnAudioEnd(session_id_); | 155 listener_->OnAudioEnd(session_id_); |
166 content::SpeechRecognitionResult results; | 156 SpeechRecognitionResult results; |
167 results.hypotheses.push_back(content::SpeechRecognitionHypothesis( | 157 results.hypotheses.push_back(SpeechRecognitionHypothesis( |
168 ASCIIToUTF16(kTestResult), 1.0)); | 158 ASCIIToUTF16(kTestResult), 1.0)); |
169 listener_->OnRecognitionResult(session_id_, results); | 159 listener_->OnRecognitionResult(session_id_, results); |
170 listener_->OnRecognitionEnd(session_id_); | 160 listener_->OnRecognitionEnd(session_id_); |
171 session_id_ = 0; | 161 session_id_ = 0; |
172 listener_ = NULL; | 162 listener_ = NULL; |
173 VLOG(1) << "Finished setting fake recognition result."; | 163 VLOG(1) << "Finished setting fake recognition result."; |
174 } | 164 } |
175 } | 165 } |
176 | 166 |
177 int session_id_; | 167 int session_id_; |
178 SpeechRecognitionEventListener* listener_; | 168 SpeechRecognitionEventListener* listener_; |
179 SpeechRecognitionSessionConfig session_config_; | 169 SpeechRecognitionSessionConfig session_config_; |
180 SpeechRecognitionSessionContext session_ctx_; | 170 SpeechRecognitionSessionContext session_ctx_; |
181 std::string grammar_; | 171 std::string grammar_; |
182 bool did_cancel_all_; | 172 bool did_cancel_all_; |
183 bool should_send_fake_response_; | 173 bool should_send_fake_response_; |
184 base::WaitableEvent recognition_started_event_; | 174 base::WaitableEvent recognition_started_event_; |
185 }; | 175 }; |
186 | 176 |
187 class SpeechRecognitionBrowserTest : public content::ContentBrowserTest { | 177 class SpeechRecognitionBrowserTest : public ContentBrowserTest { |
188 public: | 178 public: |
189 // ContentBrowserTest methods | 179 // ContentBrowserTest methods |
190 virtual void SetUpCommandLine(CommandLine* command_line) { | 180 virtual void SetUpCommandLine(CommandLine* command_line) { |
191 EXPECT_TRUE(!command_line->HasSwitch(switches::kDisableSpeechInput)); | 181 EXPECT_TRUE(!command_line->HasSwitch(switches::kDisableSpeechInput)); |
192 } | 182 } |
193 | 183 |
194 protected: | 184 protected: |
195 void LoadAndStartSpeechRecognitionTest(const char* filename) { | 185 void LoadAndStartSpeechRecognitionTest(const char* filename) { |
196 // The test page calculates the speech button's coordinate in the page on | 186 // The test page calculates the speech button's coordinate in the page on |
197 // load & sets that coordinate in the URL fragment. We send mouse down & up | 187 // load & sets that coordinate in the URL fragment. We send mouse down & up |
198 // events at that coordinate to trigger speech recognition. | 188 // events at that coordinate to trigger speech recognition. |
199 GURL test_url = content::GetTestUrl("speech", filename); | 189 GURL test_url = GetTestUrl("speech", filename); |
200 content::NavigateToURL(shell(), test_url); | 190 NavigateToURL(shell(), test_url); |
201 | 191 |
202 WebKit::WebMouseEvent mouse_event; | 192 WebKit::WebMouseEvent mouse_event; |
203 mouse_event.type = WebKit::WebInputEvent::MouseDown; | 193 mouse_event.type = WebKit::WebInputEvent::MouseDown; |
204 mouse_event.button = WebKit::WebMouseEvent::ButtonLeft; | 194 mouse_event.button = WebKit::WebMouseEvent::ButtonLeft; |
205 mouse_event.x = 0; | 195 mouse_event.x = 0; |
206 mouse_event.y = 0; | 196 mouse_event.y = 0; |
207 mouse_event.clickCount = 1; | 197 mouse_event.clickCount = 1; |
208 WebContents* web_contents = shell()->web_contents(); | 198 WebContents* web_contents = shell()->web_contents(); |
209 | 199 |
210 content::WindowedNotificationObserver observer( | 200 WindowedNotificationObserver observer( |
211 content::NOTIFICATION_LOAD_STOP, | 201 NOTIFICATION_LOAD_STOP, |
212 content::Source<NavigationController>(&web_contents->GetController())); | 202 Source<NavigationController>(&web_contents->GetController())); |
213 web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event); | 203 web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event); |
214 mouse_event.type = WebKit::WebInputEvent::MouseUp; | 204 mouse_event.type = WebKit::WebInputEvent::MouseUp; |
215 web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event); | 205 web_contents->GetRenderViewHost()->ForwardMouseEvent(mouse_event); |
216 fake_speech_recognition_manager_.recognition_started_event().Wait(); | 206 fake_speech_recognition_manager_.recognition_started_event().Wait(); |
217 | 207 |
218 // We should wait for a navigation event, raised by the test page JS code | 208 // We should wait for a navigation event, raised by the test page JS code |
219 // upon the onwebkitspeechchange event, in all cases except when the | 209 // upon the onwebkitspeechchange event, in all cases except when the |
220 // speech response is inhibited. | 210 // speech response is inhibited. |
221 if (fake_speech_recognition_manager_.should_send_fake_response()) | 211 if (fake_speech_recognition_manager_.should_send_fake_response()) |
222 observer.Wait(); | 212 observer.Wait(); |
(...skipping 20 matching lines...) Expand all Loading... |
243 } | 233 } |
244 | 234 |
245 virtual void TearDownInProcessBrowserTestFixture() { | 235 virtual void TearDownInProcessBrowserTestFixture() { |
246 speech_recognition_manager_ = NULL; | 236 speech_recognition_manager_ = NULL; |
247 } | 237 } |
248 | 238 |
249 FakeSpeechRecognitionManager fake_speech_recognition_manager_; | 239 FakeSpeechRecognitionManager fake_speech_recognition_manager_; |
250 | 240 |
251 // This is used by the static |fakeManager|, and it is a pointer rather than a | 241 // This is used by the static |fakeManager|, and it is a pointer rather than a |
252 // direct instance per the style guide. | 242 // direct instance per the style guide. |
253 static content::SpeechRecognitionManager* speech_recognition_manager_; | 243 static SpeechRecognitionManager* speech_recognition_manager_; |
254 }; | 244 }; |
255 | 245 |
256 content::SpeechRecognitionManager* | 246 SpeechRecognitionManager* |
257 SpeechRecognitionBrowserTest::speech_recognition_manager_ = NULL; | 247 SpeechRecognitionBrowserTest::speech_recognition_manager_ = NULL; |
258 | 248 |
259 // TODO(satish): Once this flakiness has been fixed, add a second test here to | 249 // TODO(satish): Once this flakiness has been fixed, add a second test here to |
260 // check for sending many clicks in succession to the speech button and verify | 250 // check for sending many clicks in succession to the speech button and verify |
261 // that it doesn't cause any crash but works as expected. This should act as the | 251 // that it doesn't cause any crash but works as expected. This should act as the |
262 // test for http://crbug.com/59173 | 252 // test for http://crbug.com/59173 |
263 // | 253 // |
264 // TODO(satish): Similar to above, once this flakiness has been fixed add | 254 // TODO(satish): Similar to above, once this flakiness has been fixed add |
265 // another test here to check that when speech recognition is in progress and | 255 // another test here to check that when speech recognition is in progress and |
266 // a renderer crashes, we get a call to | 256 // a renderer crashes, we get a call to |
(...skipping 14 matching lines...) Expand all Loading... |
281 // The test checks that the cancel-all callback gets issued when a session | 271 // The test checks that the cancel-all callback gets issued when a session |
282 // is pending, so don't send a fake response. | 272 // is pending, so don't send a fake response. |
283 // We are not expecting a navigation event being raised from the JS of the | 273 // We are not expecting a navigation event being raised from the JS of the |
284 // test page JavaScript in this case. | 274 // test page JavaScript in this case. |
285 fake_speech_recognition_manager_.set_should_send_fake_response(false); | 275 fake_speech_recognition_manager_.set_should_send_fake_response(false); |
286 | 276 |
287 LoadAndStartSpeechRecognitionTest("basic_recognition.html"); | 277 LoadAndStartSpeechRecognitionTest("basic_recognition.html"); |
288 | 278 |
289 // Make the renderer crash. This should trigger | 279 // Make the renderer crash. This should trigger |
290 // InputTagSpeechDispatcherHost to cancel all pending sessions. | 280 // InputTagSpeechDispatcherHost to cancel all pending sessions. |
291 content::NavigateToURL(shell(), GURL(chrome::kChromeUICrashURL)); | 281 NavigateToURL(shell(), GURL(chrome::kChromeUICrashURL)); |
292 | 282 |
293 EXPECT_TRUE(fake_speech_recognition_manager_.did_cancel_all()); | 283 EXPECT_TRUE(fake_speech_recognition_manager_.did_cancel_all()); |
294 } | 284 } |
295 | 285 |
296 } // namespace speech | 286 } // namespace content |
OLD | NEW |