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 "chrome/browser/speech/speech_input_extension_manager.h" | 5 #include "chrome/browser/speech/speech_input_extension_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
11 #include "chrome/browser/extensions/extension_event_router.h" | 11 #include "chrome/browser/extensions/extension_event_router.h" |
12 #include "chrome/browser/extensions/extension_service.h" | 12 #include "chrome/browser/extensions/extension_service.h" |
13 #include "chrome/browser/prefs/pref_service.h" | 13 #include "chrome/browser/prefs/pref_service.h" |
14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/profiles/profile_dependency_manager.h" | 15 #include "chrome/browser/profiles/profile_dependency_manager.h" |
16 #include "chrome/browser/profiles/profile_keyed_service.h" | 16 #include "chrome/browser/profiles/profile_keyed_service.h" |
17 #include "chrome/browser/profiles/profile_keyed_service_factory.h" | 17 #include "chrome/browser/profiles/profile_keyed_service_factory.h" |
| 18 #include "chrome/browser/speech/chrome_speech_input_manager.h" |
18 #include "chrome/browser/speech/speech_input_extension_notification.h" | 19 #include "chrome/browser/speech/speech_input_extension_notification.h" |
19 #include "chrome/common/chrome_notification_types.h" | 20 #include "chrome/common/chrome_notification_types.h" |
20 #include "chrome/common/extensions/extension.h" | 21 #include "chrome/common/extensions/extension.h" |
21 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
22 #include "content/browser/speech/speech_recognizer.h" | 23 #include "content/browser/speech/speech_recognizer.h" |
23 #include "content/public/browser/browser_thread.h" | 24 #include "content/public/browser/browser_thread.h" |
24 #include "content/public/browser/notification_registrar.h" | 25 #include "content/public/browser/notification_registrar.h" |
25 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
26 #include "content/public/browser/resource_context.h" | |
27 #include "content/public/common/speech_input_result.h" | 27 #include "content/public/common/speech_input_result.h" |
28 | 28 |
29 using content::BrowserThread; | 29 using content::BrowserThread; |
| 30 using speech_input::ChromeSpeechInputManager; |
30 using speech_input::SpeechRecognizer; | 31 using speech_input::SpeechRecognizer; |
31 | 32 |
32 namespace { | 33 namespace { |
33 | 34 |
34 const char kErrorNoRecordingDeviceFound[] = "noRecordingDeviceFound"; | 35 const char kErrorNoRecordingDeviceFound[] = "noRecordingDeviceFound"; |
35 const char kErrorRecordingDeviceInUse[] = "recordingDeviceInUse"; | 36 const char kErrorRecordingDeviceInUse[] = "recordingDeviceInUse"; |
36 const char kErrorUnableToStart[] = "unableToStart"; | 37 const char kErrorUnableToStart[] = "unableToStart"; |
37 const char kErrorRequestDenied[] = "requestDenied"; | 38 const char kErrorRequestDenied[] = "requestDenied"; |
38 const char kErrorRequestInProgress[] = "requestInProgress"; | 39 const char kErrorRequestInProgress[] = "requestInProgress"; |
39 const char kErrorInvalidOperation[] = "invalidOperation"; | 40 const char kErrorInvalidOperation[] = "invalidOperation"; |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 DictionaryValue* js_error = new DictionaryValue(); | 471 DictionaryValue* js_error = new DictionaryValue(); |
471 args.Append(js_error); | 472 args.Append(js_error); |
472 js_error->SetString(kErrorCodeKey, error); | 473 js_error->SetString(kErrorCodeKey, error); |
473 std::string json_args; | 474 std::string json_args; |
474 base::JSONWriter::Write(&args, false, &json_args); | 475 base::JSONWriter::Write(&args, false, &json_args); |
475 DispatchEventToExtension(extension_id, | 476 DispatchEventToExtension(extension_id, |
476 kOnErrorEvent, json_args); | 477 kOnErrorEvent, json_args); |
477 } | 478 } |
478 } | 479 } |
479 | 480 |
480 bool SpeechInputExtensionManager::Start(const std::string& extension_id, | 481 bool SpeechInputExtensionManager::Start( |
481 const std::string& language, const std::string& grammar, | 482 const std::string& extension_id, const std::string& language, |
482 bool filter_profanities, std::string* error) { | 483 const std::string& grammar, bool filter_profanities, std::string* error) { |
483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 484 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
484 DCHECK(error); | 485 DCHECK(error); |
485 VLOG(1) << "Requesting start (UI thread)"; | 486 VLOG(1) << "Requesting start (UI thread)"; |
486 | 487 |
487 base::AutoLock auto_lock(state_lock_); | 488 base::AutoLock auto_lock(state_lock_); |
488 if (state_ == kShutdown || | 489 if (state_ == kShutdown || |
489 (!extension_id_in_use_.empty() && extension_id_in_use_ != extension_id)) { | 490 (!extension_id_in_use_.empty() && extension_id_in_use_ != extension_id)) { |
490 *error = kErrorRequestDenied; | 491 *error = kErrorRequestDenied; |
491 return false; | 492 return false; |
492 } | 493 } |
(...skipping 12 matching lines...) Expand all Loading... |
505 return false; | 506 return false; |
506 | 507 |
507 default: | 508 default: |
508 NOTREACHED(); | 509 NOTREACHED(); |
509 } | 510 } |
510 | 511 |
511 extension_id_in_use_ = extension_id; | 512 extension_id_in_use_ = extension_id; |
512 VLOG(1) << "State changed to starting"; | 513 VLOG(1) << "State changed to starting"; |
513 state_ = kStarting; | 514 state_ = kStarting; |
514 | 515 |
515 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 516 BrowserThread::PostTask( |
| 517 BrowserThread::IO, FROM_HERE, |
516 base::Bind(&SpeechInputExtensionManager::StartOnIOThread, this, | 518 base::Bind(&SpeechInputExtensionManager::StartOnIOThread, this, |
517 profile_->GetRequestContext(), profile_->GetResourceContext(), | 519 profile_->GetRequestContext(), language, grammar, |
518 language, grammar, filter_profanities)); | 520 filter_profanities)); |
519 return true; | 521 return true; |
520 } | 522 } |
521 | 523 |
522 void SpeechInputExtensionManager::StartOnIOThread( | 524 void SpeechInputExtensionManager::StartOnIOThread( |
523 net::URLRequestContextGetter* context_getter, | 525 net::URLRequestContextGetter* context_getter, |
524 content::ResourceContext* resource_context, | |
525 const std::string& language, | 526 const std::string& language, |
526 const std::string& grammar, | 527 const std::string& grammar, |
527 bool filter_profanities) { | 528 bool filter_profanities) { |
528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
529 VLOG(1) << "Requesting start (IO thread)"; | 530 VLOG(1) << "Requesting start (IO thread)"; |
530 | 531 |
531 // Everything put inside the lock to ensure the validity of context_getter, | 532 // Everything put inside the lock to ensure the validity of context_getter, |
532 // guaranteed while not in the shutdown state. Any ongoing or recognition | 533 // guaranteed while not in the shutdown state. Any ongoing or recognition |
533 // request will be requested to be aborted when entering the shutdown state. | 534 // request will be requested to be aborted when entering the shutdown state. |
534 base::AutoLock auto_lock(state_lock_); | 535 base::AutoLock auto_lock(state_lock_); |
535 if (state_ == kShutdown) | 536 if (state_ == kShutdown) |
536 return; | 537 return; |
537 | 538 |
538 if (!GetSpeechInputExtensionInterface()->HasAudioInputDevices( | 539 if (!GetSpeechInputExtensionInterface()->HasAudioInputDevices()) { |
539 resource_context)) { | 540 BrowserThread::PostTask( |
540 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 541 BrowserThread::UI, FROM_HERE, |
541 base::Bind(&SpeechInputExtensionManager::DispatchError, this, | 542 base::Bind(&SpeechInputExtensionManager::DispatchError, this, |
542 std::string(kErrorNoRecordingDeviceFound), false)); | 543 std::string(kErrorNoRecordingDeviceFound), false)); |
543 return; | 544 return; |
544 } | 545 } |
545 | 546 |
546 if (GetSpeechInputExtensionInterface()->IsRecordingInProcess( | 547 if (GetSpeechInputExtensionInterface()->IsRecordingInProcess()) { |
547 resource_context)) { | |
548 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 548 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
549 base::Bind(&SpeechInputExtensionManager::DispatchError, this, | 549 base::Bind(&SpeechInputExtensionManager::DispatchError, this, |
550 std::string(kErrorRecordingDeviceInUse), false)); | 550 std::string(kErrorRecordingDeviceInUse), false)); |
551 return; | 551 return; |
552 } | 552 } |
553 | 553 |
554 GetSpeechInputExtensionInterface()->StartRecording(this, context_getter, | 554 GetSpeechInputExtensionInterface()->StartRecording( |
555 resource_context, kSpeechCallerId, language, grammar, filter_profanities); | 555 this, context_getter, kSpeechCallerId, language, grammar, |
| 556 filter_profanities); |
556 } | 557 } |
557 | 558 |
558 bool SpeechInputExtensionManager::HasAudioInputDevices( | 559 bool SpeechInputExtensionManager::HasAudioInputDevices() { |
559 content::ResourceContext* resource_context) { | |
560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 560 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
561 DCHECK(resource_context); | 561 return ChromeSpeechInputManager::GetInstance()->HasAudioInputDevices(); |
562 return resource_context->GetAudioManager()->HasAudioInputDevices(); | |
563 } | 562 } |
564 | 563 |
565 bool SpeechInputExtensionManager::IsRecordingInProcess( | 564 bool SpeechInputExtensionManager::IsRecordingInProcess() { |
566 content::ResourceContext* resource_context) { | |
567 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 565 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
568 DCHECK(resource_context); | 566 return ChromeSpeechInputManager::GetInstance()->IsRecordingInProcess(); |
569 return resource_context->GetAudioManager()->IsRecordingInProcess(); | |
570 } | 567 } |
571 | 568 |
572 void SpeechInputExtensionManager::IsRecording( | 569 void SpeechInputExtensionManager::IsRecording( |
573 const IsRecordingCallback& callback) { | 570 const IsRecordingCallback& callback) { |
574 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 571 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
575 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 572 BrowserThread::PostTask( |
| 573 BrowserThread::IO, FROM_HERE, |
576 base::Bind(&SpeechInputExtensionManager::IsRecordingOnIOThread, | 574 base::Bind(&SpeechInputExtensionManager::IsRecordingOnIOThread, |
577 this, callback, profile_->GetResourceContext())); | 575 this, callback)); |
578 } | 576 } |
579 | 577 |
580 void SpeechInputExtensionManager::IsRecordingOnIOThread( | 578 void SpeechInputExtensionManager::IsRecordingOnIOThread( |
581 const IsRecordingCallback& callback, | 579 const IsRecordingCallback& callback) { |
582 content::ResourceContext* resource_context) { | |
583 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 580 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
584 DCHECK(resource_context); | |
585 | 581 |
586 bool result = GetSpeechInputExtensionInterface()->IsRecordingInProcess( | 582 bool result = GetSpeechInputExtensionInterface()->IsRecordingInProcess(); |
587 resource_context); | 583 BrowserThread::PostTask( |
588 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 584 BrowserThread::UI, FROM_HERE, |
589 base::Bind(&SpeechInputExtensionManager::IsRecordingOnUIThread, | 585 base::Bind(&SpeechInputExtensionManager::IsRecordingOnUIThread, |
590 this, callback, result)); | 586 this, callback, result)); |
591 } | 587 } |
592 | 588 |
593 void SpeechInputExtensionManager::IsRecordingOnUIThread( | 589 void SpeechInputExtensionManager::IsRecordingOnUIThread( |
594 const IsRecordingCallback& callback, | 590 const IsRecordingCallback& callback, |
595 bool result) { | 591 bool result) { |
596 BrowserThread::CurrentlyOn(BrowserThread::UI); | 592 BrowserThread::CurrentlyOn(BrowserThread::UI); |
597 callback.Run(result); | 593 callback.Run(result); |
598 } | 594 } |
599 | 595 |
600 void SpeechInputExtensionManager::StartRecording( | 596 void SpeechInputExtensionManager::StartRecording( |
601 content::SpeechRecognizerDelegate* delegate, | 597 content::SpeechRecognizerDelegate* delegate, |
602 net::URLRequestContextGetter* context_getter, | 598 net::URLRequestContextGetter* context_getter, |
603 content::ResourceContext* resource_context, | |
604 int caller_id, | 599 int caller_id, |
605 const std::string& language, | 600 const std::string& language, |
606 const std::string& grammar, | 601 const std::string& grammar, |
607 bool filter_profanities) { | 602 bool filter_profanities) { |
608 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 603 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
609 DCHECK(resource_context); | |
610 DCHECK(!recognizer_); | 604 DCHECK(!recognizer_); |
611 recognizer_ = new SpeechRecognizer(delegate, caller_id, language, grammar, | 605 recognizer_ = new SpeechRecognizer(delegate, caller_id, language, grammar, |
612 context_getter, resource_context->GetAudioManager(), | 606 context_getter, filter_profanities, "", ""); |
613 filter_profanities, "", ""); | |
614 recognizer_->StartRecording(); | 607 recognizer_->StartRecording(); |
615 } | 608 } |
616 | 609 |
617 bool SpeechInputExtensionManager::HasValidRecognizer() { | 610 bool SpeechInputExtensionManager::HasValidRecognizer() { |
618 // Conditional expression used to avoid a performance warning on windows. | 611 return !!recognizer_; |
619 return recognizer_ ? true : false; | |
620 } | 612 } |
621 | 613 |
622 bool SpeechInputExtensionManager::Stop(const std::string& extension_id, | 614 bool SpeechInputExtensionManager::Stop(const std::string& extension_id, |
623 std::string* error) { | 615 std::string* error) { |
624 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 616 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
625 DCHECK(error); | 617 DCHECK(error); |
626 VLOG(1) << "Requesting stop (UI thread)"; | 618 VLOG(1) << "Requesting stop (UI thread)"; |
627 | 619 |
628 base::AutoLock auto_lock(state_lock_); | 620 base::AutoLock auto_lock(state_lock_); |
629 if (state_ == kShutdown || | 621 if (state_ == kShutdown || |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 base::Bind(&SpeechInputExtensionManager::SetInputVolumeOnUIThread, | 708 base::Bind(&SpeechInputExtensionManager::SetInputVolumeOnUIThread, |
717 this, volume)); | 709 this, volume)); |
718 } | 710 } |
719 | 711 |
720 void SpeechInputExtensionManager::SetInputVolumeOnUIThread( | 712 void SpeechInputExtensionManager::SetInputVolumeOnUIThread( |
721 float volume) { | 713 float volume) { |
722 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 714 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
723 DCHECK(notification_.get()); | 715 DCHECK(notification_.get()); |
724 notification_->SetVUMeterVolume(volume); | 716 notification_->SetVUMeterVolume(volume); |
725 } | 717 } |
OLD | NEW |