Chromium Code Reviews| 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" |
| 11 #include "base/prefs/pref_service.h" | 11 #include "base/prefs/pref_service.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "base/synchronization/lock.h" | 13 #include "base/synchronization/lock.h" |
| 14 #include "base/threading/thread_restrictions.h" | 14 #include "base/threading/thread_restrictions.h" |
| 15 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
| 16 #include "chrome/browser/profiles/profile_manager.h" | 16 #include "chrome/browser/profiles/profile_manager.h" |
| 17 #include "chrome/browser/tab_contents/tab_util.h" | 17 #include "chrome/browser/tab_contents/tab_util.h" |
| 18 #include "chrome/common/pref_names.h" | 18 #include "chrome/common/pref_names.h" |
| 19 #include "chrome/common/url_constants.h" | 19 #include "chrome/common/url_constants.h" |
| 20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 21 #include "content/public/browser/notification_registrar.h" | 21 #include "content/public/browser/notification_registrar.h" |
| 22 #include "content/public/browser/notification_source.h" | 22 #include "content/public/browser/notification_source.h" |
| 23 #include "content/public/browser/notification_types.h" | 23 #include "content/public/browser/notification_types.h" |
| 24 #include "content/public/browser/render_frame_host.h" | |
| 24 #include "content/public/browser/render_process_host.h" | 25 #include "content/public/browser/render_process_host.h" |
| 25 #include "content/public/browser/render_view_host.h" | 26 #include "content/public/browser/render_view_host.h" |
| 26 #include "content/public/browser/resource_context.h" | 27 #include "content/public/browser/resource_context.h" |
| 27 #include "content/public/browser/speech_recognition_manager.h" | 28 #include "content/public/browser/speech_recognition_manager.h" |
| 28 #include "content/public/browser/speech_recognition_session_config.h" | 29 #include "content/public/browser/speech_recognition_session_config.h" |
| 29 #include "content/public/browser/speech_recognition_session_context.h" | 30 #include "content/public/browser/speech_recognition_session_context.h" |
| 30 #include "content/public/browser/web_contents.h" | 31 #include "content/public/browser/web_contents.h" |
| 31 #include "content/public/common/speech_recognition_error.h" | 32 #include "content/public/common/speech_recognition_error.h" |
| 32 #include "content/public/common/speech_recognition_result.h" | 33 #include "content/public/common/speech_recognition_result.h" |
| 33 #include "net/url_request/url_request_context_getter.h" | 34 #include "net/url_request/url_request_context_getter.h" |
| 34 | 35 |
| 35 #if defined(OS_WIN) | 36 #if defined(OS_WIN) |
| 36 #include "chrome/installer/util/wmi.h" | 37 #include "chrome/installer/util/wmi.h" |
| 37 #endif | 38 #endif |
| 38 | 39 |
| 39 #if defined(ENABLE_EXTENSIONS) | 40 #if defined(ENABLE_EXTENSIONS) |
| 40 #include "chrome/browser/extensions/extension_service.h" | 41 #include "chrome/browser/extensions/extension_service.h" |
| 41 #include "extensions/browser/view_type_utils.h" | 42 #include "extensions/browser/view_type_utils.h" |
| 42 #endif | 43 #endif |
| 43 | 44 |
| 44 using content::BrowserThread; | 45 using content::BrowserThread; |
| 46 using content::RenderFrameHost; | |
| 45 using content::SpeechRecognitionManager; | 47 using content::SpeechRecognitionManager; |
| 46 using content::WebContents; | 48 using content::WebContents; |
| 47 | 49 |
| 48 namespace speech { | 50 namespace speech { |
| 49 | 51 |
| 50 namespace { | 52 namespace { |
| 51 | 53 |
| 52 void TabClosedCallbackOnIOThread(int render_process_id, int render_view_id) { | 54 void AbortSpeechSessionsForFrameOnIO(int render_process_id, |
| 53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 55 int render_frame_id) { |
| 56 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 54 | 57 |
| 55 SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); | 58 SpeechRecognitionManager* manager = SpeechRecognitionManager::GetInstance(); |
| 56 // |manager| becomes NULL if a browser shutdown happens between the post of | 59 // |manager| becomes NULL if a browser shutdown happens between the post of |
| 57 // this task (from the UI thread) and this call (on the IO thread). In this | 60 // this task (from the UI thread) and this call (on the IO thread). In this |
| 58 // case we just return. | 61 // case we just return. |
| 59 if (!manager) | 62 if (!manager) |
| 60 return; | 63 return; |
| 61 | 64 |
| 62 manager->AbortAllSessionsForRenderView(render_process_id, render_view_id); | 65 manager->AbortAllSessionsForRenderFrame(render_process_id, render_frame_id); |
| 66 } | |
| 67 | |
| 68 void AbortSpeechSessionsForFrame(RenderFrameHost* render_frame_host) { | |
| 69 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 70 | |
| 71 BrowserThread::PostTask( | |
| 72 BrowserThread::IO, FROM_HERE, | |
| 73 base::Bind(&AbortSpeechSessionsForFrameOnIO, | |
| 74 render_frame_host->GetProcess()->GetID(), | |
| 75 render_frame_host->GetRoutingID())); | |
| 63 } | 76 } |
| 64 | 77 |
| 65 } // namespace | 78 } // namespace |
| 66 | 79 |
| 67 | 80 |
| 68 // Asynchronously fetches the PC and audio hardware/driver info if | 81 // Asynchronously fetches the PC and audio hardware/driver info if |
| 69 // the user has opted into UMA. This information is sent with speech input | 82 // the user has opted into UMA. This information is sent with speech input |
| 70 // requests to the server for identifying and improving quality issues with | 83 // requests to the server for identifying and improving quality issues with |
| 71 // specific device configurations. | 84 // specific device configurations. |
| 72 class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo | 85 class ChromeSpeechRecognitionManagerDelegate::OptionalRequestInfo |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 | 146 |
| 134 // Simple utility to get notified when a WebContent (a tab or an extension's | 147 // Simple utility to get notified when a WebContent (a tab or an extension's |
| 135 // background page) is closed or crashes. The callback will always be called on | 148 // background page) is closed or crashes. The callback will always be called on |
| 136 // the UI thread. | 149 // the UI thread. |
| 137 // There is no restriction on the constructor, however this class must be | 150 // There is no restriction on the constructor, however this class must be |
| 138 // destroyed on the UI thread, due to the NotificationRegistrar dependency. | 151 // destroyed on the UI thread, due to the NotificationRegistrar dependency. |
| 139 class ChromeSpeechRecognitionManagerDelegate::TabWatcher | 152 class ChromeSpeechRecognitionManagerDelegate::TabWatcher |
| 140 : public base::RefCountedThreadSafe<TabWatcher>, | 153 : public base::RefCountedThreadSafe<TabWatcher>, |
| 141 public content::NotificationObserver { | 154 public content::NotificationObserver { |
| 142 public: | 155 public: |
| 143 typedef base::Callback<void(int render_process_id, int render_view_id)> | 156 typedef base::Callback<void(WebContents* web_contents)> |
| 144 TabClosedCallback; | 157 TabClosedCallback; |
| 145 | 158 |
| 146 explicit TabWatcher(TabClosedCallback tab_closed_callback) | 159 explicit TabWatcher(TabClosedCallback tab_closed_callback) |
| 147 : tab_closed_callback_(tab_closed_callback) { | 160 : tab_closed_callback_(tab_closed_callback) { |
| 148 } | 161 } |
| 149 | 162 |
| 150 // Starts monitoring the WebContents corresponding to the given | 163 // Starts monitoring the WebContents corresponding to the given |
| 151 // |render_process_id|, |render_view_id| pair, invoking |tab_closed_callback_| | 164 // |render_process_id|, |render_frame_id| pair, invoking |
| 152 // if closed/unloaded. | 165 // |tab_closed_callback_| if closed/unloaded. |
| 153 void Watch(int render_process_id, int render_view_id) { | 166 void Watch(int render_process_id, int render_frame_id) { |
| 154 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { | 167 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 155 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | |
| 156 &TabWatcher::Watch, this, render_process_id, render_view_id)); | |
| 157 return; | |
| 158 } | |
| 159 | 168 |
| 160 WebContents* web_contents = tab_util::GetWebContentsByID(render_process_id, | 169 WebContents* web_contents = WebContents::FromRenderFrameHost( |
| 161 render_view_id); | 170 RenderFrameHost::FromID(render_process_id, render_frame_id)); |
| 171 | |
| 162 // Sessions initiated by speech input extension APIs will end up in a NULL | 172 // Sessions initiated by speech input extension APIs will end up in a NULL |
| 163 // WebContent here, but they are properly managed by the | 173 // WebContent here, but they are properly managed by the |
| 164 // chrome::SpeechInputExtensionManager. However, sessions initiated within a | 174 // chrome::SpeechInputExtensionManager. However, sessions initiated within a |
| 165 // extension using the (new) speech JS APIs, will be properly handled here. | 175 // extension using the (new) speech JS APIs, will be properly handled here. |
| 166 // TODO(primiano) turn this line into a DCHECK once speech input extension | 176 // TODO(primiano) turn this line into a DCHECK once speech input extension |
| 167 // API is deprecated. | 177 // API is deprecated. |
| 168 if (!web_contents) | 178 if (!web_contents) |
| 169 return; | 179 return; |
| 170 | 180 |
| 171 // Avoid multiple registrations on |registrar_| for the same |web_contents|. | 181 // Avoid multiple registrations on |registrar_| for the same |web_contents|. |
| 172 if (FindWebContents(web_contents) != registered_web_contents_.end()) { | 182 if (registered_web_contents_.find(web_contents) != |
| 183 registered_web_contents_.end()) { | |
| 173 return; | 184 return; |
| 174 } | 185 } |
| 175 registered_web_contents_.push_back( | 186 registered_web_contents_.insert(web_contents); |
| 176 WebContentsInfo(web_contents, render_process_id, render_view_id)); | |
| 177 | 187 |
| 178 // Lazy initialize the registrar. | 188 // Lazy initialize the registrar. |
| 179 if (!registrar_.get()) | 189 if (!registrar_.get()) |
| 180 registrar_.reset(new content::NotificationRegistrar()); | 190 registrar_.reset(new content::NotificationRegistrar()); |
| 181 | 191 |
| 182 registrar_->Add(this, | 192 registrar_->Add(this, |
| 183 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, | 193 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
| 184 content::Source<WebContents>(web_contents)); | 194 content::Source<WebContents>(web_contents)); |
| 185 registrar_->Add(this, | 195 registrar_->Add(this, |
| 186 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 196 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
| 187 content::Source<WebContents>(web_contents)); | 197 content::Source<WebContents>(web_contents)); |
| 188 } | 198 } |
| 189 | 199 |
| 190 // content::NotificationObserver implementation. | 200 // content::NotificationObserver implementation. |
| 191 void Observe(int type, | 201 void Observe(int type, |
| 192 const content::NotificationSource& source, | 202 const content::NotificationSource& source, |
| 193 const content::NotificationDetails& details) override { | 203 const content::NotificationDetails& details) override { |
| 194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 195 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED || | 205 DCHECK(type == content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED || |
| 196 type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED); | 206 type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED); |
| 197 | 207 |
| 198 WebContents* web_contents = content::Source<WebContents>(source).ptr(); | 208 WebContents* web_contents = content::Source<WebContents>(source).ptr(); |
| 199 std::vector<WebContentsInfo>::iterator iter = FindWebContents(web_contents); | 209 DCHECK(registered_web_contents_.find(web_contents) != |
| 200 DCHECK(iter != registered_web_contents_.end()); | 210 registered_web_contents_.end()); |
| 201 int render_process_id = iter->render_process_id; | 211 registered_web_contents_.erase(web_contents); |
| 202 int render_view_id = iter->render_view_id; | |
| 203 registered_web_contents_.erase(iter); | |
| 204 | 212 |
| 205 registrar_->Remove(this, | 213 registrar_->Remove(this, |
| 206 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, | 214 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
| 207 content::Source<WebContents>(web_contents)); | 215 content::Source<WebContents>(web_contents)); |
| 208 registrar_->Remove(this, | 216 registrar_->Remove(this, |
| 209 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 217 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
| 210 content::Source<WebContents>(web_contents)); | 218 content::Source<WebContents>(web_contents)); |
| 211 | 219 |
| 212 tab_closed_callback_.Run(render_process_id, render_view_id); | 220 tab_closed_callback_.Run(web_contents); |
| 213 } | 221 } |
| 214 | 222 |
| 215 private: | 223 private: |
| 216 struct WebContentsInfo { | |
| 217 WebContentsInfo(content::WebContents* web_contents, | |
| 218 int render_process_id, | |
| 219 int render_view_id) | |
| 220 : web_contents(web_contents), | |
| 221 render_process_id(render_process_id), | |
| 222 render_view_id(render_view_id) {} | |
| 223 | |
| 224 ~WebContentsInfo() {} | |
| 225 | |
| 226 content::WebContents* web_contents; | |
| 227 int render_process_id; | |
| 228 int render_view_id; | |
| 229 }; | |
| 230 | |
| 231 friend class base::RefCountedThreadSafe<TabWatcher>; | 224 friend class base::RefCountedThreadSafe<TabWatcher>; |
| 232 | 225 |
| 233 ~TabWatcher() override { | 226 ~TabWatcher() override { |
| 234 // Must be destroyed on the UI thread due to |registrar_| non thread-safety. | 227 // Must be destroyed on the UI thread due to |registrar_| non thread-safety. |
| 235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 236 } | 229 } |
| 237 | 230 |
| 238 // Helper function to find the iterator in |registered_web_contents_| which | |
| 239 // contains |web_contents|. | |
| 240 std::vector<WebContentsInfo>::iterator FindWebContents( | |
| 241 content::WebContents* web_contents) { | |
| 242 for (std::vector<WebContentsInfo>::iterator i( | |
| 243 registered_web_contents_.begin()); | |
| 244 i != registered_web_contents_.end(); ++i) { | |
| 245 if (i->web_contents == web_contents) | |
| 246 return i; | |
| 247 } | |
| 248 | |
| 249 return registered_web_contents_.end(); | |
| 250 } | |
| 251 | |
| 252 // Lazy-initialized and used on the UI thread to handle web contents | 231 // Lazy-initialized and used on the UI thread to handle web contents |
| 253 // notifications (tab closing). | 232 // notifications (tab closing). |
| 254 scoped_ptr<content::NotificationRegistrar> registrar_; | 233 scoped_ptr<content::NotificationRegistrar> registrar_; |
| 255 | 234 |
| 256 // Keeps track of which WebContent(s) have been registered, in order to avoid | 235 // Keeps track of which WebContent(s) have been registered, in order to avoid |
| 257 // double registrations on |registrar_| and to pass the correct render | 236 // double registrations on |registrar_|. |
| 258 // process id and render view id to |tab_closed_callback_| after the process | 237 std::set<WebContents*> registered_web_contents_; |
| 259 // has gone away. | |
| 260 std::vector<WebContentsInfo> registered_web_contents_; | |
| 261 | 238 |
| 262 // Callback used to notify, on the thread specified by |callback_thread_| the | 239 // Callback used to notify, on the the UI thread the closure of a registered |
| 263 // closure of a registered tab. | 240 // tab. |
| 264 TabClosedCallback tab_closed_callback_; | 241 TabClosedCallback tab_closed_callback_; |
| 265 | 242 |
| 266 DISALLOW_COPY_AND_ASSIGN(TabWatcher); | 243 DISALLOW_COPY_AND_ASSIGN(TabWatcher); |
| 267 }; | 244 }; |
| 268 | 245 |
| 269 ChromeSpeechRecognitionManagerDelegate | 246 ChromeSpeechRecognitionManagerDelegate |
| 270 ::ChromeSpeechRecognitionManagerDelegate() { | 247 ::ChromeSpeechRecognitionManagerDelegate() { |
| 271 } | 248 } |
| 272 | 249 |
| 273 ChromeSpeechRecognitionManagerDelegate | 250 ChromeSpeechRecognitionManagerDelegate |
| 274 ::~ChromeSpeechRecognitionManagerDelegate() { | 251 ::~ChromeSpeechRecognitionManagerDelegate() { |
| 275 } | 252 } |
| 276 | 253 |
| 277 void ChromeSpeechRecognitionManagerDelegate::TabClosedCallback( | 254 void ChromeSpeechRecognitionManagerDelegate::TabClosedCallback( |
| 278 int render_process_id, int render_view_id) { | 255 WebContents* web_contents) { |
| 279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 256 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 280 | 257 |
| 281 // Tell the S.R. Manager (which lives on the IO thread) to abort all the | 258 web_contents->ForEachFrame(base::Bind(&AbortSpeechSessionsForFrame)); |
| 282 // sessions for the given renderer view. | |
| 283 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | |
| 284 &TabClosedCallbackOnIOThread, render_process_id, render_view_id)); | |
| 285 } | 259 } |
| 286 | 260 |
| 287 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart( | 261 void ChromeSpeechRecognitionManagerDelegate::OnRecognitionStart( |
| 288 int session_id) { | 262 int session_id) { |
| 289 const content::SpeechRecognitionSessionContext& context = | 263 const content::SpeechRecognitionSessionContext& context = |
| 290 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); | 264 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); |
| 291 | 265 |
| 292 // Register callback to auto abort session on tab closure. | 266 // Register callback to auto abort session on tab closure. |
| 293 // |tab_watcher_| is lazyly istantiated on the first call. | 267 // |tab_watcher_| is lazyly istantiated on the first call. |
| 294 if (!tab_watcher_.get()) { | 268 if (!tab_watcher_.get()) { |
| 295 tab_watcher_ = new TabWatcher( | 269 tab_watcher_ = new TabWatcher( |
| 296 base::Bind(&ChromeSpeechRecognitionManagerDelegate::TabClosedCallback, | 270 base::Bind(&ChromeSpeechRecognitionManagerDelegate::TabClosedCallback, |
| 297 base::Unretained(this))); | 271 base::Unretained(this))); |
| 298 } | 272 } |
| 299 tab_watcher_->Watch(context.render_process_id, context.render_view_id); | 273 |
| 274 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | |
| 275 base::Bind(&TabWatcher::Watch, | |
| 276 tab_watcher_, | |
| 277 context.render_process_id, | |
| 278 context.render_frame_id)); | |
| 300 } | 279 } |
| 301 | 280 |
| 302 void ChromeSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) { | 281 void ChromeSpeechRecognitionManagerDelegate::OnAudioStart(int session_id) { |
| 303 } | 282 } |
| 304 | 283 |
| 305 void ChromeSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete( | 284 void ChromeSpeechRecognitionManagerDelegate::OnEnvironmentEstimationComplete( |
| 306 int session_id) { | 285 int session_id) { |
| 307 } | 286 } |
| 308 | 287 |
| 309 void ChromeSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) { | 288 void ChromeSpeechRecognitionManagerDelegate::OnSoundStart(int session_id) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 } | 329 } |
| 351 | 330 |
| 352 void ChromeSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed( | 331 void ChromeSpeechRecognitionManagerDelegate::CheckRecognitionIsAllowed( |
| 353 int session_id, | 332 int session_id, |
| 354 base::Callback<void(bool ask_user, bool is_allowed)> callback) { | 333 base::Callback<void(bool ask_user, bool is_allowed)> callback) { |
| 355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 356 | 335 |
| 357 const content::SpeechRecognitionSessionContext& context = | 336 const content::SpeechRecognitionSessionContext& context = |
| 358 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); | 337 SpeechRecognitionManager::GetInstance()->GetSessionContext(session_id); |
| 359 | 338 |
| 360 // Make sure that initiators (extensions/web pages) properly set the | 339 // Check that the context is appropriate, and whether or not we need to |
|
Charlie Reis
2014/12/09 00:52:33
Let's preserve this comment, since it gives the mo
mlamouri (slow - plz ping)
2015/01/19 11:20:23
Done. Moved where the check happens.
| |
| 361 // |render_process_id| field, which is needed later to retrieve the profile. | 340 // request permission from the user. |
| 362 DCHECK_NE(context.render_process_id, 0); | |
| 363 | |
| 364 int render_process_id = context.render_process_id; | |
| 365 int render_view_id = context.render_view_id; | |
| 366 if (context.embedder_render_process_id) { | |
| 367 // If this is a request originated from a guest, we need to re-route the | |
| 368 // permission check through the embedder (app). | |
| 369 render_process_id = context.embedder_render_process_id; | |
| 370 render_view_id = context.embedder_render_view_id; | |
| 371 } | |
| 372 | |
| 373 // Check that the render view type is appropriate, and whether or not we | |
| 374 // need to request permission from the user. | |
| 375 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 341 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 376 base::Bind(&CheckRenderViewType, | 342 base::Bind(&CheckRenderViewType, callback, context)); |
| 377 callback, | |
| 378 render_process_id, | |
| 379 render_view_id)); | |
| 380 } | 343 } |
| 381 | 344 |
| 382 content::SpeechRecognitionEventListener* | 345 content::SpeechRecognitionEventListener* |
| 383 ChromeSpeechRecognitionManagerDelegate::GetEventListener() { | 346 ChromeSpeechRecognitionManagerDelegate::GetEventListener() { |
| 384 return this; | 347 return this; |
| 385 } | 348 } |
| 386 | 349 |
| 387 bool ChromeSpeechRecognitionManagerDelegate::FilterProfanities( | 350 bool ChromeSpeechRecognitionManagerDelegate::FilterProfanities( |
| 388 int render_process_id) { | 351 int render_process_id) { |
| 389 content::RenderProcessHost* rph = | 352 content::RenderProcessHost* rph = |
| 390 content::RenderProcessHost::FromID(render_process_id); | 353 content::RenderProcessHost::FromID(render_process_id); |
| 391 if (!rph) // Guard against race conditions on RPH lifetime. | 354 if (!rph) // Guard against race conditions on RPH lifetime. |
| 392 return true; | 355 return true; |
| 393 | 356 |
| 394 return Profile::FromBrowserContext(rph->GetBrowserContext())->GetPrefs()-> | 357 return Profile::FromBrowserContext(rph->GetBrowserContext())->GetPrefs()-> |
| 395 GetBoolean(prefs::kSpeechRecognitionFilterProfanities); | 358 GetBoolean(prefs::kSpeechRecognitionFilterProfanities); |
| 396 } | 359 } |
| 397 | 360 |
| 398 // static. | 361 // static. |
| 399 void ChromeSpeechRecognitionManagerDelegate::CheckRenderViewType( | 362 void ChromeSpeechRecognitionManagerDelegate::CheckRenderViewType( |
| 400 base::Callback<void(bool ask_user, bool is_allowed)> callback, | 363 base::Callback<void(bool ask_user, bool is_allowed)> callback, |
| 401 int render_process_id, | 364 const content::SpeechRecognitionSessionContext& context) { |
| 402 int render_view_id) { | 365 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 366 DCHECK_NE(context.render_process_id, 0); |
| 404 const content::RenderViewHost* render_view_host = | 367 DCHECK_NE(context.render_frame_id, MSG_ROUTING_NONE); |
| 405 content::RenderViewHost::FromID(render_process_id, render_view_id); | |
| 406 | 368 |
| 407 bool allowed = false; | 369 bool allowed = false; |
| 408 bool check_permission = false; | 370 bool check_permission = false; |
| 409 | 371 |
| 410 if (!render_view_host) { | 372 RenderFrameHost* render_frame_host = RenderFrameHost::FromID( |
| 373 context.render_process_id, context.render_frame_id); | |
| 374 | |
| 375 if (context.embedder_render_process_id) { | |
| 376 // If this is a request originated from a guest, we need to re-route the | |
| 377 // permission check through the embedder (app). | |
| 378 render_frame_host = RenderFrameHost::FromID( | |
| 379 context.embedder_render_process_id, context.embedder_render_frame_id); | |
| 380 } | |
| 381 | |
| 382 if (!render_frame_host) { | |
| 411 // This happens for extensions. Manifest should be checked for permission. | 383 // This happens for extensions. Manifest should be checked for permission. |
| 412 allowed = true; | 384 allowed = true; |
| 413 check_permission = false; | 385 check_permission = false; |
| 414 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 386 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 415 base::Bind(callback, check_permission, allowed)); | 387 base::Bind(callback, check_permission, allowed)); |
| 416 return; | 388 return; |
| 417 } | 389 } |
| 418 | 390 |
| 419 WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host); | 391 WebContents* web_contents = |
| 392 WebContents::FromRenderFrameHost(render_frame_host); | |
| 420 | 393 |
| 421 // chrome://app-list/ uses speech recognition. | 394 // chrome://app-list/ uses speech recognition. |
| 422 if (web_contents->GetCommittedWebUI() && | 395 if (web_contents->GetCommittedWebUI() && |
| 423 web_contents->GetLastCommittedURL().spec() == | 396 web_contents->GetLastCommittedURL().spec() == |
| 424 chrome::kChromeUIAppListStartPageURL) { | 397 chrome::kChromeUIAppListStartPageURL) { |
| 425 allowed = true; | 398 allowed = true; |
| 426 check_permission = false; | 399 check_permission = false; |
| 427 } | 400 } |
| 428 | 401 |
| 429 #if defined(ENABLE_EXTENSIONS) | 402 #if defined(ENABLE_EXTENSIONS) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 443 // Otherwise this should be a regular tab contents. | 416 // Otherwise this should be a regular tab contents. |
| 444 allowed = true; | 417 allowed = true; |
| 445 check_permission = true; | 418 check_permission = true; |
| 446 #endif | 419 #endif |
| 447 | 420 |
| 448 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | 421 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 449 base::Bind(callback, check_permission, allowed)); | 422 base::Bind(callback, check_permission, allowed)); |
| 450 } | 423 } |
| 451 | 424 |
| 452 } // namespace speech | 425 } // namespace speech |
| OLD | NEW |