speech_input_manager.cc revision 731df977c0511bca2206b5f333555b1205ff1f43
1bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/speech/speech_input_manager.h" 6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "app/l10n_util.h" 8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/ref_counted.h" 9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/singleton.h" 10731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/browser_thread.h" 11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/speech/speech_input_bubble_controller.h" 12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/speech/speech_recognizer.h" 13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/tab_contents/infobar_delegate.h" 14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/tab_contents/tab_contents.h" 15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/tab_contents/tab_util.h" 16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "grit/generated_resources.h" 17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "media/audio/audio_manager.h" 18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <map> 19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace speech_input { 21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass SpeechInputManagerImpl : public SpeechInputManager, 23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public SpeechInputBubbleControllerDelegate, 24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public SpeechRecognizerDelegate { 25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public: 26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // SpeechInputManager methods. 27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void StartRecognition(SpeechInputManagerDelegate* delegate, 28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int caller_id, 29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int render_process_id, 30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int render_view_id, 31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const gfx::Rect& element_rect); 32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void CancelRecognition(int caller_id); 33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void StopRecording(int caller_id); 34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // SpeechRecognizer::Delegate methods. 36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void SetRecognitionResult(int caller_id, bool error, 37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const string16& value); 38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void DidCompleteRecording(int caller_id); 39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void DidCompleteRecognition(int caller_id); 40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void OnRecognizerError(int caller_id, 41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechRecognizer::ErrorCode error); 42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void DidCompleteEnvironmentEstimation(int caller_id); 43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void SetInputVolume(int caller_id, float volume); 44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // SpeechInputBubbleController::Delegate methods. 46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void InfoBubbleButtonClicked(int caller_id, 47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechInputBubble::Button button); 48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual void InfoBubbleFocusChanged(int caller_id); 49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private: 51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen struct SpeechInputRequest { 52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechInputManagerDelegate* delegate; 53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen scoped_refptr<SpeechRecognizer> recognizer; 54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool is_active; // Set to true when recording or recognition is going on. 55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen }; 56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Private constructor to enforce singleton. 58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen friend struct DefaultSingletonTraits<SpeechInputManagerImpl>; 59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechInputManagerImpl(); 60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen virtual ~SpeechInputManagerImpl(); 61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool HasPendingRequest(int caller_id) const; 63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechInputManagerDelegate* GetDelegate(int caller_id) const; 64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void CancelRecognitionAndInformDelegate(int caller_id); 66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Starts/restarts recognition for an existing request. 68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen void StartRecognitionForRequest(int caller_id); 69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechInputManagerDelegate* delegate_; 71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen typedef std::map<int, SpeechInputRequest> SpeechRecognizerMap; 72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechRecognizerMap requests_; 73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int recording_caller_id_; 74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen scoped_refptr<SpeechInputBubbleController> bubble_controller_; 75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}; 76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSpeechInputManager* SpeechInputManager::Get() { 78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return Singleton<SpeechInputManagerImpl>::get(); 79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSpeechInputManagerImpl::SpeechInputManagerImpl() 82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen : recording_caller_id_(0), 83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bubble_controller_(new SpeechInputBubbleController( 84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ALLOW_THIS_IN_INITIALIZER_LIST(this))) { 85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSpeechInputManagerImpl::~SpeechInputManagerImpl() { 88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen while (requests_.begin() != requests_.end()) 89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen CancelRecognition(requests_.begin()->first); 90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool SpeechInputManagerImpl::HasPendingRequest(int caller_id) const { 93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return requests_.find(caller_id) != requests_.end(); 94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSpeechInputManagerDelegate* SpeechInputManagerImpl::GetDelegate( 97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int caller_id) const { 98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return requests_.find(caller_id)->second.delegate; 99bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::StartRecognition( 102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechInputManagerDelegate* delegate, 103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int caller_id, 104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int render_process_id, 105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int render_view_id, 106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const gfx::Rect& element_rect) { 107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(!HasPendingRequest(caller_id)); 108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bubble_controller_->CreateBubble(caller_id, render_process_id, render_view_id, 110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen element_rect); 111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechInputRequest* request = &requests_[caller_id]; 113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen request->delegate = delegate; 114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen request->recognizer = new SpeechRecognizer(this, caller_id); 115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen request->is_active = false; 116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen StartRecognitionForRequest(caller_id); 118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::StartRecognitionForRequest(int caller_id) { 121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(HasPendingRequest(caller_id)); 122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // If we are currently recording audio for another caller, abort that cleanly. 124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (recording_caller_id_) 125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen CancelRecognitionAndInformDelegate(recording_caller_id_); 126bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!AudioManager::GetAudioManager()->HasAudioInputDevices()) { 128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bubble_controller_->SetBubbleMessage( 129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen caller_id, l10n_util::GetStringUTF16(IDS_SPEECH_INPUT_NO_MIC)); 130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } else { 131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen recording_caller_id_ = caller_id; 132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen requests_[caller_id].is_active = true; 133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen requests_[caller_id].recognizer->StartRecording(); 134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::CancelRecognition(int caller_id) { 138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(HasPendingRequest(caller_id)); 139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (requests_[caller_id].is_active) 140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen requests_[caller_id].recognizer->CancelRecognition(); 141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen requests_.erase(caller_id); 142bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (recording_caller_id_ == caller_id) 143bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen recording_caller_id_ = 0; 144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bubble_controller_->CloseBubble(caller_id); 145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::StopRecording(int caller_id) { 148bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(HasPendingRequest(caller_id)); 149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen requests_[caller_id].recognizer->StopRecording(); 150bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::SetRecognitionResult(int caller_id, 153bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bool error, 154bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const string16& value) { 155bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(HasPendingRequest(caller_id)); 156bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen GetDelegate(caller_id)->SetRecognitionResult(caller_id, 157bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen (error ? string16() : value)); 158bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::DidCompleteRecording(int caller_id) { 161bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(recording_caller_id_ == caller_id); 162bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(HasPendingRequest(caller_id)); 163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen recording_caller_id_ = 0; 164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen GetDelegate(caller_id)->DidCompleteRecording(caller_id); 165bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bubble_controller_->SetBubbleRecognizingMode(caller_id); 166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::DidCompleteRecognition(int caller_id) { 169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen GetDelegate(caller_id)->DidCompleteRecognition(caller_id); 170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen requests_.erase(caller_id); 171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bubble_controller_->CloseBubble(caller_id); 172bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 173bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::OnRecognizerError( 175bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int caller_id, SpeechRecognizer::ErrorCode error) { 176bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (caller_id == recording_caller_id_) 177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen recording_caller_id_ = 0; 178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 179bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen requests_[caller_id].is_active = false; 180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 181bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int message_id; 182bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen switch (error) { 183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen case SpeechRecognizer::RECOGNIZER_ERROR_CAPTURE: 184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen message_id = IDS_SPEECH_INPUT_ERROR; 185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen break; 186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen case SpeechRecognizer::RECOGNIZER_ERROR_NO_SPEECH: 187bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen message_id = IDS_SPEECH_INPUT_NO_SPEECH; 188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen break; 189bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen case SpeechRecognizer::RECOGNIZER_ERROR_NO_RESULTS: 190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen message_id = IDS_SPEECH_INPUT_NO_RESULTS; 191bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen break; 192bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen default: 193bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NOTREACHED() << "unknown error " << error; 194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 195bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 196bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bubble_controller_->SetBubbleMessage(caller_id, 197bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen l10n_util::GetStringUTF16(message_id)); 198bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 199bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 200bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::DidCompleteEnvironmentEstimation(int caller_id) { 201bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(HasPendingRequest(caller_id)); 202bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(recording_caller_id_ == caller_id); 203bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 204bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Speech recognizer has gathered enough background audio so we can ask the 205bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // user to start speaking. 206bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bubble_controller_->SetBubbleRecordingMode(caller_id); 207bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 208bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 209bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::SetInputVolume(int caller_id, float volume) { 210bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(HasPendingRequest(caller_id)); 211bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK_EQ(recording_caller_id_, caller_id); 212bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 213bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen bubble_controller_->SetBubbleInputVolume(caller_id, volume); 214bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 215bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 216bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::CancelRecognitionAndInformDelegate(int caller_id) { 217bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SpeechInputManagerDelegate* cur_delegate = GetDelegate(caller_id); 218bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen CancelRecognition(caller_id); 219bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen cur_delegate->DidCompleteRecording(caller_id); 220bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen cur_delegate->DidCompleteRecognition(caller_id); 221bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 222bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 223bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::InfoBubbleButtonClicked( 224bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int caller_id, SpeechInputBubble::Button button) { 225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 226bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Ignore if the caller id was not in our active recognizers list because the 227bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // user might have clicked more than once, or recognition could have been 228bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // cancelled due to other reasons before the user click was processed. 229bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!HasPendingRequest(caller_id)) 230bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 231bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 232bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (button == SpeechInputBubble::BUTTON_CANCEL) { 233bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen CancelRecognitionAndInformDelegate(caller_id); 234bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } else if (button == SpeechInputBubble::BUTTON_TRY_AGAIN) { 235bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen StartRecognitionForRequest(caller_id); 236bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 237bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 238bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 239bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid SpeechInputManagerImpl::InfoBubbleFocusChanged(int caller_id) { 240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 241bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Ignore if the caller id was not in our active recognizers list because the 242bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // user might have clicked more than once, or recognition could have been 243bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // ended due to other reasons before the user click was processed. 244bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (HasPendingRequest(caller_id)) { 245bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // If this is an ongoing recording or if we were displaying an error message 246bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // to the user, abort it since user has switched focus. Otherwise 247bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // recognition has started and keep that going so user can start speaking to 248bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // another element while this gets the results in parallel. 249bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (recording_caller_id_ == caller_id || !requests_[caller_id].is_active) { 250bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen CancelRecognitionAndInformDelegate(caller_id); 251bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 252bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 253bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 254bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 255bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} // namespace speech_input 256