OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/guest_view/web_view/web_view_permission_helper.h" | |
6 | |
7 #include "chrome/browser/content_settings/tab_specific_content_settings.h" | |
8 #include "chrome/browser/geolocation/geolocation_permission_context.h" | |
9 #include "chrome/browser/geolocation/geolocation_permission_context_factory.h" | |
10 #include "chrome/browser/guest_view/web_view/web_view_constants.h" | |
11 #include "chrome/browser/guest_view/web_view/web_view_guest.h" | |
12 #include "chrome/browser/guest_view/web_view/web_view_permission_types.h" | |
13 #include "chrome/browser/plugins/chrome_plugin_service_filter.h" | |
14 #include "chrome/browser/profiles/profile.h" | |
15 #include "chrome/common/render_messages.h" | |
16 #include "content/public/browser/render_process_host.h" | |
17 #include "content/public/browser/render_view_host.h" | |
18 #include "content/public/browser/user_metrics.h" | |
19 | |
20 using content::BrowserPluginGuestDelegate; | |
21 using content::RenderViewHost; | |
22 | |
23 namespace { | |
24 static std::string PermissionTypeToString(WebViewPermissionType type) { | |
25 switch (type) { | |
26 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: | |
27 return webview::kPermissionTypeDownload; | |
28 case WEB_VIEW_PERMISSION_TYPE_FILESYSTEM: | |
29 return webview::kPermissionTypeFileSystem; | |
30 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION: | |
31 return webview::kPermissionTypeGeolocation; | |
32 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: | |
33 return webview::kPermissionTypeDialog; | |
34 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN: | |
35 return webview::kPermissionTypeLoadPlugin; | |
36 case WEB_VIEW_PERMISSION_TYPE_MEDIA: | |
37 return webview::kPermissionTypeMedia; | |
38 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: | |
39 return webview::kPermissionTypeNewWindow; | |
40 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: | |
41 return webview::kPermissionTypePointerLock; | |
42 default: | |
43 NOTREACHED(); | |
44 return std::string(); | |
45 } | |
46 } | |
47 | |
48 // static | |
49 void RecordUserInitiatedUMA( | |
50 const WebViewPermissionHelper::PermissionResponseInfo& info, | |
51 bool allow) { | |
52 if (allow) { | |
53 // Note that |allow| == true means the embedder explicitly allowed the | |
54 // request. For some requests they might still fail. An example of such | |
55 // scenario would be: an embedder allows geolocation request but doesn't | |
56 // have geolocation access on its own. | |
57 switch (info.permission_type) { | |
58 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: | |
59 content::RecordAction( | |
60 UserMetricsAction("WebView.PermissionAllow.Download")); | |
61 break; | |
62 case WEB_VIEW_PERMISSION_TYPE_FILESYSTEM: | |
63 content::RecordAction( | |
64 UserMetricsAction("WebView.PermissionAllow.FileSystem")); | |
65 break; | |
66 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION: | |
67 content::RecordAction( | |
68 UserMetricsAction("WebView.PermissionAllow.Geolocation")); | |
69 break; | |
70 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: | |
71 content::RecordAction( | |
72 UserMetricsAction("WebView.PermissionAllow.JSDialog")); | |
73 break; | |
74 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN: | |
75 content::RecordAction( | |
76 UserMetricsAction("WebView.Guest.PermissionAllow.PluginLoad")); | |
77 case WEB_VIEW_PERMISSION_TYPE_MEDIA: | |
78 content::RecordAction( | |
79 UserMetricsAction("WebView.PermissionAllow.Media")); | |
80 break; | |
81 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: | |
82 content::RecordAction( | |
83 UserMetricsAction("BrowserPlugin.PermissionAllow.NewWindow")); | |
84 break; | |
85 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: | |
86 content::RecordAction( | |
87 UserMetricsAction("WebView.PermissionAllow.PointerLock")); | |
88 break; | |
89 default: | |
90 break; | |
91 } | |
92 } else { | |
93 switch (info.permission_type) { | |
94 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: | |
95 content::RecordAction( | |
96 UserMetricsAction("WebView.PermissionDeny.Download")); | |
97 break; | |
98 case WEB_VIEW_PERMISSION_TYPE_FILESYSTEM: | |
99 content::RecordAction( | |
100 UserMetricsAction("WebView.PermissionDeny.FileSystem")); | |
101 break; | |
102 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION: | |
103 content::RecordAction( | |
104 UserMetricsAction("WebView.PermissionDeny.Geolocation")); | |
105 break; | |
106 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: | |
107 content::RecordAction( | |
108 UserMetricsAction("WebView.PermissionDeny.JSDialog")); | |
109 break; | |
110 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN: | |
111 content::RecordAction( | |
112 UserMetricsAction("WebView.Guest.PermissionDeny.PluginLoad")); | |
113 break; | |
114 case WEB_VIEW_PERMISSION_TYPE_MEDIA: | |
115 content::RecordAction( | |
116 UserMetricsAction("WebView.PermissionDeny.Media")); | |
117 break; | |
118 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: | |
119 content::RecordAction( | |
120 UserMetricsAction("BrowserPlugin.PermissionDeny.NewWindow")); | |
121 break; | |
122 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: | |
123 content::RecordAction( | |
124 UserMetricsAction("WebView.PermissionDeny.PointerLock")); | |
125 break; | |
126 default: | |
127 break; | |
128 } | |
129 } | |
130 } | |
131 | |
132 } // namespace | |
133 | |
134 WebViewPermissionHelper::WebViewPermissionHelper(WebViewGuest* web_view_guest) | |
135 : content::WebContentsObserver(web_view_guest->guest_web_contents()), | |
136 weak_factory_(this), | |
137 next_permission_request_id_(0), | |
138 web_view_guest_(web_view_guest) { | |
139 } | |
140 | |
141 WebViewPermissionHelper::~WebViewPermissionHelper() { | |
142 } | |
143 | |
144 // static | |
145 WebViewPermissionHelper* WebViewPermissionHelper::FromFrameID( | |
146 int render_process_id, | |
147 int render_frame_id) { | |
148 WebViewGuest* web_view_guest = WebViewGuest::FromFrameID( | |
149 render_process_id, render_frame_id); | |
150 if (!web_view_guest) { | |
151 return NULL; | |
152 } | |
153 return web_view_guest->GetWebViewPermissionHelper(); | |
154 } | |
155 | |
156 // static | |
157 WebViewPermissionHelper* WebViewPermissionHelper::FromWebContents( | |
158 content::WebContents* web_contents) { | |
159 WebViewGuest* web_view_guest = WebViewGuest::FromWebContents(web_contents); | |
160 if (!web_view_guest) | |
161 return NULL; | |
162 return web_view_guest->GetWebViewPermissionHelper(); | |
Fady Samuel
2014/06/27 18:46:07
Remove this public accessor and make WebviewPermis
Xi Han
2014/07/03 18:55:58
This is a good idea, but I find out that a public
| |
163 } | |
164 | |
165 #if defined(ENABLE_PLUGINS) | |
166 bool WebViewPermissionHelper::OnMessageReceived( | |
167 const IPC::Message& message, | |
168 content::RenderFrameHost* render_frame_host) { | |
169 IPC_BEGIN_MESSAGE_MAP(WebViewPermissionHelper, message) | |
170 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedOutdatedPlugin, | |
171 OnBlockedOutdatedPlugin) | |
172 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedUnauthorizedPlugin, | |
173 OnBlockedUnauthorizedPlugin) | |
174 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_NPAPINotSupported, | |
175 OnNPAPINotSupported) | |
176 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
177 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FindMissingPlugin, | |
178 OnFindMissingPlugin) | |
179 #endif | |
180 IPC_MESSAGE_UNHANDLED(return false) | |
181 IPC_END_MESSAGE_MAP() | |
182 | |
183 return true; | |
184 } | |
185 | |
186 bool WebViewPermissionHelper::OnMessageReceived(const IPC::Message& message) { | |
187 IPC_BEGIN_MESSAGE_MAP(WebViewPermissionHelper, message) | |
188 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CouldNotLoadPlugin, | |
189 OnCouldNotLoadPlugin) | |
190 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_OpenAboutPlugins, | |
191 OnOpenAboutPlugins) | |
192 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
193 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RemovePluginPlaceholderHost, | |
194 OnRemovePluginPlaceholderHost) | |
195 #endif | |
196 IPC_MESSAGE_UNHANDLED(return false) | |
197 IPC_END_MESSAGE_MAP() | |
198 | |
199 return true; | |
200 } | |
201 | |
202 void WebViewPermissionHelper::OnBlockedUnauthorizedPlugin( | |
203 const base::string16& name, | |
204 const std::string& identifier) { | |
205 const char kPluginName[] = "name"; | |
206 const char kPluginIdentifier[] = "identifier"; | |
207 | |
208 base::DictionaryValue info; | |
209 info.SetString(std::string(kPluginName), name); | |
210 info.SetString(std::string(kPluginIdentifier), identifier); | |
211 RequestPermission( | |
212 WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN, | |
213 info, | |
214 base::Bind(&WebViewPermissionHelper::OnPermissionResponse, | |
215 weak_factory_.GetWeakPtr(), | |
216 identifier), | |
217 true /* allowed_by_default */); | |
218 content::RecordAction( | |
219 base::UserMetricsAction("WebView.Guest.PluginLoadRequest")); | |
220 } | |
221 | |
222 void WebViewPermissionHelper::OnCouldNotLoadPlugin( | |
223 const base::FilePath& plugin_path) { | |
224 } | |
225 | |
226 void WebViewPermissionHelper::OnBlockedOutdatedPlugin( | |
227 int placeholder_id, | |
228 const std::string& identifier) { | |
229 } | |
230 | |
231 void WebViewPermissionHelper::OnNPAPINotSupported(const std::string& id) { | |
232 } | |
233 | |
234 void WebViewPermissionHelper::OnOpenAboutPlugins() { | |
235 } | |
236 | |
237 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
238 void WebViewPermissionHelper::OnFindMissingPlugin( | |
239 int placeholder_id, | |
240 const std::string& mime_type) { | |
241 Send(new ChromeViewMsg_DidNotFindMissingPlugin(placeholder_id)); | |
242 } | |
243 | |
244 void WebViewPermissionHelper::OnRemovePluginPlaceholderHost( | |
245 int placeholder_id) { | |
246 } | |
247 #endif // defined(ENABLE_PLUGIN_INSTALLATION) | |
248 | |
249 void WebViewPermissionHelper::OnPermissionResponse( | |
250 const std::string& identifier, | |
251 bool allow, | |
252 const std::string& input) { | |
253 if (allow) { | |
254 ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins( | |
255 web_contents(), true, identifier); | |
256 } | |
257 } | |
258 | |
259 #endif // defined(ENABLE_PLUGINS) | |
260 | |
261 void WebViewPermissionHelper::RequestMediaAccessPermission( | |
262 content::WebContents* source, | |
263 const content::MediaStreamRequest& request, | |
264 const content::MediaResponseCallback& callback) { | |
265 base::DictionaryValue request_info; | |
266 request_info.Set( | |
267 guestview::kUrl, | |
268 base::Value::CreateStringValue(request.security_origin.spec())); | |
269 RequestPermission(WEB_VIEW_PERMISSION_TYPE_MEDIA, | |
270 request_info, | |
271 base::Bind(&WebViewPermissionHelper:: | |
272 OnMediaPermissionResponse, | |
273 base::Unretained(this), | |
274 request, | |
275 callback), | |
276 false /* allowed_by_default */); | |
277 } | |
278 | |
279 void WebViewPermissionHelper::OnMediaPermissionResponse( | |
280 const content::MediaStreamRequest& request, | |
281 const content::MediaResponseCallback& callback, | |
282 bool allow, | |
283 const std::string& user_input) { | |
284 if (!allow || !web_view_guest_->attached()) { | |
285 // Deny the request. | |
286 callback.Run(content::MediaStreamDevices(), | |
287 content::MEDIA_DEVICE_INVALID_STATE, | |
288 scoped_ptr<content::MediaStreamUI>()); | |
289 return; | |
290 } | |
291 if (!web_view_guest_->embedder_web_contents()->GetDelegate()) | |
292 return; | |
293 | |
294 web_view_guest_->embedder_web_contents()->GetDelegate()-> | |
295 RequestMediaAccessPermission(web_view_guest_->embedder_web_contents(), | |
296 request, | |
297 callback); | |
298 } | |
299 | |
300 void WebViewPermissionHelper::CanDownload( | |
301 content::RenderViewHost* render_view_host, | |
302 const GURL& url, | |
303 const std::string& request_method, | |
304 const base::Callback<void(bool)>& callback) { | |
305 base::DictionaryValue request_info; | |
306 request_info.Set( | |
307 guestview::kUrl, | |
308 base::Value::CreateStringValue(url.spec())); | |
309 RequestPermission( | |
310 WEB_VIEW_PERMISSION_TYPE_DOWNLOAD, | |
311 request_info, | |
312 base::Bind(&WebViewPermissionHelper::OnDownloadPermissionResponse, | |
313 base::Unretained(this), | |
314 callback), | |
315 false /* allowed_by_default */); | |
316 } | |
317 | |
318 void WebViewPermissionHelper::OnDownloadPermissionResponse( | |
319 const base::Callback<void(bool)>& callback, | |
320 bool allow, | |
321 const std::string& user_input) { | |
322 callback.Run(allow && web_view_guest_->attached()); | |
323 } | |
324 | |
325 void WebViewPermissionHelper::RequestPointerLockPermission( | |
326 bool user_gesture, | |
327 bool last_unlocked_by_target, | |
328 const base::Callback<void(bool)>& callback) { | |
329 base::DictionaryValue request_info; | |
330 request_info.Set(guestview::kUserGesture, | |
331 base::Value::CreateBooleanValue(user_gesture)); | |
332 request_info.Set(webview::kLastUnlockedBySelf, | |
333 base::Value::CreateBooleanValue(last_unlocked_by_target)); | |
334 request_info.Set(guestview::kUrl, | |
335 base::Value::CreateStringValue( | |
336 web_contents()->GetLastCommittedURL().spec())); | |
337 | |
338 RequestPermission( | |
339 WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK, | |
340 request_info, | |
341 base::Bind( | |
342 &WebViewPermissionHelper::OnPointerLockPermissionResponse, | |
343 base::Unretained(this), | |
344 callback), | |
345 false /* allowed_by_default */); | |
346 } | |
347 | |
348 void WebViewPermissionHelper::OnPointerLockPermissionResponse( | |
349 const base::Callback<void(bool)>& callback, | |
350 bool allow, | |
351 const std::string& user_input) { | |
352 callback.Run(allow && web_view_guest_->attached()); | |
353 } | |
354 | |
355 void WebViewPermissionHelper::RequestGeolocationPermission( | |
356 int bridge_id, | |
357 const GURL& requesting_frame, | |
358 bool user_gesture, | |
359 const base::Callback<void(bool)>& callback) { | |
360 base::DictionaryValue request_info; | |
361 request_info.Set(guestview::kUrl, | |
362 base::Value::CreateStringValue(requesting_frame.spec())); | |
363 request_info.Set(guestview::kUserGesture, | |
364 base::Value::CreateBooleanValue(user_gesture)); | |
365 | |
366 // It is safe to hold an unretained pointer to WebViewPermissionHelper because | |
367 // this callback is called from WebViewPermissionHelper::SetPermission. | |
368 const PermissionResponseCallback permission_callback = | |
369 base::Bind( | |
370 &WebViewPermissionHelper::OnGeolocationPermissionResponse, | |
371 base::Unretained(this), | |
372 bridge_id, | |
373 user_gesture, | |
374 callback); | |
375 int request_id = RequestPermission( | |
376 WEB_VIEW_PERMISSION_TYPE_GEOLOCATION, | |
377 request_info, | |
378 permission_callback, | |
379 false /* allowed_by_default */); | |
380 bridge_id_to_request_id_map_[bridge_id] = request_id; | |
381 } | |
382 | |
383 void WebViewPermissionHelper::OnGeolocationPermissionResponse( | |
384 int bridge_id, | |
385 bool user_gesture, | |
386 const base::Callback<void(bool)>& callback, | |
387 bool allow, | |
388 const std::string& user_input) { | |
389 // The <webview> embedder has allowed the permission. We now need to make sure | |
390 // that the embedder has geolocation permission. | |
391 RemoveBridgeID(bridge_id); | |
392 | |
393 if (!allow || !web_view_guest_->attached()) { | |
394 callback.Run(false); | |
395 return; | |
396 } | |
397 | |
398 Profile* profile = Profile::FromBrowserContext( | |
399 web_view_guest_->browser_context()); | |
400 GeolocationPermissionContextFactory::GetForProfile(profile)-> | |
401 RequestGeolocationPermission( | |
402 web_view_guest_->embedder_web_contents(), | |
403 // The geolocation permission request here is not initiated | |
404 // through WebGeolocationPermissionRequest. We are only interested | |
405 // in the fact whether the embedder/app has geolocation | |
406 // permission. Therefore we use an invalid |bridge_id|. | |
407 -1, | |
408 web_view_guest_->embedder_web_contents()->GetLastCommittedURL(), | |
409 user_gesture, | |
410 callback, | |
411 NULL); | |
412 } | |
413 | |
414 void WebViewPermissionHelper::CancelGeolocationPermissionRequest( | |
415 int bridge_id) { | |
416 int request_id = RemoveBridgeID(bridge_id); | |
417 RequestMap::iterator request_itr = | |
418 pending_permission_requests_.find(request_id); | |
419 | |
420 if (request_itr == pending_permission_requests_.end()) | |
421 return; | |
422 | |
423 pending_permission_requests_.erase(request_itr); | |
424 } | |
425 | |
426 int WebViewPermissionHelper::RemoveBridgeID(int bridge_id) { | |
427 std::map<int, int>::iterator bridge_itr = | |
428 bridge_id_to_request_id_map_.find(bridge_id); | |
429 if (bridge_itr == bridge_id_to_request_id_map_.end()) | |
430 return webview::kInvalidPermissionRequestID; | |
431 | |
432 int request_id = bridge_itr->second; | |
433 bridge_id_to_request_id_map_.erase(bridge_itr); | |
434 return request_id; | |
435 } | |
436 | |
437 void WebViewPermissionHelper::RequestFileSystemPermission( | |
438 const GURL& url, | |
439 bool allowed_by_default, | |
440 const base::Callback<void(bool)>& callback) { | |
441 base::DictionaryValue request_info; | |
442 request_info.Set(guestview::kUrl, base::Value::CreateStringValue(url.spec())); | |
443 RequestPermission( | |
444 WEB_VIEW_PERMISSION_TYPE_FILESYSTEM, | |
445 request_info, | |
446 base::Bind( | |
447 &WebViewPermissionHelper::OnFileSystemPermissionResponse, | |
448 base::Unretained(this), | |
449 callback), | |
450 allowed_by_default); | |
451 } | |
452 | |
453 void WebViewPermissionHelper::OnFileSystemPermissionResponse( | |
454 const base::Callback<void(bool)>& callback, | |
455 bool allow, | |
456 const std::string& user_input) { | |
457 callback.Run(allow && web_view_guest_->attached()); | |
458 } | |
459 | |
460 void WebViewPermissionHelper::FileSystemAccessedAsync(int render_process_id, | |
461 int render_frame_id, | |
462 int request_id, | |
463 const GURL& url, | |
464 bool blocked_by_policy) { | |
465 RequestFileSystemPermission( | |
466 url, | |
467 !blocked_by_policy, | |
468 base::Bind(&WebViewPermissionHelper::FileSystemAccessedAsyncResponse, | |
469 base::Unretained(this), | |
470 render_process_id, | |
471 render_frame_id, | |
472 request_id, | |
473 url)); | |
474 } | |
475 | |
476 void WebViewPermissionHelper::FileSystemAccessedAsyncResponse( | |
477 int render_process_id, | |
478 int render_frame_id, | |
479 int request_id, | |
480 const GURL& url, | |
481 bool allowed) { | |
482 TabSpecificContentSettings::FileSystemAccessed( | |
483 render_process_id, render_frame_id, url, !allowed); | |
484 Send(new ChromeViewMsg_RequestFileSystemAccessAsyncResponse( | |
485 render_frame_id, request_id, allowed)); | |
486 } | |
487 | |
488 void WebViewPermissionHelper::FileSystemAccessedSync(int render_process_id, | |
489 int render_frame_id, | |
490 const GURL& url, | |
491 bool blocked_by_policy, | |
492 IPC::Message* reply_msg) { | |
493 RequestFileSystemPermission( | |
494 url, | |
495 !blocked_by_policy, | |
496 base::Bind(&WebViewPermissionHelper::FileSystemAccessedSyncResponse, | |
497 base::Unretained(this), | |
498 render_process_id, | |
499 render_frame_id, | |
500 url, | |
501 reply_msg)); | |
502 } | |
503 | |
504 void WebViewPermissionHelper::FileSystemAccessedSyncResponse( | |
505 int render_process_id, | |
506 int render_frame_id, | |
507 const GURL& url, | |
508 IPC::Message* reply_msg, | |
509 bool allowed) { | |
510 TabSpecificContentSettings::FileSystemAccessed( | |
511 render_process_id, render_frame_id, url, !allowed); | |
512 ChromeViewHostMsg_RequestFileSystemAccessSync::WriteReplyParams(reply_msg, | |
513 allowed); | |
514 Send(reply_msg); | |
515 } | |
516 | |
517 int WebViewPermissionHelper::RequestPermission( | |
518 WebViewPermissionType permission_type, | |
519 const base::DictionaryValue& request_info, | |
520 const PermissionResponseCallback& callback, | |
521 bool allowed_by_default) { | |
522 // If there are too many pending permission requests then reject this request. | |
523 if (pending_permission_requests_.size() >= | |
524 webview::kMaxOutstandingPermissionRequests) { | |
525 // Let the stack unwind before we deny the permission request so that | |
526 // objects held by the permission request are not destroyed immediately | |
527 // after creation. This is to allow those same objects to be accessed again | |
528 // in the same scope without fear of use after freeing. | |
529 base::MessageLoop::current()->PostTask( | |
530 FROM_HERE, | |
531 base::Bind(&PermissionResponseCallback::Run, | |
532 base::Owned(new PermissionResponseCallback(callback)), | |
533 allowed_by_default, | |
534 std::string())); | |
535 return webview::kInvalidPermissionRequestID; | |
536 } | |
537 | |
538 int request_id = next_permission_request_id_++; | |
539 pending_permission_requests_[request_id] = | |
540 PermissionResponseInfo(callback, permission_type, allowed_by_default); | |
541 scoped_ptr<base::DictionaryValue> args(request_info.DeepCopy()); | |
542 args->SetInteger(webview::kRequestId, request_id); | |
543 switch (permission_type) { | |
544 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: { | |
545 web_view_guest_->DispatchEvent( | |
546 new GuestViewBase::Event(webview::kEventNewWindow, args.Pass())); | |
547 break; | |
548 } | |
549 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: { | |
550 web_view_guest_->DispatchEvent( | |
551 new GuestViewBase::Event(webview::kEventDialog, args.Pass())); | |
552 break; | |
553 } | |
554 default: { | |
555 args->SetString(webview::kPermission, | |
556 PermissionTypeToString(permission_type)); | |
557 web_view_guest_->DispatchEvent(new GuestViewBase::Event( | |
558 webview::kEventPermissionRequest, | |
559 args.Pass())); | |
560 break; | |
561 } | |
562 } | |
563 return request_id; | |
564 } | |
565 | |
566 WebViewPermissionHelper::SetPermissionResult | |
567 WebViewPermissionHelper::SetPermission( | |
568 int request_id, | |
569 PermissionResponseAction action, | |
570 const std::string& user_input) { | |
571 RequestMap::iterator request_itr = | |
572 pending_permission_requests_.find(request_id); | |
573 | |
574 if (request_itr == pending_permission_requests_.end()) | |
575 return SET_PERMISSION_INVALID; | |
576 | |
577 const PermissionResponseInfo& info = request_itr->second; | |
578 bool allow = (action == ALLOW) || | |
579 ((action == DEFAULT) && info.allowed_by_default); | |
580 | |
581 info.callback.Run(allow, user_input); | |
582 | |
583 // Only record user initiated (i.e. non-default) actions. | |
584 if (action != DEFAULT) | |
585 RecordUserInitiatedUMA(info, allow); | |
586 | |
587 pending_permission_requests_.erase(request_itr); | |
588 | |
589 return allow ? SET_PERMISSION_ALLOWED : SET_PERMISSION_DENIED; | |
590 } | |
591 | |
592 WebViewPermissionHelper::PermissionResponseInfo::PermissionResponseInfo() | |
593 : permission_type(WEB_VIEW_PERMISSION_TYPE_UNKNOWN), | |
594 allowed_by_default(false) { | |
595 } | |
596 | |
597 WebViewPermissionHelper::PermissionResponseInfo::PermissionResponseInfo( | |
598 const PermissionResponseCallback& callback, | |
599 WebViewPermissionType permission_type, | |
600 bool allowed_by_default) | |
601 : callback(callback), | |
602 permission_type(permission_type), | |
603 allowed_by_default(allowed_by_default) { | |
604 } | |
605 | |
606 WebViewPermissionHelper::PermissionResponseInfo::~PermissionResponseInfo() { | |
607 } | |
OLD | NEW |