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/chrome_speech_recognition_manager_delegate.h" | 5 #include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 // Sessions initiated by speech input extension APIs will end up in a NULL | 157 // Sessions initiated by speech input extension APIs will end up in a NULL |
158 // WebContent here, but they are properly managed by the | 158 // WebContent here, but they are properly managed by the |
159 // chrome::SpeechInputExtensionManager. However, sessions initiated within a | 159 // chrome::SpeechInputExtensionManager. However, sessions initiated within a |
160 // extension using the (new) speech JS APIs, will be properly handled here. | 160 // extension using the (new) speech JS APIs, will be properly handled here. |
161 // TODO(primiano) turn this line into a DCHECK once speech input extension | 161 // TODO(primiano) turn this line into a DCHECK once speech input extension |
162 // API is deprecated. | 162 // API is deprecated. |
163 if (!web_contents) | 163 if (!web_contents) |
164 return; | 164 return; |
165 | 165 |
166 // Avoid multiple registrations on |registrar_| for the same |web_contents|. | 166 // Avoid multiple registrations on |registrar_| for the same |web_contents|. |
167 if (registered_web_contents_.find(web_contents) != | 167 if (FindWebContents(web_contents) != registered_web_contents_.end()) { |
168 registered_web_contents_.end()) { | |
169 return; | 168 return; |
170 } | 169 } |
171 registered_web_contents_.insert(web_contents); | 170 registered_web_contents_.push_back( |
| 171 WebContentsInfo(web_contents, render_process_id, render_view_id)); |
172 | 172 |
173 // Lazy initialize the registrar. | 173 // Lazy initialize the registrar. |
174 if (!registrar_.get()) | 174 if (!registrar_.get()) |
175 registrar_.reset(new content::NotificationRegistrar()); | 175 registrar_.reset(new content::NotificationRegistrar()); |
176 | 176 |
177 registrar_->Add(this, | 177 registrar_->Add(this, |
| 178 content::NOTIFICATION_WEB_CONTENTS_SWAPPED, |
| 179 content::Source<WebContents>(web_contents)); |
| 180 registrar_->Add(this, |
178 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 181 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
179 content::Source<WebContents>(web_contents)); | 182 content::Source<WebContents>(web_contents)); |
180 } | 183 } |
181 | 184 |
182 // content::NotificationObserver implementation. | 185 // content::NotificationObserver implementation. |
183 virtual void Observe(int type, | 186 virtual void Observe(int type, |
184 const content::NotificationSource& source, | 187 const content::NotificationSource& source, |
185 const content::NotificationDetails& details) OVERRIDE { | 188 const content::NotificationDetails& details) OVERRIDE { |
186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
187 DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, type); | 190 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED || |
| 191 type == content::NOTIFICATION_WEB_CONTENTS_SWAPPED); |
188 | 192 |
189 WebContents* web_contents = content::Source<WebContents>(source).ptr(); | 193 WebContents* web_contents = content::Source<WebContents>(source).ptr(); |
190 int render_process_id = web_contents->GetRenderProcessHost()->GetID(); | 194 std::vector<WebContentsInfo>::iterator iter = FindWebContents(web_contents); |
191 int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID(); | 195 DCHECK(iter != registered_web_contents_.end()); |
| 196 int render_process_id = iter->render_process_id; |
| 197 int render_view_id = iter->render_view_id; |
| 198 registered_web_contents_.erase(iter); |
192 | 199 |
193 registrar_->Remove(this, | 200 registrar_->Remove(this, |
| 201 content::NOTIFICATION_WEB_CONTENTS_SWAPPED, |
| 202 content::Source<WebContents>(web_contents)); |
| 203 registrar_->Remove(this, |
194 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 204 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
195 content::Source<WebContents>(web_contents)); | 205 content::Source<WebContents>(web_contents)); |
196 registered_web_contents_.erase(web_contents); | |
197 | 206 |
198 BrowserThread::PostTask(callback_thread_, FROM_HERE, base::Bind( | 207 BrowserThread::PostTask(callback_thread_, FROM_HERE, base::Bind( |
199 tab_closed_callback_, render_process_id, render_view_id)); | 208 tab_closed_callback_, render_process_id, render_view_id)); |
200 } | 209 } |
201 | 210 |
202 private: | 211 private: |
| 212 struct WebContentsInfo { |
| 213 WebContentsInfo(content::WebContents* web_contents, |
| 214 int render_process_id, |
| 215 int render_view_id) |
| 216 : web_contents(web_contents), |
| 217 render_process_id(render_process_id), |
| 218 render_view_id(render_view_id) {} |
| 219 |
| 220 ~WebContentsInfo() {} |
| 221 |
| 222 content::WebContents* web_contents; |
| 223 int render_process_id; |
| 224 int render_view_id; |
| 225 }; |
| 226 |
203 friend class base::RefCountedThreadSafe<TabWatcher>; | 227 friend class base::RefCountedThreadSafe<TabWatcher>; |
204 | 228 |
205 virtual ~TabWatcher() { | 229 virtual ~TabWatcher() { |
206 // Must be destroyed on the UI thread due to |registrar_| non thread-safety. | 230 // Must be destroyed on the UI thread due to |registrar_| non thread-safety. |
207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
208 } | 232 } |
209 | 233 |
| 234 // Helper function to find the iterator in |registered_web_contents_| which |
| 235 // contains |web_contents|. |
| 236 std::vector<WebContentsInfo>::iterator FindWebContents( |
| 237 content::WebContents* web_contents) { |
| 238 for (std::vector<WebContentsInfo>::iterator i( |
| 239 registered_web_contents_.begin()); |
| 240 i != registered_web_contents_.end(); ++i) { |
| 241 if (i->web_contents == web_contents) |
| 242 return i; |
| 243 } |
| 244 |
| 245 return registered_web_contents_.end(); |
| 246 } |
| 247 |
210 // Lazy-initialized and used on the UI thread to handle web contents | 248 // Lazy-initialized and used on the UI thread to handle web contents |
211 // notifications (tab closing). | 249 // notifications (tab closing). |
212 scoped_ptr<content::NotificationRegistrar> registrar_; | 250 scoped_ptr<content::NotificationRegistrar> registrar_; |
213 | 251 |
214 // Keeps track of which WebContent(s) have been registered, in order to avoid | 252 // Keeps track of which WebContent(s) have been registered, in order to avoid |
215 // double registrations on |registrar_| | 253 // double registrations on |registrar_| and to pass the correct render |
216 std::set<content::WebContents*> registered_web_contents_; | 254 // process id and render view id to |tab_closed_callback_| after the process |
| 255 // has gone away. |
| 256 std::vector<WebContentsInfo> registered_web_contents_; |
217 | 257 |
218 // Callback used to notify, on the thread specified by |callback_thread_| the | 258 // Callback used to notify, on the thread specified by |callback_thread_| the |
219 // closure of a registered tab. | 259 // closure of a registered tab. |
220 TabClosedCallback tab_closed_callback_; | 260 TabClosedCallback tab_closed_callback_; |
221 content::BrowserThread::ID callback_thread_; | 261 content::BrowserThread::ID callback_thread_; |
222 | 262 |
223 DISALLOW_COPY_AND_ASSIGN(TabWatcher); | 263 DISALLOW_COPY_AND_ASSIGN(TabWatcher); |
224 }; | 264 }; |
225 | 265 |
226 ChromeSpeechRecognitionManagerDelegate | 266 ChromeSpeechRecognitionManagerDelegate |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 } | 563 } |
524 | 564 |
525 SpeechRecognitionBubbleController* | 565 SpeechRecognitionBubbleController* |
526 ChromeSpeechRecognitionManagerDelegate::GetBubbleController() { | 566 ChromeSpeechRecognitionManagerDelegate::GetBubbleController() { |
527 if (!bubble_controller_.get()) | 567 if (!bubble_controller_.get()) |
528 bubble_controller_ = new SpeechRecognitionBubbleController(this); | 568 bubble_controller_ = new SpeechRecognitionBubbleController(this); |
529 return bubble_controller_.get(); | 569 return bubble_controller_.get(); |
530 } | 570 } |
531 | 571 |
532 } // namespace speech | 572 } // namespace speech |
OLD | NEW |