Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(462)

Side by Side Diff: chrome/browser/speech/speech_input_extension_manager.cc

Issue 8508051: Revert 109285 - Seems to have broken chrome_frame_net_tests on the win_rel trybot, stuffing up th... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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.
4
5 #include "chrome/browser/speech/speech_input_extension_manager.h"
6
7 #include "base/bind.h"
8 #include "base/json/json_writer.h"
9 #include "base/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "chrome/browser/extensions/extension_event_router.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/prefs/pref_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_dependency_manager.h"
16 #include "chrome/browser/profiles/profile_keyed_service.h"
17 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
18 #include "chrome/common/chrome_notification_types.h"
19 #include "chrome/common/extensions/extension.h"
20 #include "chrome/common/pref_names.h"
21 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/notification_service.h"
23
24 using content::BrowserThread;
25 using namespace speech_input;
26
27 namespace {
28
29 const char kErrorNoRecordingDeviceFound[] = "noRecordingDeviceFound";
30 const char kErrorRecordingDeviceInUse[] = "recordingDeviceInUse";
31 const char kErrorUnableToStart[] = "unableToStart";
32 const char kErrorRequestDenied[] = "requestDenied";
33 const char kErrorRequestInProgress[] = "requestInProgress";
34 const char kErrorInvalidOperation[] = "invalidOperation";
35
36 const char kErrorCodeKey[] = "code";
37 const char kErrorCaptureError[] = "captureError";
38 const char kErrorNetworkError[] = "networkError";
39 const char kErrorNoSpeechHeard[] = "noSpeechHeard";
40 const char kErrorNoResults[] = "noResults";
41
42 const char kUtteranceKey[] = "utterance";
43 const char kConfidenceKey[] = "confidence";
44 const char kHypothesesKey[] = "hypotheses";
45
46 const char kOnErrorEvent[] = "experimental.speechInput.onError";
47 const char kOnResultEvent[] = "experimental.speechInput.onResult";
48 const char kOnSoundStartEvent[] = "experimental.speechInput.onSoundStart";
49 const char kOnSoundEndEvent[] = "experimental.speechInput.onSoundEnd";
50
51 // Caller id provided to the speech recognizer. Since only one extension can
52 // be recording on the same time a constant value is enough as id.
53 static const int kSpeechCallerId = 1;
54
55 // Wrap an SpeechInputExtensionManager using scoped_refptr to avoid
56 // assertion failures on destruction because of not using release().
57 class SpeechInputExtensionManagerWrapper : public ProfileKeyedService {
58 public:
59 explicit SpeechInputExtensionManagerWrapper(
60 SpeechInputExtensionManager* manager)
61 : manager_(manager) {}
62
63 virtual ~SpeechInputExtensionManagerWrapper() {}
64
65 SpeechInputExtensionManager* manager() const { return manager_.get(); }
66
67 private:
68 // Methods from ProfileKeyedService.
69 virtual void Shutdown() OVERRIDE {
70 manager()->ShutdownOnUIThread();
71 }
72
73 scoped_refptr<SpeechInputExtensionManager> manager_;
74 };
75
76 }
77
78 // Factory for SpeechInputExtensionManagers as profile keyed services.
79 class SpeechInputExtensionManager::Factory : public ProfileKeyedServiceFactory {
80 public:
81 static void Initialize();
82 static Factory* GetInstance();
83
84 SpeechInputExtensionManagerWrapper* GetForProfile(Profile* profile);
85
86 private:
87 friend struct DefaultSingletonTraits<Factory>;
88
89 Factory();
90 virtual ~Factory();
91
92 // ProfileKeyedServiceFactory methods:
93 virtual ProfileKeyedService* BuildServiceInstanceFor(
94 Profile* profile) const OVERRIDE;
95 virtual bool ServiceRedirectedInIncognito() OVERRIDE { return false; }
96 virtual bool ServiceIsNULLWhileTesting() OVERRIDE { return true; }
97 virtual bool ServiceIsCreatedWithProfile() OVERRIDE { return true; }
98
99 DISALLOW_COPY_AND_ASSIGN(Factory);
100 };
101
102 void SpeechInputExtensionManager::Factory::Initialize() {
103 GetInstance();
104 }
105
106 SpeechInputExtensionManager::Factory*
107 SpeechInputExtensionManager::Factory::GetInstance() {
108 return Singleton<SpeechInputExtensionManager::Factory>::get();
109 }
110
111 SpeechInputExtensionManagerWrapper*
112 SpeechInputExtensionManager::Factory::GetForProfile(
113 Profile* profile) {
114 return static_cast<SpeechInputExtensionManagerWrapper*>(
115 GetServiceForProfile(profile, true));
116 }
117
118 SpeechInputExtensionManager::Factory::Factory()
119 : ProfileKeyedServiceFactory(ProfileDependencyManager::GetInstance()) {
120 }
121
122 SpeechInputExtensionManager::Factory::~Factory() {
123 }
124
125 ProfileKeyedService*
126 SpeechInputExtensionManager::Factory::BuildServiceInstanceFor(
127 Profile* profile) const {
128 scoped_refptr<SpeechInputExtensionManager> manager(
129 new SpeechInputExtensionManager(profile));
130 return new SpeechInputExtensionManagerWrapper(manager);
131 }
132
133 SpeechInputExtensionInterface::SpeechInputExtensionInterface() {
134 }
135
136 SpeechInputExtensionInterface::~SpeechInputExtensionInterface() {
137 }
138
139 SpeechInputExtensionManager::SpeechInputExtensionManager(Profile* profile)
140 : profile_(profile),
141 state_(kIdle),
142 speech_interface_(NULL),
143 notification_(profile) {
144 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
145 content::Source<Profile>(profile_));
146 }
147
148 SpeechInputExtensionManager::~SpeechInputExtensionManager() {
149 }
150
151 SpeechInputExtensionManager* SpeechInputExtensionManager::GetForProfile(
152 Profile* profile) {
153 SpeechInputExtensionManagerWrapper *wrapper =
154 Factory::GetInstance()->GetForProfile(profile);
155 if (!wrapper)
156 return NULL;
157 return wrapper->manager();
158 }
159
160 void SpeechInputExtensionManager::InitializeFactory() {
161 Factory::Initialize();
162 }
163
164 void SpeechInputExtensionManager::Observe(int type,
165 const content::NotificationSource& source,
166 const content::NotificationDetails& details) {
167 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) {
168 ExtensionUnloaded(
169 content::Details<UnloadedExtensionInfo>(details)->extension->id());
170 } else {
171 NOTREACHED();
172 }
173 }
174
175 void SpeechInputExtensionManager::ShutdownOnUIThread() {
176 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
177 VLOG(1) << "Profile shutting down.";
178
179 base::AutoLock auto_lock(state_lock_);
180 DCHECK(state_ != kShutdown);
181 if (state_ != kIdle) {
182 notification_.Hide();
183 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
184 base::Bind(&SpeechInputExtensionManager::ForceStopOnIOThread, this));
185 }
186 state_ = kShutdown;
187 VLOG(1) << "Entering the shutdown sink state.";
188 registrar_.RemoveAll();
189 profile_ = NULL;
190 }
191
192 void SpeechInputExtensionManager::ExtensionUnloaded(
193 const std::string& extension_id) {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195
196 base::AutoLock auto_lock(state_lock_);
197 if (state_ == kShutdown)
198 return;
199
200 VLOG(1) << "Extension unloaded. Requesting to enforce stop...";
201 if (extension_id_in_use_ == extension_id) {
202 if (state_ != kIdle) {
203 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
204 base::Bind(&SpeechInputExtensionManager::ForceStopOnIOThread, this));
205 }
206 }
207 }
208
209 void SpeechInputExtensionManager::SetSpeechInputExtensionInterface(
210 SpeechInputExtensionInterface* interface) {
211 speech_interface_ = interface;
212 }
213
214 SpeechInputExtensionInterface*
215 SpeechInputExtensionManager::GetSpeechInputExtensionInterface() {
216 return speech_interface_ ? speech_interface_ : this;
217 }
218
219 void SpeechInputExtensionManager::ResetToIdleState() {
220 VLOG(1) << "State changed to idle. Deassociating any extensions.";
221 state_ = kIdle;
222 extension_id_in_use_.clear();
223 }
224
225 void SpeechInputExtensionManager::SetRecognitionResult(
226 int caller_id,
227 const SpeechInputResult& result) {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
229 DCHECK_EQ(caller_id, kSpeechCallerId);
230
231 // Stopping will start the disassociation with the extension.
232 // Make a copy to report the results to the proper one.
233 std::string extension_id = extension_id_in_use_;
234 ForceStopOnIOThread();
235
236 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
237 base::Bind(&SpeechInputExtensionManager::SetRecognitionResultOnUIThread,
238 this, result, extension_id));
239 }
240
241 void SpeechInputExtensionManager::SetRecognitionResultOnUIThread(
242 const SpeechInputResult& result, const std::string& extension_id) {
243 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
244
245 ListValue args;
246 DictionaryValue* js_event = new DictionaryValue();
247 args.Append(js_event);
248
249 ListValue* js_hypothesis_array = new ListValue();
250 js_event->Set(kHypothesesKey, js_hypothesis_array);
251
252 for (size_t i = 0; i < result.hypotheses.size(); ++i) {
253 const SpeechInputHypothesis& hypothesis = result.hypotheses[i];
254
255 DictionaryValue* js_hypothesis_object = new DictionaryValue();
256 js_hypothesis_array->Append(js_hypothesis_object);
257
258 js_hypothesis_object->SetString(kUtteranceKey,
259 UTF16ToUTF8(hypothesis.utterance));
260 js_hypothesis_object->SetDouble(kConfidenceKey,
261 hypothesis.confidence);
262 }
263
264 std::string json_args;
265 base::JSONWriter::Write(&args, false, &json_args);
266 VLOG(1) << "Results: " << json_args;
267 DispatchEventToExtension(extension_id, kOnResultEvent, json_args);
268 }
269
270 void SpeechInputExtensionManager::DidStartReceivingAudio(int caller_id) {
271 VLOG(1) << "DidStartReceivingAudio";
272 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
273 DCHECK_EQ(caller_id, kSpeechCallerId);
274
275 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
276 base::Bind(&SpeechInputExtensionManager::DidStartReceivingAudioOnUIThread,
277 this));
278 }
279
280 void SpeechInputExtensionManager::DidCompleteRecording(int caller_id) {
281 DCHECK_EQ(caller_id, kSpeechCallerId);
282 }
283
284 void SpeechInputExtensionManager::DidCompleteRecognition(int caller_id) {
285 DCHECK_EQ(caller_id, kSpeechCallerId);
286 }
287
288 void SpeechInputExtensionManager::DidStartReceivingAudioOnUIThread() {
289 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
290
291 base::AutoLock auto_lock(state_lock_);
292 if (state_ == kShutdown)
293 return;
294
295 DCHECK_EQ(state_, kStarting);
296 VLOG(1) << "State changed to recording";
297 state_ = kRecording;
298
299 const Extension* extension = profile_->GetExtensionService()->
300 GetExtensionById(extension_id_in_use_, true);
301 DCHECK(extension);
302
303 bool show_notification = !profile_->GetPrefs()->GetBoolean(
304 prefs::kSpeechInputTrayNotificationShown);
305
306 notification_.Show(extension, show_notification);
307
308 if (show_notification) {
309 profile_->GetPrefs()->SetBoolean(
310 prefs::kSpeechInputTrayNotificationShown, true);
311 }
312
313 VLOG(1) << "Sending start notification";
314 content::NotificationService::current()->Notify(
315 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_RECORDING_STARTED,
316 content::Source<Profile>(profile_),
317 content::Details<std::string>(&extension_id_in_use_));
318 }
319
320 void SpeechInputExtensionManager::OnRecognizerError(
321 int caller_id, SpeechInputError error) {
322 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
323 DCHECK_EQ(caller_id, kSpeechCallerId);
324 VLOG(1) << "OnRecognizerError: " << error;
325
326 base::AutoLock auto_lock(state_lock_);
327 if (state_ == kShutdown)
328 return;
329
330 // Release the recognizer object.
331 GetSpeechInputExtensionInterface()->StopRecording(true);
332
333 std::string event_error_code;
334 bool report_to_event = true;
335
336 switch (error) {
337 case kErrorNone:
338 break;
339
340 case kErrorAudio:
341 if (state_ == kStarting) {
342 event_error_code = kErrorUnableToStart;
343 report_to_event = false;
344 } else {
345 event_error_code = kErrorCaptureError;
346 }
347 break;
348
349 case kErrorNetwork:
350 event_error_code = kErrorNetworkError;
351 break;
352
353 case kErrorBadGrammar:
354 // No error is returned on invalid language, for example.
355 // To avoid confusion about when this is would be fired, the invalid
356 // params error is not being exposed to the onError event.
357 event_error_code = kErrorUnableToStart;
358 break;
359
360 case kErrorNoSpeech:
361 event_error_code = kErrorNoSpeechHeard;
362 break;
363
364 case kErrorNoMatch:
365 event_error_code = kErrorNoResults;
366 break;
367
368 // The remaining kErrorAborted case should never be returned by the server.
369 default:
370 NOTREACHED();
371 }
372
373 if (!event_error_code.empty()) {
374 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
375 base::Bind(&SpeechInputExtensionManager::DispatchError,
376 this, event_error_code, report_to_event));
377 }
378 }
379
380 void SpeechInputExtensionManager::DidCompleteEnvironmentEstimation(
381 int caller_id) {
382 DCHECK_EQ(caller_id, kSpeechCallerId);
383 }
384
385 void SpeechInputExtensionManager::DidStartReceivingSpeech(int caller_id) {
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
387 DCHECK_EQ(caller_id, kSpeechCallerId);
388 VLOG(1) << "DidStartReceivingSpeech";
389
390 std::string json_args;
391 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
392 base::Bind(&SpeechInputExtensionManager::DispatchEventToExtension,
393 this, extension_id_in_use_, std::string(kOnSoundStartEvent),
394 json_args));
395 }
396
397 void SpeechInputExtensionManager::DidStopReceivingSpeech(int caller_id) {
398 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
399 DCHECK_EQ(caller_id, kSpeechCallerId);
400 VLOG(1) << "DidStopReceivingSpeech";
401
402 std::string json_args;
403 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
404 base::Bind(&SpeechInputExtensionManager::DispatchEventToExtension,
405 this, extension_id_in_use_, std::string(kOnSoundEndEvent),
406 json_args));
407 }
408
409 void SpeechInputExtensionManager::DispatchEventToExtension(
410 const std::string& extension_id, const std::string& event,
411 const std::string& json_args) {
412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
413
414 base::AutoLock auto_lock(state_lock_);
415 if (state_ == kShutdown)
416 return;
417
418 if (profile_ && profile_->GetExtensionEventRouter()) {
419 std::string final_args;
420 if (json_args.empty()) {
421 ListValue args;
422 base::JSONWriter::Write(&args, false, &final_args);
423 } else {
424 final_args = json_args;
425 }
426
427 profile_->GetExtensionEventRouter()->DispatchEventToExtension(
428 extension_id, event, final_args, profile_, GURL());
429 }
430 }
431
432 void SpeechInputExtensionManager::DispatchError(
433 const std::string& error, bool dispatch_event) {
434 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
435
436 std::string extension_id;
437 {
438 base::AutoLock auto_lock(state_lock_);
439 if (state_ == kShutdown)
440 return;
441
442 if (state_ == kRecording)
443 notification_.Hide();
444
445 extension_id = extension_id_in_use_;
446 ResetToIdleState();
447
448 // Will set the error property in the ongoing extension function calls.
449 ExtensionError details(extension_id, error);
450 content::NotificationService::current()->Notify(
451 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_FAILED,
452 content::Source<Profile>(profile_),
453 content::Details<ExtensionError>(&details));
454 }
455
456 // Used for errors that are also reported via the onError event.
457 if (dispatch_event) {
458 ListValue args;
459 DictionaryValue *js_error = new DictionaryValue();
460 args.Append(js_error);
461 js_error->SetString(kErrorCodeKey, error);
462 std::string json_args;
463 base::JSONWriter::Write(&args, false, &json_args);
464 DispatchEventToExtension(extension_id,
465 kOnErrorEvent, json_args);
466 }
467 }
468
469 bool SpeechInputExtensionManager::Start(const std::string& extension_id,
470 const std::string& language, const std::string& grammar,
471 bool filter_profanities, std::string* error) {
472 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
473 DCHECK(error);
474 VLOG(1) << "Requesting start (UI thread)";
475
476 base::AutoLock auto_lock(state_lock_);
477 if (state_ == kShutdown ||
478 (!extension_id_in_use_.empty() && extension_id_in_use_ != extension_id)) {
479 *error = kErrorRequestDenied;
480 return false;
481 }
482
483 switch (state_) {
484 case kIdle:
485 break;
486
487 case kStarting:
488 *error = kErrorRequestInProgress;
489 return false;
490
491 case kRecording:
492 case kStopping:
493 *error = kErrorInvalidOperation;
494 return false;
495
496 default:
497 NOTREACHED();
498 }
499
500 extension_id_in_use_ = extension_id;
501 VLOG(1) << "State changed to starting";
502 state_ = kStarting;
503
504 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
505 base::Bind(&SpeechInputExtensionManager::StartOnIOThread, this,
506 profile_->GetRequestContext(), language, grammar, filter_profanities));
507 return true;
508 }
509
510 void SpeechInputExtensionManager::StartOnIOThread(
511 net::URLRequestContextGetter* context_getter,
512 const std::string& language, const std::string& grammar,
513 bool filter_profanities) {
514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
515 VLOG(1) << "Requesting start (IO thread)";
516
517 // Everything put inside the lock to ensure the validity of context_getter,
518 // guaranteed while not in the shutdown state. Any ongoing or recognition
519 // request will be requested to be aborted when entering the shutdown state.
520 base::AutoLock auto_lock(state_lock_);
521 if (state_ == kShutdown)
522 return;
523
524 if (!GetSpeechInputExtensionInterface()->HasAudioInputDevices()) {
525 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
526 base::Bind(&SpeechInputExtensionManager::DispatchError, this,
527 std::string(kErrorNoRecordingDeviceFound), false));
528 return;
529 }
530
531 if (GetSpeechInputExtensionInterface()->IsRecordingInProcess()) {
532 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
533 base::Bind(&SpeechInputExtensionManager::DispatchError, this,
534 std::string(kErrorRecordingDeviceInUse), false));
535 return;
536 }
537
538 GetSpeechInputExtensionInterface()->StartRecording(this, context_getter,
539 kSpeechCallerId, language, grammar, filter_profanities);
540 }
541
542 bool SpeechInputExtensionManager::HasAudioInputDevices() {
543 return AudioManager::GetAudioManager()->HasAudioInputDevices();
544 }
545
546 bool SpeechInputExtensionManager::IsRecordingInProcess() {
547 // Thread-safe query.
548 return AudioManager::GetAudioManager()->IsRecordingInProcess();
549 }
550
551 bool SpeechInputExtensionManager::IsRecording() {
552 return GetSpeechInputExtensionInterface()->IsRecordingInProcess();
553 }
554
555 void SpeechInputExtensionManager::StartRecording(
556 speech_input::SpeechRecognizerDelegate* delegate,
557 net::URLRequestContextGetter* context_getter, int caller_id,
558 const std::string& language, const std::string& grammar,
559 bool filter_profanities) {
560 DCHECK(!recognizer_);
561 recognizer_ = new SpeechRecognizer(delegate, caller_id, language, grammar,
562 context_getter, filter_profanities, "", "");
563 recognizer_->StartRecording();
564 }
565
566 bool SpeechInputExtensionManager::HasValidRecognizer() {
567 // Conditional expression used to avoid a performance warning on windows.
568 return recognizer_ ? true : false;
569 }
570
571 bool SpeechInputExtensionManager::Stop(const std::string& extension_id,
572 std::string* error) {
573 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
574 DCHECK(error);
575 VLOG(1) << "Requesting stop (UI thread)";
576
577 base::AutoLock auto_lock(state_lock_);
578 if (state_ == kShutdown ||
579 (!extension_id_in_use_.empty() && extension_id_in_use_ != extension_id)) {
580 *error = kErrorRequestDenied;
581 return false;
582 }
583
584 switch (state_) {
585 case kRecording:
586 break;
587
588 case kStopping:
589 *error = kErrorRequestInProgress;
590 return false;
591
592 case kIdle:
593 case kStarting:
594 *error = kErrorInvalidOperation;
595 return false;
596
597 default:
598 NOTREACHED();
599 }
600
601 // Guarded by the state lock.
602 DCHECK(GetSpeechInputExtensionInterface()->HasValidRecognizer());
603
604 VLOG(1) << "State changed to stopping";
605 state_ = kStopping;
606
607 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
608 base::Bind(&SpeechInputExtensionManager::ForceStopOnIOThread, this));
609 return true;
610 }
611
612 void SpeechInputExtensionManager::ForceStopOnIOThread() {
613 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
614 VLOG(1) << "Requesting forced stop (IO thread)";
615
616 base::AutoLock auto_lock(state_lock_);
617 DCHECK(state_ != kIdle);
618
619 GetSpeechInputExtensionInterface()->StopRecording(false);
620
621 if (state_ == kShutdown)
622 return;
623
624 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
625 base::Bind(&SpeechInputExtensionManager::StopSucceededOnUIThread, this));
626 }
627
628 void SpeechInputExtensionManager::StopRecording(bool recognition_failed) {
629 if (recognizer_) {
630 // Recognition is already cancelled in case of failure.
631 // Double-cancelling leads to assertion failures.
632 if (!recognition_failed)
633 recognizer_->CancelRecognition();
634 recognizer_.release();
635 }
636 }
637
638 void SpeechInputExtensionManager::StopSucceededOnUIThread() {
639 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
640 VLOG(1) << "Stop succeeded (UI thread)";
641
642 base::AutoLock auto_lock(state_lock_);
643 if (state_ == kShutdown)
644 return;
645
646 std::string extension_id = extension_id_in_use_;
647 ResetToIdleState();
648
649 notification_.Hide();
650
651 content::NotificationService::current()->Notify(
652 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_RECORDING_STOPPED,
653 // Guarded by the state_ == kShutdown check.
654 content::Source<Profile>(profile_),
655 content::Details<std::string>(&extension_id));
656 }
657
658 void SpeechInputExtensionManager::SetInputVolume(int caller_id,
659 float volume,
660 float noise_volume) {
661 DCHECK_EQ(caller_id, kSpeechCallerId);
662 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
663 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
664 base::Bind(&SpeechInputExtensionManager::SetInputVolumeOnUIThread,
665 this, volume));
666 }
667
668 void SpeechInputExtensionManager::SetInputVolumeOnUIThread(
669 float volume) {
670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
671 notification_.SetVUMeterVolume(volume);
672 }
OLDNEW
« no previous file with comments | « chrome/browser/speech/speech_input_extension_manager.h ('k') | chrome/browser/speech/speech_input_extension_notification.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698