| 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 |