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