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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 // Sessions initiated by speech input extension APIs will end up in a NULL | 159 // Sessions initiated by speech input extension APIs will end up in a NULL |
160 // WebContent here, but they are properly managed by the | 160 // WebContent here, but they are properly managed by the |
161 // chrome::SpeechInputExtensionManager. However, sessions initiated within a | 161 // chrome::SpeechInputExtensionManager. However, sessions initiated within a |
162 // extension using the (new) speech JS APIs, will be properly handled here. | 162 // extension using the (new) speech JS APIs, will be properly handled here. |
163 // TODO(primiano) turn this line into a DCHECK once speech input extension | 163 // TODO(primiano) turn this line into a DCHECK once speech input extension |
164 // API is deprecated. | 164 // API is deprecated. |
165 if (!web_contents) | 165 if (!web_contents) |
166 return; | 166 return; |
167 | 167 |
168 // Avoid multiple registrations for the same |web_contents|. | 168 // Avoid multiple registrations for the same |web_contents|. |
169 if (FindWebContents(web_contents) != registered_web_contents_.end()) { | 169 if (FindWebContents(web_contents) != registered_web_contents_.end()) |
170 return; | 170 return; |
171 } | 171 |
172 registered_web_contents_.push_back(new WebContentsTracker( | 172 registered_web_contents_.push_back(new WebContentsTracker( |
173 web_contents, base::Bind(&TabWatcher::OnTabClosed, | 173 web_contents, base::Bind(&TabWatcher::OnTabClosed, |
174 // |this| outlives WebContentsTracker. | 174 // |this| outlives WebContentsTracker. |
175 base::Unretained(this), web_contents), | 175 base::Unretained(this), web_contents), |
176 render_process_id, render_view_id)); | 176 render_process_id, render_view_id)); |
177 } | 177 } |
178 | 178 |
179 void OnTabClosed(content::WebContents* web_contents) { | 179 void OnTabClosed(content::WebContents* web_contents) { |
180 ScopedVector<WebContentsTracker>::iterator iter = | 180 ScopedVector<WebContentsTracker>::iterator iter = |
181 FindWebContents(web_contents); | 181 FindWebContents(web_contents); |
182 DCHECK(iter != registered_web_contents_.end()); | 182 DCHECK(iter != registered_web_contents_.end()); |
183 int render_process_id = (*iter)->render_process_id(); | 183 int render_process_id = (*iter)->render_process_id(); |
184 int render_view_id = (*iter)->render_view_id(); | 184 int render_view_id = (*iter)->render_view_id(); |
185 registered_web_contents_.erase(iter); | 185 registered_web_contents_.erase(iter); |
186 | 186 |
187 tab_closed_callback_.Run(render_process_id, render_view_id); | 187 tab_closed_callback_.Run(render_process_id, render_view_id); |
188 } | 188 } |
189 | 189 |
190 private: | 190 private: |
191 class WebContentsTracker : public content::WebContentsObserver { | 191 class WebContentsTracker : public content::WebContentsObserver { |
192 public: | 192 public: |
193 WebContentsTracker(content::WebContents* web_contents, | 193 WebContentsTracker(content::WebContents* web_contents, |
194 const base::Closure& finished_callback, | 194 const base::Closure& finished_callback, |
195 int render_process_id, | 195 int render_process_id, |
196 int render_view_id) | 196 int render_view_id) |
197 : content::WebContentsObserver(web_contents), | 197 : content::WebContentsObserver(web_contents), |
| 198 web_contents_(web_contents), |
198 finished_callback_(finished_callback), | 199 finished_callback_(finished_callback), |
199 render_process_id_(render_process_id), | 200 render_process_id_(render_process_id), |
200 render_view_id_(render_view_id) {} | 201 render_view_id_(render_view_id) {} |
201 | 202 |
202 ~WebContentsTracker() override {} | 203 ~WebContentsTracker() override {} |
203 | 204 |
204 int render_process_id() const { return render_process_id_; } | 205 int render_process_id() const { return render_process_id_; } |
205 int render_view_id() const { return render_view_id_; } | 206 int render_view_id() const { return render_view_id_; } |
| 207 const content::WebContents* GetWebContents() const { return web_contents_; } |
206 | 208 |
207 private: | 209 private: |
208 // content::WebContentsObserver overrides. | 210 // content::WebContentsObserver overrides. |
209 void WebContentsDestroyed() override { | 211 void WebContentsDestroyed() override { |
210 Observe(nullptr); | 212 Observe(nullptr); |
211 finished_callback_.Run(); | 213 finished_callback_.Run(); |
212 // NOTE: We are deleted now. | 214 // NOTE: We are deleted now. |
213 } | 215 } |
214 void RenderViewHostChanged(content::RenderViewHost* old_host, | 216 void RenderViewHostChanged(content::RenderViewHost* old_host, |
215 content::RenderViewHost* new_host) override { | 217 content::RenderViewHost* new_host) override { |
216 Observe(nullptr); | 218 Observe(nullptr); |
217 finished_callback_.Run(); | 219 finished_callback_.Run(); |
218 // NOTE: We are deleted now. | 220 // NOTE: We are deleted now. |
219 } | 221 } |
220 | 222 |
| 223 // Raw pointer to our WebContents. |
| 224 // |
| 225 // Although we are a WebContentsObserver, calling |
| 226 // WebContents::web_contents() would return NULL once we unregister |
| 227 // ourselves in WebContentsDestroyed() or RenderViewHostChanged(). So we |
| 228 // store a reference to perform cleanup. |
| 229 const content::WebContents* const web_contents_; |
221 const base::Closure finished_callback_; | 230 const base::Closure finished_callback_; |
222 const int render_process_id_; | 231 const int render_process_id_; |
223 const int render_view_id_; | 232 const int render_view_id_; |
224 }; | 233 }; |
225 | 234 |
226 friend class base::RefCountedThreadSafe<TabWatcher>; | 235 friend class base::RefCountedThreadSafe<TabWatcher>; |
227 | 236 |
228 ~TabWatcher() { | 237 ~TabWatcher() { |
229 // Must be destroyed on the UI thread due to |registrar_| non thread-safety. | 238 // Must be destroyed on the UI thread due to |registrar_| non thread-safety. |
230 // TODO(lazyboy): Do we still need this? | 239 // TODO(lazyboy): Do we still need this? |
231 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 240 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
232 } | 241 } |
233 | 242 |
234 // Helper function to find the iterator in |registered_web_contents_| which | 243 // Helper function to find the iterator in |registered_web_contents_| which |
235 // contains |web_contents|. | 244 // contains |web_contents|. |
236 ScopedVector<WebContentsTracker>::iterator FindWebContents( | 245 ScopedVector<WebContentsTracker>::iterator FindWebContents( |
237 content::WebContents* web_contents) { | 246 content::WebContents* web_contents) { |
238 for (ScopedVector<WebContentsTracker>::iterator i( | 247 for (ScopedVector<WebContentsTracker>::iterator i( |
239 registered_web_contents_.begin()); | 248 registered_web_contents_.begin()); |
240 i != registered_web_contents_.end(); ++i) { | 249 i != registered_web_contents_.end(); ++i) { |
241 if ((*i)->web_contents() == web_contents) | 250 if ((*i)->GetWebContents() == web_contents) |
242 return i; | 251 return i; |
243 } | 252 } |
244 | 253 |
245 return registered_web_contents_.end(); | 254 return registered_web_contents_.end(); |
246 } | 255 } |
247 | 256 |
248 // Keeps track of which WebContent(s) have been registered, in order to avoid | 257 // Keeps track of which WebContent(s) have been registered, in order to avoid |
249 // double registrations on WebContentsObserver and to pass the correct render | 258 // double registrations on WebContentsObserver and to pass the correct render |
250 // process id and render view id to |tab_closed_callback_| after the process | 259 // process id and render view id to |tab_closed_callback_| after the process |
251 // has gone away. | 260 // has gone away. |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 // Otherwise this should be a regular tab contents. | 435 // Otherwise this should be a regular tab contents. |
427 allowed = true; | 436 allowed = true; |
428 check_permission = true; | 437 check_permission = true; |
429 #endif | 438 #endif |
430 | 439 |
431 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 440 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
432 base::Bind(callback, check_permission, allowed)); | 441 base::Bind(callback, check_permission, allowed)); |
433 } | 442 } |
434 | 443 |
435 } // namespace speech | 444 } // namespace speech |
OLD | NEW |