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

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

Issue 10407120: Moving tray icon and notification balloon for background speech recognition sessions to ChromeSpeec… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed win issued ("interface" member clashes with a VS macro name, sigh) Created 8 years, 6 months 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
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_host.h"
13 #include "chrome/browser/extensions/extension_process_manager.h"
12 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/prefs/pref_service.h" 15 #include "chrome/browser/extensions/extension_system.h"
14 #include "chrome/browser/profiles/profile.h" 16 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_dependency_manager.h" 17 #include "chrome/browser/profiles/profile_dependency_manager.h"
16 #include "chrome/browser/profiles/profile_keyed_service.h" 18 #include "chrome/browser/profiles/profile_keyed_service.h"
17 #include "chrome/browser/profiles/profile_keyed_service_factory.h" 19 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
18 #include "chrome/common/chrome_notification_types.h" 20 #include "chrome/common/chrome_notification_types.h"
19 #include "chrome/common/extensions/extension.h" 21 #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/browser_thread.h"
22 #include "content/public/browser/notification_registrar.h" 23 #include "content/public/browser/notification_registrar.h"
23 #include "content/public/browser/notification_service.h" 24 #include "content/public/browser/notification_service.h"
25 #include "content/public/browser/render_process_host.h"
24 #include "content/public/browser/speech_recognition_manager.h" 26 #include "content/public/browser/speech_recognition_manager.h"
25 #include "content/public/browser/speech_recognition_session_config.h" 27 #include "content/public/browser/speech_recognition_session_config.h"
26 #include "content/public/browser/speech_recognition_session_context.h" 28 #include "content/public/browser/speech_recognition_session_context.h"
27 #include "content/public/common/speech_recognition_error.h" 29 #include "content/public/common/speech_recognition_error.h"
28 #include "content/public/common/speech_recognition_result.h" 30 #include "content/public/common/speech_recognition_result.h"
29 #include "net/url_request/url_request_context_getter.h" 31 #include "net/url_request/url_request_context_getter.h"
30 32
31 using content::BrowserThread; 33 using content::BrowserThread;
32 using content::SpeechRecognitionHypothesis; 34 using content::SpeechRecognitionHypothesis;
33 using content::SpeechRecognitionManager; 35 using content::SpeechRecognitionManager;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 90
89 private: 91 private:
90 friend struct DefaultSingletonTraits<Factory>; 92 friend struct DefaultSingletonTraits<Factory>;
91 93
92 Factory(); 94 Factory();
93 virtual ~Factory(); 95 virtual ~Factory();
94 96
95 // ProfileKeyedServiceFactory methods: 97 // ProfileKeyedServiceFactory methods:
96 virtual ProfileKeyedService* BuildServiceInstanceFor( 98 virtual ProfileKeyedService* BuildServiceInstanceFor(
97 Profile* profile) const OVERRIDE; 99 Profile* profile) const OVERRIDE;
98 virtual void RegisterUserPrefs(PrefService* prefs) OVERRIDE;
99 virtual bool ServiceRedirectedInIncognito() OVERRIDE { return false; } 100 virtual bool ServiceRedirectedInIncognito() OVERRIDE { return false; }
100 virtual bool ServiceIsNULLWhileTesting() OVERRIDE { return true; } 101 virtual bool ServiceIsNULLWhileTesting() OVERRIDE { return true; }
101 virtual bool ServiceIsCreatedWithProfile() OVERRIDE { return true; } 102 virtual bool ServiceIsCreatedWithProfile() OVERRIDE { return true; }
102 103
103 DISALLOW_COPY_AND_ASSIGN(Factory); 104 DISALLOW_COPY_AND_ASSIGN(Factory);
104 }; 105 };
105 106
106 void SpeechInputExtensionManager::Factory::Initialize() { 107 void SpeechInputExtensionManager::Factory::Initialize() {
107 GetInstance(); 108 GetInstance();
108 } 109 }
(...skipping 19 matching lines...) Expand all
128 } 129 }
129 130
130 ProfileKeyedService* 131 ProfileKeyedService*
131 SpeechInputExtensionManager::Factory::BuildServiceInstanceFor( 132 SpeechInputExtensionManager::Factory::BuildServiceInstanceFor(
132 Profile* profile) const { 133 Profile* profile) const {
133 scoped_refptr<SpeechInputExtensionManager> manager( 134 scoped_refptr<SpeechInputExtensionManager> manager(
134 new SpeechInputExtensionManager(profile)); 135 new SpeechInputExtensionManager(profile));
135 return new SpeechInputExtensionManagerWrapper(manager); 136 return new SpeechInputExtensionManagerWrapper(manager);
136 } 137 }
137 138
138 void SpeechInputExtensionManager::Factory::RegisterUserPrefs(
139 PrefService* prefs) {
140 prefs->RegisterBooleanPref(prefs::kSpeechInputTrayNotificationShown,
141 false,
142 PrefService::UNSYNCABLE_PREF);
143 }
144
145 SpeechInputExtensionInterface::SpeechInputExtensionInterface() { 139 SpeechInputExtensionInterface::SpeechInputExtensionInterface() {
146 } 140 }
147 141
148 SpeechInputExtensionInterface::~SpeechInputExtensionInterface() { 142 SpeechInputExtensionInterface::~SpeechInputExtensionInterface() {
149 } 143 }
150 144
151 SpeechInputExtensionManager::SpeechInputExtensionManager(Profile* profile) 145 SpeechInputExtensionManager::SpeechInputExtensionManager(Profile* profile)
152 : profile_(profile), 146 : profile_(profile),
153 state_(kIdle), 147 state_(kIdle),
154 registrar_(new content::NotificationRegistrar), 148 registrar_(new content::NotificationRegistrar),
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 VLOG(1) << "Extension unloaded. Requesting to enforce stop..."; 228 VLOG(1) << "Extension unloaded. Requesting to enforce stop...";
235 if (extension_id_in_use_ == extension_id) { 229 if (extension_id_in_use_ == extension_id) {
236 if (state_ != kIdle) { 230 if (state_ != kIdle) {
237 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 231 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
238 base::Bind(&SpeechInputExtensionManager::ForceStopOnIOThread, this)); 232 base::Bind(&SpeechInputExtensionManager::ForceStopOnIOThread, this));
239 } 233 }
240 } 234 }
241 } 235 }
242 236
243 void SpeechInputExtensionManager::SetSpeechInputExtensionInterface( 237 void SpeechInputExtensionManager::SetSpeechInputExtensionInterface(
244 SpeechInputExtensionInterface* interface) { 238 SpeechInputExtensionInterface* speech_interface) {
245 speech_interface_ = interface; 239 speech_interface_ = speech_interface;
246 } 240 }
247 241
248 SpeechInputExtensionInterface* 242 SpeechInputExtensionInterface*
249 SpeechInputExtensionManager::GetSpeechInputExtensionInterface() { 243 SpeechInputExtensionManager::GetSpeechInputExtensionInterface() {
250 return speech_interface_ ? speech_interface_ : this; 244 return speech_interface_ ? speech_interface_ : this;
251 } 245 }
252 246
253 void SpeechInputExtensionManager::ResetToIdleState() { 247 void SpeechInputExtensionManager::ResetToIdleState() {
254 VLOG(1) << "State changed to idle. Deassociating any extensions."; 248 VLOG(1) << "State changed to idle. Deassociating any extensions.";
255 state_ = kIdle; 249 state_ = kIdle;
256 extension_id_in_use_.clear(); 250 extension_id_in_use_.clear();
257 } 251 }
258 252
253 int SpeechInputExtensionManager::GetRenderProcessIDForExtension(
254 const std::string& extension_id) const {
255 ExtensionProcessManager* epm =
256 ExtensionSystem::Get(profile_)->process_manager();
257 DCHECK(epm);
258 ExtensionHost* eh = epm->GetBackgroundHostForExtension(extension_id);
259 DCHECK(eh);
260 content::RenderProcessHost* rph = eh->render_process_host();
261 DCHECK(rph);
262 return rph->GetID();
263 }
264
259 void SpeechInputExtensionManager::OnRecognitionResult( 265 void SpeechInputExtensionManager::OnRecognitionResult(
260 int session_id, 266 int session_id,
261 const content::SpeechRecognitionResult& result) { 267 const content::SpeechRecognitionResult& result) {
262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
263 DCHECK_EQ(session_id, speech_recognition_session_id_); 269 DCHECK_EQ(session_id, speech_recognition_session_id_);
264 270
265 // Stopping will start the disassociation with the extension. 271 // Stopping will start the disassociation with the extension.
266 // Make a copy to report the results to the proper one. 272 // Make a copy to report the results to the proper one.
267 std::string extension_id = extension_id_in_use_; 273 std::string extension_id = extension_id_in_use_;
268 ForceStopOnIOThread(); 274 ForceStopOnIOThread();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 340
335 base::AutoLock auto_lock(state_lock_); 341 base::AutoLock auto_lock(state_lock_);
336 if (state_ == kShutdown) 342 if (state_ == kShutdown)
337 return; 343 return;
338 344
339 DCHECK_EQ(state_, kStarting); 345 DCHECK_EQ(state_, kStarting);
340 VLOG(1) << "State changed to recording"; 346 VLOG(1) << "State changed to recording";
341 state_ = kRecording; 347 state_ = kRecording;
342 348
343 DCHECK(profile_); 349 DCHECK(profile_);
344 profile_->GetPrefs()->SetBoolean(
345 prefs::kSpeechInputTrayNotificationShown, true);
346 350
347 VLOG(1) << "Sending start notification"; 351 VLOG(1) << "Sending start notification";
348 content::NotificationService::current()->Notify( 352 content::NotificationService::current()->Notify(
349 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_RECORDING_STARTED, 353 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_RECORDING_STARTED,
350 content::Source<Profile>(profile_), 354 content::Source<Profile>(profile_),
351 content::Details<std::string>(&extension_id_in_use_)); 355 content::Details<std::string>(&extension_id_in_use_));
352 } 356 }
353 357
354 void SpeechInputExtensionManager::OnRecognitionError( 358 void SpeechInputExtensionManager::OnRecognitionError(
355 int session_id, const content::SpeechRecognitionError& error) { 359 int session_id, const content::SpeechRecognitionError& error) {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 *error = kErrorInvalidOperation; 535 *error = kErrorInvalidOperation;
532 return false; 536 return false;
533 537
534 default: 538 default:
535 NOTREACHED(); 539 NOTREACHED();
536 } 540 }
537 541
538 const extensions::Extension* extension = profile_->GetExtensionService()-> 542 const extensions::Extension* extension = profile_->GetExtensionService()->
539 GetExtensionById(extension_id, true); 543 GetExtensionById(extension_id, true);
540 DCHECK(extension); 544 DCHECK(extension);
541 const string16& extension_name = UTF8ToUTF16(extension->name()); 545 const std::string& extension_name = extension->name();
542 546
543 extension_id_in_use_ = extension_id; 547 extension_id_in_use_ = extension_id;
544 VLOG(1) << "State changed to starting"; 548 VLOG(1) << "State changed to starting";
545 state_ = kStarting; 549 state_ = kStarting;
546 550
547 // Checks if the security notification balloon has been already shown (only
548 // once for a profile). It is reset on DidStartReceivingAudioOnUIThread.
549 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = 551 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
550 profile_->GetRequestContext(); 552 profile_->GetRequestContext();
551 const bool show_notification = !profile_->GetPrefs()->GetBoolean( 553
552 prefs::kSpeechInputTrayNotificationShown); 554 const int render_process_id = GetRenderProcessIDForExtension(extension_id);
553 555
554 BrowserThread::PostTask( 556 BrowserThread::PostTask(
555 BrowserThread::IO, FROM_HERE, 557 BrowserThread::IO, FROM_HERE,
556 base::Bind(&SpeechInputExtensionManager::StartOnIOThread, this, 558 base::Bind(&SpeechInputExtensionManager::StartOnIOThread, this,
557 url_request_context_getter, extension_name, language, grammar, 559 url_request_context_getter, extension_name, language, grammar,
558 filter_profanities, show_notification)); 560 filter_profanities, render_process_id));
559 return true; 561 return true;
560 } 562 }
561 563
562 void SpeechInputExtensionManager::StartOnIOThread( 564 void SpeechInputExtensionManager::StartOnIOThread(
563 scoped_refptr<net::URLRequestContextGetter> context_getter, 565 scoped_refptr<net::URLRequestContextGetter> context_getter,
564 const string16& extension_name, 566 const std::string& extension_name,
565 const std::string& language, 567 const std::string& language,
566 const std::string& grammar, 568 const std::string& grammar,
567 bool filter_profanities, 569 bool filter_profanities,
568 bool show_notification) { 570 int render_process_id) {
569 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 571 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
570 VLOG(1) << "Requesting start (IO thread)"; 572 VLOG(1) << "Requesting start (IO thread)";
571 573
572 // Everything put inside the lock to ensure the validity of context_getter, 574 // Everything put inside the lock to ensure the validity of context_getter,
573 // guaranteed while not in the shutdown state. Any ongoing or recognition 575 // guaranteed while not in the shutdown state. Any ongoing or recognition
574 // request will be requested to be aborted when entering the shutdown state. 576 // request will be requested to be aborted when entering the shutdown state.
575 base::AutoLock auto_lock(state_lock_); 577 base::AutoLock auto_lock(state_lock_);
576 if (state_ == kShutdown) 578 if (state_ == kShutdown)
577 return; 579 return;
578 580
(...skipping 17 matching lines...) Expand all
596 std::string(kErrorRecordingDeviceInUse), false)); 598 std::string(kErrorRecordingDeviceInUse), false));
597 return; 599 return;
598 } 600 }
599 601
600 GetSpeechInputExtensionInterface()->StartRecording(this, 602 GetSpeechInputExtensionInterface()->StartRecording(this,
601 context_getter, 603 context_getter,
602 extension_name, 604 extension_name,
603 language, 605 language,
604 grammar, 606 grammar,
605 filter_profanities, 607 filter_profanities,
606 show_notification); 608 render_process_id);
607 } 609 }
608 610
609 bool SpeechInputExtensionManager::HasAudioInputDevices() { 611 bool SpeechInputExtensionManager::HasAudioInputDevices() {
610 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 612 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
611 return SpeechRecognitionManager::GetInstance()->HasAudioInputDevices(); 613 return SpeechRecognitionManager::GetInstance()->HasAudioInputDevices();
612 } 614 }
613 615
614 bool SpeechInputExtensionManager::IsCapturingAudio() { 616 bool SpeechInputExtensionManager::IsCapturingAudio() {
615 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 617 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
616 return SpeechRecognitionManager::GetInstance()->IsCapturingAudio(); 618 return SpeechRecognitionManager::GetInstance()->IsCapturingAudio();
(...skipping 23 matching lines...) Expand all
640 void SpeechInputExtensionManager::IsRecordingOnUIThread( 642 void SpeechInputExtensionManager::IsRecordingOnUIThread(
641 const IsRecordingCallback& callback, 643 const IsRecordingCallback& callback,
642 bool result) { 644 bool result) {
643 BrowserThread::CurrentlyOn(BrowserThread::UI); 645 BrowserThread::CurrentlyOn(BrowserThread::UI);
644 callback.Run(result); 646 callback.Run(result);
645 } 647 }
646 648
647 void SpeechInputExtensionManager::StartRecording( 649 void SpeechInputExtensionManager::StartRecording(
648 content::SpeechRecognitionEventListener* listener, 650 content::SpeechRecognitionEventListener* listener,
649 net::URLRequestContextGetter* context_getter, 651 net::URLRequestContextGetter* context_getter,
650 const string16& extension_name, 652 const std::string& extension_name,
651 const std::string& language, 653 const std::string& language,
652 const std::string& grammar, 654 const std::string& grammar,
653 bool filter_profanities, 655 bool filter_profanities,
654 bool show_notification) { 656 int render_process_id) {
655 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 657 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
656 658
657 content::SpeechRecognitionSessionContext context; 659 content::SpeechRecognitionSessionContext context;
658 context.requested_by_page_element = false; 660 context.requested_by_page_element = false;
659 context.is_first_request_for_context = show_notification; 661 context.render_process_id = render_process_id;
660 context.context_name = extension_name; 662 context.context_name = extension_name;
661 663
662 content::SpeechRecognitionSessionConfig config; 664 content::SpeechRecognitionSessionConfig config;
663 // config.is_one_shot = true; // TODO(primiano) Uncomment when CL2.0 lands. 665 // config.is_one_shot = true; // TODO(primiano) Uncomment when CL2.0 lands.
664 config.language = language; 666 config.language = language;
665 config.grammars.push_back(content::SpeechRecognitionGrammar(grammar)); 667 config.grammars.push_back(content::SpeechRecognitionGrammar(grammar));
666 config.initial_context = context; 668 config.initial_context = context;
667 config.url_request_context_getter = context_getter; 669 config.url_request_context_getter = context_getter;
668 config.filter_profanities = filter_profanities; 670 config.filter_profanities = filter_profanities;
669 config.event_listener = listener; 671 config.event_listener = listener;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 content::NotificationService::current()->Notify( 767 content::NotificationService::current()->Notify(
766 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_RECORDING_STOPPED, 768 chrome::NOTIFICATION_EXTENSION_SPEECH_INPUT_RECORDING_STOPPED,
767 // Guarded by the state_ == kShutdown check. 769 // Guarded by the state_ == kShutdown check.
768 content::Source<Profile>(profile_), 770 content::Source<Profile>(profile_),
769 content::Details<std::string>(&extension_id)); 771 content::Details<std::string>(&extension_id));
770 } 772 }
771 773
772 void SpeechInputExtensionManager::OnAudioLevelsChange(int session_id, 774 void SpeechInputExtensionManager::OnAudioLevelsChange(int session_id,
773 float volume, 775 float volume,
774 float noise_volume) {} 776 float noise_volume) {}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698