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
3 // found in the LICENSE file.
5 #include "chrome/browser/speech/speech_recognition_bubble_controller.h"
8 #include "chrome/browser/tab_contents/tab_util.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/browser/notification_registrar.h"
11 #include "content/public/browser/notification_source.h"
12 #include "content/public/browser/notification_types.h"
13 #include "content/public/browser/render_process_host.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
17 using content::BrowserThread;
18 using content::WebContents;
21 const int kInvalidSessionId = 0;
26 SpeechRecognitionBubbleController::SpeechRecognitionBubbleController(
28 : delegate_(delegate),
29 last_request_issued_(REQUEST_CLOSE),
30 current_bubble_session_id_(kInvalidSessionId),
31 current_bubble_render_process_id_(0),
32 current_bubble_render_view_id_(0) {
35 SpeechRecognitionBubbleController::~SpeechRecognitionBubbleController() {
36 DCHECK_EQ(kInvalidSessionId, current_bubble_session_id_);
39 void SpeechRecognitionBubbleController::CreateBubble(
41 int render_process_id,
43 const gfx::Rect& element_rect) {
45 base::AutoLock auto_lock(lock_);
46 current_bubble_session_id_ = session_id;
47 current_bubble_render_process_id_ = render_process_id;
48 current_bubble_render_view_id_ = render_view_id;
51 UIRequest request(REQUEST_CREATE);
52 request.render_process_id = render_process_id;
53 request.render_view_id = render_view_id;
54 request.element_rect = element_rect;
55 ProcessRequestInUiThread(request);
58 void SpeechRecognitionBubbleController::SetBubbleRecordingMode() {
59 ProcessRequestInUiThread(UIRequest(REQUEST_SET_RECORDING_MODE));
62 void SpeechRecognitionBubbleController::SetBubbleRecognizingMode() {
63 ProcessRequestInUiThread(UIRequest(REQUEST_SET_RECOGNIZING_MODE));
66 void SpeechRecognitionBubbleController::SetBubbleMessage(
67 const base::string16& text) {
68 UIRequest request(REQUEST_SET_MESSAGE);
69 request.message = text;
70 ProcessRequestInUiThread(request);
73 bool SpeechRecognitionBubbleController::IsShowingMessage() const {
74 return last_request_issued_ == REQUEST_SET_MESSAGE;
77 void SpeechRecognitionBubbleController::SetBubbleInputVolume(
80 UIRequest request(REQUEST_SET_INPUT_VOLUME);
81 request.volume = volume;
82 request.noise_volume = noise_volume;
83 ProcessRequestInUiThread(request);
86 void SpeechRecognitionBubbleController::CloseBubble() {
88 base::AutoLock auto_lock(lock_);
89 current_bubble_session_id_ = kInvalidSessionId;
91 ProcessRequestInUiThread(UIRequest(REQUEST_CLOSE));
94 void SpeechRecognitionBubbleController::CloseBubbleForRenderViewOnUIThread(
95 int render_process_id, int render_view_id) {
97 base::AutoLock auto_lock(lock_);
98 if (current_bubble_session_id_ == kInvalidSessionId ||
99 current_bubble_render_process_id_ != render_process_id ||
100 current_bubble_render_view_id_ != render_view_id) {
103 current_bubble_session_id_ = kInvalidSessionId;
105 ProcessRequestInUiThread(UIRequest(REQUEST_CLOSE));
108 int SpeechRecognitionBubbleController::GetActiveSessionID() {
109 base::AutoLock auto_lock(lock_);
110 return current_bubble_session_id_;
113 void SpeechRecognitionBubbleController::InfoBubbleButtonClicked(
114 SpeechRecognitionBubble::Button button) {
115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
116 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
118 &SpeechRecognitionBubbleController::InvokeDelegateButtonClicked, this,
122 void SpeechRecognitionBubbleController::InfoBubbleFocusChanged() {
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
124 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
125 base::Bind(&SpeechRecognitionBubbleController::InvokeDelegateFocusChanged,
129 void SpeechRecognitionBubbleController::InvokeDelegateButtonClicked(
130 SpeechRecognitionBubble::Button button) {
131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
133 base::AutoLock auto_lock(lock_);
134 if (kInvalidSessionId == current_bubble_session_id_)
137 delegate_->InfoBubbleButtonClicked(current_bubble_session_id_, button);
140 void SpeechRecognitionBubbleController::InvokeDelegateFocusChanged() {
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
143 base::AutoLock auto_lock(lock_);
144 if (kInvalidSessionId == current_bubble_session_id_)
147 delegate_->InfoBubbleFocusChanged(current_bubble_session_id_);
150 void SpeechRecognitionBubbleController::ProcessRequestInUiThread(
151 const UIRequest& request) {
152 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
153 last_request_issued_ = request.type;
154 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
155 base::Bind(&SpeechRecognitionBubbleController::ProcessRequestInUiThread,
160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
162 // In the case of a tab closed or crashed, the bubble can have been destroyed
163 // earlier on the UI thread, while other tasks were being enqueued from the IO
164 // to the UI thread. Simply return in such cases.
165 if (request.type != REQUEST_CREATE && !bubble_.get())
168 switch (request.type) {
170 bubble_.reset(SpeechRecognitionBubble::Create(
171 request.render_process_id, request.render_view_id,
172 this, request.element_rect));
174 if (!bubble_.get()) {
175 // Could be null if tab or display rect were invalid.
176 // Simulate the cancel button being clicked to inform the delegate.
177 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
179 &SpeechRecognitionBubbleController::InvokeDelegateButtonClicked,
180 this, SpeechRecognitionBubble::BUTTON_CANCEL));
184 bubble_->SetWarmUpMode();
186 case REQUEST_SET_RECORDING_MODE:
187 bubble_->SetRecordingMode();
189 case REQUEST_SET_RECOGNIZING_MODE:
190 bubble_->SetRecognizingMode();
192 case REQUEST_SET_MESSAGE:
193 bubble_->SetMessage(request.message);
195 case REQUEST_SET_INPUT_VOLUME:
196 bubble_->SetInputVolume(request.volume, request.noise_volume);
207 SpeechRecognitionBubbleController::UIRequest::UIRequest(RequestType type_value)
211 render_process_id(0),
215 SpeechRecognitionBubbleController::UIRequest::~UIRequest() {
218 } // namespace speech