Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(521)

Side by Side Diff: chrome/browser/guest_view/web_view/web_view_guest.cc

Issue 347113002: Refactor PluginPermissionHelper as WebViewPermissionHelper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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/guest_view/web_view/web_view_guest.h" 5 #include "chrome/browser/guest_view/web_view/web_view_guest.h"
6 6
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/chrome_notification_types.h" 10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
12 #include "chrome/browser/extensions/api/web_request/web_request_api.h" 11 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
13 #include "chrome/browser/extensions/api/webview/webview_api.h" 12 #include "chrome/browser/extensions/api/webview/webview_api.h"
14 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" 13 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
15 #include "chrome/browser/extensions/extension_renderer_state.h" 14 #include "chrome/browser/extensions/extension_renderer_state.h"
16 #include "chrome/browser/extensions/menu_manager.h" 15 #include "chrome/browser/extensions/menu_manager.h"
17 #include "chrome/browser/extensions/script_executor.h" 16 #include "chrome/browser/extensions/script_executor.h"
18 #include "chrome/browser/favicon/favicon_tab_helper.h" 17 #include "chrome/browser/favicon/favicon_tab_helper.h"
19 #include "chrome/browser/geolocation/geolocation_permission_context.h"
20 #include "chrome/browser/geolocation/geolocation_permission_context_factory.h"
21 #include "chrome/browser/guest_view/guest_view_constants.h" 18 #include "chrome/browser/guest_view/guest_view_constants.h"
22 #include "chrome/browser/guest_view/guest_view_manager.h" 19 #include "chrome/browser/guest_view/guest_view_manager.h"
23 #include "chrome/browser/guest_view/web_view/web_view_constants.h" 20 #include "chrome/browser/guest_view/web_view/web_view_constants.h"
21 #include "chrome/browser/guest_view/web_view/web_view_permission_helper.h"
24 #include "chrome/browser/guest_view/web_view/web_view_permission_types.h" 22 #include "chrome/browser/guest_view/web_view/web_view_permission_types.h"
25 #include "chrome/browser/renderer_context_menu/context_menu_delegate.h" 23 #include "chrome/browser/renderer_context_menu/context_menu_delegate.h"
26 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h" 24 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
27 #include "chrome/browser/ui/pdf/pdf_tab_helper.h" 25 #include "chrome/browser/ui/pdf/pdf_tab_helper.h"
28 #include "chrome/common/chrome_version_info.h" 26 #include "chrome/common/chrome_version_info.h"
29 #include "chrome/common/render_messages.h" 27 #include "chrome/common/render_messages.h"
30 #include "content/public/browser/browser_thread.h" 28 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/child_process_security_policy.h" 29 #include "content/public/browser/child_process_security_policy.h"
32 #include "content/public/browser/host_zoom_map.h" 30 #include "content/public/browser/host_zoom_map.h"
33 #include "content/public/browser/native_web_keyboard_event.h" 31 #include "content/public/browser/native_web_keyboard_event.h"
(...skipping 24 matching lines...) Expand all
58 56
59 #if defined(ENABLE_PRINTING) 57 #if defined(ENABLE_PRINTING)
60 #if defined(ENABLE_FULL_PRINTING) 58 #if defined(ENABLE_FULL_PRINTING)
61 #include "chrome/browser/printing/print_preview_message_handler.h" 59 #include "chrome/browser/printing/print_preview_message_handler.h"
62 #include "chrome/browser/printing/print_view_manager.h" 60 #include "chrome/browser/printing/print_view_manager.h"
63 #else 61 #else
64 #include "chrome/browser/printing/print_view_manager_basic.h" 62 #include "chrome/browser/printing/print_view_manager_basic.h"
65 #endif // defined(ENABLE_FULL_PRINTING) 63 #endif // defined(ENABLE_FULL_PRINTING)
66 #endif // defined(ENABLE_PRINTING) 64 #endif // defined(ENABLE_PRINTING)
67 65
68 #if defined(ENABLE_PLUGINS)
69 #include "chrome/browser/guest_view/web_view/plugin_permission_helper.h"
70 #endif
71
72 #if defined(OS_CHROMEOS) 66 #if defined(OS_CHROMEOS)
73 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" 67 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
74 #endif 68 #endif
75 69
76 using base::UserMetricsAction; 70 using base::UserMetricsAction;
77 using content::RenderFrameHost; 71 using content::RenderFrameHost;
78 using content::WebContents; 72 using content::WebContents;
79 73
80 namespace { 74 namespace {
81 75
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 case base::TERMINATION_STATUS_OOM_PROTECTED: 110 case base::TERMINATION_STATUS_OOM_PROTECTED:
117 #endif 111 #endif
118 return "crashed"; 112 return "crashed";
119 case base::TERMINATION_STATUS_MAX_ENUM: 113 case base::TERMINATION_STATUS_MAX_ENUM:
120 break; 114 break;
121 } 115 }
122 NOTREACHED() << "Unknown Termination Status."; 116 NOTREACHED() << "Unknown Termination Status.";
123 return "unknown"; 117 return "unknown";
124 } 118 }
125 119
126 static std::string PermissionTypeToString(WebViewPermissionType type) {
127 switch (type) {
128 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD:
129 return webview::kPermissionTypeDownload;
130 case WEB_VIEW_PERMISSION_TYPE_FILESYSTEM:
131 return webview::kPermissionTypeFileSystem;
132 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
133 return webview::kPermissionTypeGeolocation;
134 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG:
135 return webview::kPermissionTypeDialog;
136 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
137 return webview::kPermissionTypeLoadPlugin;
138 case WEB_VIEW_PERMISSION_TYPE_MEDIA:
139 return webview::kPermissionTypeMedia;
140 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW:
141 return webview::kPermissionTypeNewWindow;
142 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK:
143 return webview::kPermissionTypePointerLock;
144 default:
145 NOTREACHED();
146 return std::string();
147 }
148 }
149
150 std::string GetStoragePartitionIdFromSiteURL(const GURL& site_url) { 120 std::string GetStoragePartitionIdFromSiteURL(const GURL& site_url) {
151 const std::string& partition_id = site_url.query(); 121 const std::string& partition_id = site_url.query();
152 bool persist_storage = site_url.path().find("persist") != std::string::npos; 122 bool persist_storage = site_url.path().find("persist") != std::string::npos;
153 return (persist_storage ? webview::kPersistPrefix : "") + partition_id; 123 return (persist_storage ? webview::kPersistPrefix : "") + partition_id;
154 } 124 }
155 125
156 void RemoveWebViewEventListenersOnIOThread( 126 void RemoveWebViewEventListenersOnIOThread(
157 void* profile, 127 void* profile,
158 const std::string& extension_id, 128 const std::string& extension_id,
159 int embedder_process_id, 129 int embedder_process_id,
160 int view_instance_id) { 130 int view_instance_id) {
161 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 131 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
162 ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners( 132 ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners(
163 profile, 133 profile,
164 extension_id, 134 extension_id,
165 embedder_process_id, 135 embedder_process_id,
166 view_instance_id); 136 view_instance_id);
167 } 137 }
168 138
169 void AttachWebViewHelpers(WebContents* contents) { 139 void AttachWebViewHelpers(WebContents* contents) {
170 FaviconTabHelper::CreateForWebContents(contents); 140 FaviconTabHelper::CreateForWebContents(contents);
171 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( 141 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
172 contents); 142 contents);
173 #if defined(ENABLE_PLUGINS) 143 WebViewPermissionHelper::CreateForWebContents(contents);
Fady Samuel 2014/06/20 22:54:33 Let's not manage this here.
174 PluginPermissionHelper::CreateForWebContents(contents);
175 #endif
176 #if defined(ENABLE_PRINTING) 144 #if defined(ENABLE_PRINTING)
177 #if defined(ENABLE_FULL_PRINTING) 145 #if defined(ENABLE_FULL_PRINTING)
178 printing::PrintViewManager::CreateForWebContents(contents); 146 printing::PrintViewManager::CreateForWebContents(contents);
179 printing::PrintPreviewMessageHandler::CreateForWebContents(contents); 147 printing::PrintPreviewMessageHandler::CreateForWebContents(contents);
180 #else 148 #else
181 printing::PrintViewManagerBasic::CreateForWebContents(contents); 149 printing::PrintViewManagerBasic::CreateForWebContents(contents);
182 #endif // defined(ENABLE_FULL_PRINTING) 150 #endif // defined(ENABLE_FULL_PRINTING)
183 #endif // defined(ENABLE_PRINTING) 151 #endif // defined(ENABLE_PRINTING)
184 PDFTabHelper::CreateForWebContents(contents); 152 PDFTabHelper::CreateForWebContents(contents);
185 } 153 }
186 154
187 } // namespace 155 } // namespace
188 156
189 WebViewGuest::WebViewGuest(int guest_instance_id, 157 WebViewGuest::WebViewGuest(int guest_instance_id,
190 WebContents* guest_web_contents, 158 WebContents* guest_web_contents,
191 const std::string& embedder_extension_id) 159 const std::string& embedder_extension_id)
192 : GuestView<WebViewGuest>(guest_instance_id, 160 : GuestView<WebViewGuest>(guest_instance_id,
193 guest_web_contents, 161 guest_web_contents,
194 embedder_extension_id), 162 embedder_extension_id),
195 script_executor_(new extensions::ScriptExecutor(guest_web_contents, 163 script_executor_(new extensions::ScriptExecutor(guest_web_contents,
196 &script_observers_)), 164 &script_observers_)),
197 pending_context_menu_request_id_(0), 165 pending_context_menu_request_id_(0),
198 next_permission_request_id_(0),
199 is_overriding_user_agent_(false), 166 is_overriding_user_agent_(false),
200 pending_reload_on_attachment_(false), 167 pending_reload_on_attachment_(false),
201 main_frame_id_(0), 168 main_frame_id_(0),
202 chromevox_injected_(false), 169 chromevox_injected_(false),
203 find_helper_(this), 170 find_helper_(this),
204 javascript_dialog_helper_(this) { 171 javascript_dialog_helper_(this) {
205 notification_registrar_.Add( 172 notification_registrar_.Add(
206 this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, 173 this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
207 content::Source<WebContents>(guest_web_contents)); 174 content::Source<WebContents>(guest_web_contents));
208 175
209 notification_registrar_.Add( 176 notification_registrar_.Add(
210 this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, 177 this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT,
211 content::Source<WebContents>(guest_web_contents)); 178 content::Source<WebContents>(guest_web_contents));
212 179
213 #if defined(OS_CHROMEOS) 180 #if defined(OS_CHROMEOS)
214 chromeos::AccessibilityManager* accessibility_manager = 181 chromeos::AccessibilityManager* accessibility_manager =
215 chromeos::AccessibilityManager::Get(); 182 chromeos::AccessibilityManager::Get();
216 CHECK(accessibility_manager); 183 CHECK(accessibility_manager);
217 accessibility_subscription_ = accessibility_manager->RegisterCallback( 184 accessibility_subscription_ = accessibility_manager->RegisterCallback(
218 base::Bind(&WebViewGuest::OnAccessibilityStatusChanged, 185 base::Bind(&WebViewGuest::OnAccessibilityStatusChanged,
219 base::Unretained(this))); 186 base::Unretained(this)));
220 #endif 187 #endif
221 188
222 AttachWebViewHelpers(guest_web_contents); 189 AttachWebViewHelpers(guest_web_contents);
190 web_view_permission_helper_ =
191 WebViewPermissionHelper::FromWebContents(guest_web_contents);
223 } 192 }
224 193
225 // static 194 // static
226 bool WebViewGuest::GetGuestPartitionConfigForSite( 195 bool WebViewGuest::GetGuestPartitionConfigForSite(
227 const GURL& site, 196 const GURL& site,
228 std::string* partition_domain, 197 std::string* partition_domain,
229 std::string* partition_name, 198 std::string* partition_name,
230 bool* in_memory) { 199 bool* in_memory) {
231 if (!site.SchemeIs(content::kGuestScheme)) 200 if (!site.SchemeIs(content::kGuestScheme))
232 return false; 201 return false;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 return; 251 return;
283 } 252 }
284 *persist_storage = true; 253 *persist_storage = true;
285 } else { 254 } else {
286 *storage_partition_id = partition_str; 255 *storage_partition_id = partition_str;
287 *persist_storage = false; 256 *persist_storage = false;
288 } 257 }
289 } 258 }
290 259
291 // static 260 // static
292 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info,
293 bool allow) {
294 if (allow) {
295 // Note that |allow| == true means the embedder explicitly allowed the
296 // request. For some requests they might still fail. An example of such
297 // scenario would be: an embedder allows geolocation request but doesn't
298 // have geolocation access on its own.
299 switch (info.permission_type) {
300 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD:
301 content::RecordAction(
302 UserMetricsAction("WebView.PermissionAllow.Download"));
303 break;
304 case WEB_VIEW_PERMISSION_TYPE_FILESYSTEM:
305 content::RecordAction(
306 UserMetricsAction("WebView.PermissionAllow.FileSystem"));
307 break;
308 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
309 content::RecordAction(
310 UserMetricsAction("WebView.PermissionAllow.Geolocation"));
311 break;
312 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG:
313 content::RecordAction(
314 UserMetricsAction("WebView.PermissionAllow.JSDialog"));
315 break;
316 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
317 content::RecordAction(
318 UserMetricsAction("WebView.Guest.PermissionAllow.PluginLoad"));
319 case WEB_VIEW_PERMISSION_TYPE_MEDIA:
320 content::RecordAction(
321 UserMetricsAction("WebView.PermissionAllow.Media"));
322 break;
323 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW:
324 content::RecordAction(
325 UserMetricsAction("BrowserPlugin.PermissionAllow.NewWindow"));
326 break;
327 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK:
328 content::RecordAction(
329 UserMetricsAction("WebView.PermissionAllow.PointerLock"));
330 break;
331 default:
332 break;
333 }
334 } else {
335 switch (info.permission_type) {
336 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD:
337 content::RecordAction(
338 UserMetricsAction("WebView.PermissionDeny.Download"));
339 break;
340 case WEB_VIEW_PERMISSION_TYPE_FILESYSTEM:
341 content::RecordAction(
342 UserMetricsAction("WebView.PermissionDeny.FileSystem"));
343 break;
344 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
345 content::RecordAction(
346 UserMetricsAction("WebView.PermissionDeny.Geolocation"));
347 break;
348 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG:
349 content::RecordAction(
350 UserMetricsAction("WebView.PermissionDeny.JSDialog"));
351 break;
352 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
353 content::RecordAction(
354 UserMetricsAction("WebView.Guest.PermissionDeny.PluginLoad"));
355 break;
356 case WEB_VIEW_PERMISSION_TYPE_MEDIA:
357 content::RecordAction(
358 UserMetricsAction("WebView.PermissionDeny.Media"));
359 break;
360 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW:
361 content::RecordAction(
362 UserMetricsAction("BrowserPlugin.PermissionDeny.NewWindow"));
363 break;
364 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK:
365 content::RecordAction(
366 UserMetricsAction("WebView.PermissionDeny.PointerLock"));
367 break;
368 default:
369 break;
370 }
371 }
372 }
373
374 // static
375 scoped_ptr<base::ListValue> WebViewGuest::MenuModelToValue( 261 scoped_ptr<base::ListValue> WebViewGuest::MenuModelToValue(
376 const ui::SimpleMenuModel& menu_model) { 262 const ui::SimpleMenuModel& menu_model) {
377 scoped_ptr<base::ListValue> items(new base::ListValue()); 263 scoped_ptr<base::ListValue> items(new base::ListValue());
378 for (int i = 0; i < menu_model.GetItemCount(); ++i) { 264 for (int i = 0; i < menu_model.GetItemCount(); ++i) {
379 base::DictionaryValue* item_value = new base::DictionaryValue(); 265 base::DictionaryValue* item_value = new base::DictionaryValue();
380 // TODO(lazyboy): We need to expose some kind of enum equivalent of 266 // TODO(lazyboy): We need to expose some kind of enum equivalent of
381 // |command_id| instead of plain integers. 267 // |command_id| instead of plain integers.
382 item_value->SetInteger(webview::kMenuItemCommandId, 268 item_value->SetInteger(webview::kMenuItemCommandId,
383 menu_model.GetCommandIdAt(i)); 269 menu_model.GetCommandIdAt(i));
384 item_value->SetString(webview::kMenuItemLabel, menu_model.GetLabelAt(i)); 270 item_value->SetString(webview::kMenuItemLabel, menu_model.GetLabelAt(i));
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
688 guest_web_contents()->GetController().GoToOffset(relative_index); 574 guest_web_contents()->GetController().GoToOffset(relative_index);
689 } 575 }
690 576
691 void WebViewGuest::Reload() { 577 void WebViewGuest::Reload() {
692 // TODO(fsamuel): Don't check for repost because we don't want to show 578 // TODO(fsamuel): Don't check for repost because we don't want to show
693 // Chromium's repost warning. We might want to implement a separate API 579 // Chromium's repost warning. We might want to implement a separate API
694 // for registering a callback if a repost is about to happen. 580 // for registering a callback if a repost is about to happen.
695 guest_web_contents()->GetController().Reload(false); 581 guest_web_contents()->GetController().Reload(false);
696 } 582 }
697 583
698 void WebViewGuest::RequestFileSystemPermission( 584 WebViewPermissionHelper::SetPermissionResult WebViewGuest::SetPermission(
699 const GURL& url, 585 int request_id,
700 bool allowed_by_default, 586 WebViewPermissionHelper::PermissionResponseAction action,
701 const base::Callback<void(bool)>& callback) {
702 base::DictionaryValue request_info;
703 request_info.Set(guestview::kUrl, base::Value::CreateStringValue(url.spec()));
704 RequestPermission(
705 WEB_VIEW_PERMISSION_TYPE_FILESYSTEM,
706 request_info,
707 base::Bind(&WebViewGuest::OnWebViewFileSystemPermissionResponse,
708 base::Unretained(this),
709 callback),
710 allowed_by_default);
711 }
712
713 void WebViewGuest::OnWebViewFileSystemPermissionResponse(
714 const base::Callback<void(bool)>& callback,
715 bool allow,
716 const std::string& user_input) { 587 const std::string& user_input) {
717 callback.Run(allow && attached()); 588 return web_view_permission_helper_->SetPermission(request_id,
718 } 589 action,
719 590 user_input);
720 void WebViewGuest::RequestGeolocationPermission(
721 int bridge_id,
722 const GURL& requesting_frame,
723 bool user_gesture,
724 const base::Callback<void(bool)>& callback) {
725 base::DictionaryValue request_info;
726 request_info.Set(guestview::kUrl,
727 base::Value::CreateStringValue(requesting_frame.spec()));
728 request_info.Set(guestview::kUserGesture,
729 base::Value::CreateBooleanValue(user_gesture));
730
731 // It is safe to hold an unretained pointer to WebViewGuest because this
732 // callback is called from WebViewGuest::SetPermission.
733 const PermissionResponseCallback permission_callback =
734 base::Bind(&WebViewGuest::OnWebViewGeolocationPermissionResponse,
735 base::Unretained(this),
736 bridge_id,
737 user_gesture,
738 callback);
739 int request_id = RequestPermission(
740 WEB_VIEW_PERMISSION_TYPE_GEOLOCATION,
741 request_info,
742 permission_callback,
743 false /* allowed_by_default */);
744 bridge_id_to_request_id_map_[bridge_id] = request_id;
745 }
746
747 void WebViewGuest::OnWebViewGeolocationPermissionResponse(
748 int bridge_id,
749 bool user_gesture,
750 const base::Callback<void(bool)>& callback,
751 bool allow,
752 const std::string& user_input) {
753 // The <webview> embedder has allowed the permission. We now need to make sure
754 // that the embedder has geolocation permission.
755 RemoveBridgeID(bridge_id);
756
757 if (!allow || !attached()) {
758 callback.Run(false);
759 return;
760 }
761
762 Profile* profile = Profile::FromBrowserContext(browser_context());
763 GeolocationPermissionContextFactory::GetForProfile(profile)->
764 RequestGeolocationPermission(
765 embedder_web_contents(),
766 // The geolocation permission request here is not initiated
767 // through WebGeolocationPermissionRequest. We are only interested
768 // in the fact whether the embedder/app has geolocation
769 // permission. Therefore we use an invalid |bridge_id|.
770 -1,
771 embedder_web_contents()->GetLastCommittedURL(),
772 user_gesture,
773 callback,
774 NULL);
775 }
776
777 void WebViewGuest::CancelGeolocationPermissionRequest(int bridge_id) {
778 int request_id = RemoveBridgeID(bridge_id);
779 RequestMap::iterator request_itr =
780 pending_permission_requests_.find(request_id);
781
782 if (request_itr == pending_permission_requests_.end())
783 return;
784
785 pending_permission_requests_.erase(request_itr);
786 }
787
788 void WebViewGuest::OnWebViewMediaPermissionResponse(
789 const content::MediaStreamRequest& request,
790 const content::MediaResponseCallback& callback,
791 bool allow,
792 const std::string& user_input) {
793 if (!allow || !attached()) {
794 // Deny the request.
795 callback.Run(content::MediaStreamDevices(),
796 content::MEDIA_DEVICE_INVALID_STATE,
797 scoped_ptr<content::MediaStreamUI>());
798 return;
799 }
800 if (!embedder_web_contents()->GetDelegate())
801 return;
802
803 embedder_web_contents()->GetDelegate()->
804 RequestMediaAccessPermission(embedder_web_contents(), request, callback);
805 }
806
807 void WebViewGuest::OnWebViewDownloadPermissionResponse(
808 const base::Callback<void(bool)>& callback,
809 bool allow,
810 const std::string& user_input) {
811 callback.Run(allow && attached());
812 }
813
814 void WebViewGuest::OnWebViewPointerLockPermissionResponse(
815 const base::Callback<void(bool)>& callback,
816 bool allow,
817 const std::string& user_input) {
818 callback.Run(allow && attached());
819 }
820
821 WebViewGuest::SetPermissionResult WebViewGuest::SetPermission(
822 int request_id,
823 PermissionResponseAction action,
824 const std::string& user_input) {
825 RequestMap::iterator request_itr =
826 pending_permission_requests_.find(request_id);
827
828 if (request_itr == pending_permission_requests_.end())
829 return SET_PERMISSION_INVALID;
830
831 const PermissionResponseInfo& info = request_itr->second;
832 bool allow = (action == ALLOW) ||
833 ((action == DEFAULT) && info.allowed_by_default);
834
835 info.callback.Run(allow, user_input);
836
837 // Only record user initiated (i.e. non-default) actions.
838 if (action != DEFAULT)
839 RecordUserInitiatedUMA(info, allow);
840
841 pending_permission_requests_.erase(request_itr);
842
843 return allow ? SET_PERMISSION_ALLOWED : SET_PERMISSION_DENIED;
844 } 591 }
845 592
846 void WebViewGuest::SetUserAgentOverride( 593 void WebViewGuest::SetUserAgentOverride(
847 const std::string& user_agent_override) { 594 const std::string& user_agent_override) {
848 is_overriding_user_agent_ = !user_agent_override.empty(); 595 is_overriding_user_agent_ = !user_agent_override.empty();
849 if (is_overriding_user_agent_) { 596 if (is_overriding_user_agent_) {
850 content::RecordAction(UserMetricsAction("WebView.Guest.OverrideUA")); 597 content::RecordAction(UserMetricsAction("WebView.Guest.OverrideUA"));
851 } 598 }
852 guest_web_contents()->SetUserAgentOverride(user_agent_override); 599 guest_web_contents()->SetUserAgentOverride(user_agent_override);
853 } 600 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 callback); 633 callback);
887 return true; 634 return true;
888 } 635 }
889 636
890 // static 637 // static
891 void WebViewGuest::FileSystemAccessedAsync(int render_process_id, 638 void WebViewGuest::FileSystemAccessedAsync(int render_process_id,
892 int render_frame_id, 639 int render_frame_id,
893 int request_id, 640 int request_id,
894 const GURL& url, 641 const GURL& url,
895 bool blocked_by_policy) { 642 bool blocked_by_policy) {
896 WebViewGuest* guest = 643 WebViewPermissionHelper* web_view_permission_helper =
897 WebViewGuest::FromFrameID(render_process_id, render_frame_id); 644 WebViewPermissionHelper::FromFrameID(render_process_id, render_frame_id);
898 DCHECK(guest); 645 DCHECK(web_view_permission_helper);
899 guest->RequestFileSystemPermission( 646 web_view_permission_helper->FileSystemAccessedAsync(render_process_id,
900 url, 647 render_frame_id,
901 !blocked_by_policy, 648 request_id,
902 base::Bind(&WebViewGuest::FileSystemAccessedAsyncResponse, 649 url,
903 render_process_id, 650 blocked_by_policy);
904 render_frame_id,
905 request_id,
906 url));
907 } 651 }
908 652
909 // static 653 // static
910 void WebViewGuest::FileSystemAccessedAsyncResponse(int render_process_id,
911 int render_frame_id,
912 int request_id,
913 const GURL& url,
914 bool allowed) {
915 TabSpecificContentSettings::FileSystemAccessed(
916 render_process_id, render_frame_id, url, !allowed);
917 content::RenderFrameHost* render_frame_host =
918 content::RenderFrameHost::FromID(render_process_id, render_frame_id);
919 if (!render_frame_host)
920 return;
921 render_frame_host->Send(
922 new ChromeViewMsg_RequestFileSystemAccessAsyncResponse(
923 render_frame_id, request_id, allowed));
924 }
925
926 // static
927 void WebViewGuest::FileSystemAccessedSync(int render_process_id, 654 void WebViewGuest::FileSystemAccessedSync(int render_process_id,
928 int render_frame_id, 655 int render_frame_id,
929 const GURL& url, 656 const GURL& url,
930 bool blocked_by_policy, 657 bool blocked_by_policy,
931 IPC::Message* reply_msg) { 658 IPC::Message* reply_msg) {
932 WebViewGuest* guest = 659 WebViewPermissionHelper* web_view_permission_helper =
933 WebViewGuest::FromFrameID(render_process_id, render_frame_id); 660 WebViewPermissionHelper::FromFrameID(render_process_id, render_frame_id);
934 DCHECK(guest); 661 DCHECK(web_view_permission_helper);
935 guest->RequestFileSystemPermission( 662 web_view_permission_helper->FileSystemAccessedSync(render_process_id,
936 url, 663 render_frame_id,
937 !blocked_by_policy, 664 url,
938 base::Bind(&WebViewGuest::FileSystemAccessedSyncResponse, 665 blocked_by_policy,
939 render_process_id, 666 reply_msg);
940 render_frame_id,
941 url,
942 reply_msg));
943 }
944
945 // static
946 void WebViewGuest::FileSystemAccessedSyncResponse(int render_process_id,
947 int render_frame_id,
948 const GURL& url,
949 IPC::Message* reply_msg,
950 bool allowed) {
951 TabSpecificContentSettings::FileSystemAccessed(
952 render_process_id, render_frame_id, url, !allowed);
953 ChromeViewHostMsg_RequestFileSystemAccessSync::WriteReplyParams(reply_msg,
954 allowed);
955 content::RenderFrameHost* render_frame_host =
956 content::RenderFrameHost::FromID(render_process_id, render_frame_id);
957 if (!render_frame_id)
958 return;
959 render_frame_host->Send(reply_msg);
960 } 667 }
961 668
962 WebViewGuest::~WebViewGuest() { 669 WebViewGuest::~WebViewGuest() {
963 } 670 }
964 671
965 void WebViewGuest::DidCommitProvisionalLoadForFrame( 672 void WebViewGuest::DidCommitProvisionalLoadForFrame(
966 int64 frame_id, 673 int64 frame_id,
967 const base::string16& frame_unique_name, 674 const base::string16& frame_unique_name,
968 bool is_main_frame, 675 bool is_main_frame,
969 const GURL& url, 676 const GURL& url,
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 args->SetInteger(webview::kNewHeight, new_size.height()); 853 args->SetInteger(webview::kNewHeight, new_size.height());
1147 args->SetInteger(webview::kNewWidth, new_size.width()); 854 args->SetInteger(webview::kNewWidth, new_size.width());
1148 DispatchEvent( 855 DispatchEvent(
1149 new GuestViewBase::Event(webview::kEventSizeChanged, args.Pass())); 856 new GuestViewBase::Event(webview::kEventSizeChanged, args.Pass()));
1150 } 857 }
1151 858
1152 void WebViewGuest::RequestMediaAccessPermission( 859 void WebViewGuest::RequestMediaAccessPermission(
1153 content::WebContents* source, 860 content::WebContents* source,
1154 const content::MediaStreamRequest& request, 861 const content::MediaStreamRequest& request,
1155 const content::MediaResponseCallback& callback) { 862 const content::MediaResponseCallback& callback) {
1156 base::DictionaryValue request_info; 863 if (!web_view_permission_helper_) {
1157 request_info.Set( 864 return;
1158 guestview::kUrl, 865 }
1159 base::Value::CreateStringValue(request.security_origin.spec())); 866 web_view_permission_helper_->RequestMediaAccessPermission(source,
1160 RequestPermission(WEB_VIEW_PERMISSION_TYPE_MEDIA, 867 request,
1161 request_info, 868 callback);
1162 base::Bind(&WebViewGuest::OnWebViewMediaPermissionResponse,
1163 base::Unretained(this),
1164 request,
1165 callback),
1166 false /* allowed_by_default */);
1167 } 869 }
1168 870
1169 void WebViewGuest::CanDownload( 871 void WebViewGuest::CanDownload(
1170 content::RenderViewHost* render_view_host, 872 content::RenderViewHost* render_view_host,
1171 const GURL& url, 873 const GURL& url,
1172 const std::string& request_method, 874 const std::string& request_method,
1173 const base::Callback<void(bool)>& callback) { 875 const base::Callback<void(bool)>& callback) {
1174 base::DictionaryValue request_info; 876 if (!web_view_permission_helper_) {
1175 request_info.Set( 877 return;
1176 guestview::kUrl, 878 }
1177 base::Value::CreateStringValue(url.spec())); 879 web_view_permission_helper_->CanDownload(render_view_host,
1178 RequestPermission( 880 url,
1179 WEB_VIEW_PERMISSION_TYPE_DOWNLOAD, 881 request_method,
1180 request_info, 882 callback);
1181 base::Bind(&WebViewGuest::OnWebViewDownloadPermissionResponse,
1182 base::Unretained(this),
1183 callback),
1184 false /* allowed_by_default */);
1185 } 883 }
1186 884
1187 void WebViewGuest::RequestPointerLockPermission( 885 void WebViewGuest::RequestPointerLockPermission(
1188 bool user_gesture, 886 bool user_gesture,
1189 bool last_unlocked_by_target, 887 bool last_unlocked_by_target,
1190 const base::Callback<void(bool)>& callback) { 888 const base::Callback<void(bool)>& callback) {
1191 base::DictionaryValue request_info; 889 if (!web_view_permission_helper_) {
1192 request_info.Set(guestview::kUserGesture, 890 return;
1193 base::Value::CreateBooleanValue(user_gesture)); 891 }
1194 request_info.Set(webview::kLastUnlockedBySelf, 892 web_view_permission_helper_->RequestPointerLockPermission(
1195 base::Value::CreateBooleanValue(last_unlocked_by_target)); 893 user_gesture,
1196 request_info.Set(guestview::kUrl, 894 last_unlocked_by_target,
1197 base::Value::CreateStringValue( 895 callback);
1198 guest_web_contents()->GetLastCommittedURL().spec()));
1199
1200 RequestPermission(
1201 WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK,
1202 request_info,
1203 base::Bind(&WebViewGuest::OnWebViewPointerLockPermissionResponse,
1204 base::Unretained(this),
1205 callback),
1206 false /* allowed_by_default */);
1207 } 896 }
1208 897
1209 content::JavaScriptDialogManager* 898 content::JavaScriptDialogManager*
1210 WebViewGuest::GetJavaScriptDialogManager() { 899 WebViewGuest::GetJavaScriptDialogManager() {
1211 return &javascript_dialog_helper_; 900 return &javascript_dialog_helper_;
1212 } 901 }
1213 902
1214 content::ColorChooser* WebViewGuest::OpenColorChooser( 903 content::ColorChooser* WebViewGuest::OpenColorChooser(
1215 WebContents* web_contents, 904 WebContents* web_contents,
1216 SkColor color, 905 SkColor color,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 chromeos::AccessibilityManager* manager = 972 chromeos::AccessibilityManager* manager =
1284 chromeos::AccessibilityManager::Get(); 973 chromeos::AccessibilityManager::Get();
1285 if (manager && manager->IsSpokenFeedbackEnabled()) { 974 if (manager && manager->IsSpokenFeedbackEnabled()) {
1286 manager->InjectChromeVox(render_view_host); 975 manager->InjectChromeVox(render_view_host);
1287 chromevox_injected_ = true; 976 chromevox_injected_ = true;
1288 } 977 }
1289 } 978 }
1290 #endif 979 #endif
1291 } 980 }
1292 981
1293 int WebViewGuest::RemoveBridgeID(int bridge_id) {
1294 std::map<int, int>::iterator bridge_itr =
1295 bridge_id_to_request_id_map_.find(bridge_id);
1296 if (bridge_itr == bridge_id_to_request_id_map_.end())
1297 return webview::kInvalidPermissionRequestID;
1298
1299 int request_id = bridge_itr->second;
1300 bridge_id_to_request_id_map_.erase(bridge_itr);
1301 return request_id;
1302 }
1303
1304 int WebViewGuest::RequestPermission(
1305 WebViewPermissionType permission_type,
1306 const base::DictionaryValue& request_info,
1307 const PermissionResponseCallback& callback,
1308 bool allowed_by_default) {
1309 // If there are too many pending permission requests then reject this request.
1310 if (pending_permission_requests_.size() >=
1311 webview::kMaxOutstandingPermissionRequests) {
1312 // Let the stack unwind before we deny the permission request so that
1313 // objects held by the permission request are not destroyed immediately
1314 // after creation. This is to allow those same objects to be accessed again
1315 // in the same scope without fear of use after freeing.
1316 base::MessageLoop::current()->PostTask(
1317 FROM_HERE,
1318 base::Bind(&PermissionResponseCallback::Run,
1319 base::Owned(new PermissionResponseCallback(callback)),
1320 allowed_by_default,
1321 std::string()));
1322 return webview::kInvalidPermissionRequestID;
1323 }
1324
1325 int request_id = next_permission_request_id_++;
1326 pending_permission_requests_[request_id] =
1327 PermissionResponseInfo(callback, permission_type, allowed_by_default);
1328 scoped_ptr<base::DictionaryValue> args(request_info.DeepCopy());
1329 args->SetInteger(webview::kRequestId, request_id);
1330 switch (permission_type) {
1331 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: {
1332 DispatchEvent(
1333 new GuestViewBase::Event(webview::kEventNewWindow, args.Pass()));
1334 break;
1335 }
1336 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: {
1337 DispatchEvent(
1338 new GuestViewBase::Event(webview::kEventDialog, args.Pass()));
1339 break;
1340 }
1341 default: {
1342 args->SetString(webview::kPermission,
1343 PermissionTypeToString(permission_type));
1344 DispatchEvent(new GuestViewBase::Event(webview::kEventPermissionRequest,
1345 args.Pass()));
1346 break;
1347 }
1348 }
1349 return request_id;
1350 }
1351
1352 bool WebViewGuest::HandleKeyboardShortcuts( 982 bool WebViewGuest::HandleKeyboardShortcuts(
1353 const content::NativeWebKeyboardEvent& event) { 983 const content::NativeWebKeyboardEvent& event) {
1354 if (event.type != blink::WebInputEvent::RawKeyDown) 984 if (event.type != blink::WebInputEvent::RawKeyDown)
1355 return false; 985 return false;
1356 986
1357 // If the user hits the escape key without any modifiers then unlock the 987 // If the user hits the escape key without any modifiers then unlock the
1358 // mouse if necessary. 988 // mouse if necessary.
1359 if ((event.windowsKeyCode == ui::VKEY_ESCAPE) && 989 if ((event.windowsKeyCode == ui::VKEY_ESCAPE) &&
1360 !(event.modifiers & blink::WebInputEvent::InputModifiers)) { 990 !(event.modifiers & blink::WebInputEvent::InputModifiers)) {
1361 return guest_web_contents()->GotResponseToLockMouseRequest(false); 991 return guest_web_contents()->GotResponseToLockMouseRequest(false);
(...skipping 20 matching lines...) Expand all
1382 1012
1383 if (event.windowsKeyCode == ui::VKEY_BROWSER_FORWARD) { 1013 if (event.windowsKeyCode == ui::VKEY_BROWSER_FORWARD) {
1384 Go(1); 1014 Go(1);
1385 return true; 1015 return true;
1386 } 1016 }
1387 #endif 1017 #endif
1388 1018
1389 return false; 1019 return false;
1390 } 1020 }
1391 1021
1392 WebViewGuest::PermissionResponseInfo::PermissionResponseInfo()
1393 : permission_type(WEB_VIEW_PERMISSION_TYPE_UNKNOWN),
1394 allowed_by_default(false) {
1395 }
1396
1397 WebViewGuest::PermissionResponseInfo::PermissionResponseInfo(
1398 const PermissionResponseCallback& callback,
1399 WebViewPermissionType permission_type,
1400 bool allowed_by_default)
1401 : callback(callback),
1402 permission_type(permission_type),
1403 allowed_by_default(allowed_by_default) {
1404 }
1405
1406 WebViewGuest::PermissionResponseInfo::~PermissionResponseInfo() {
1407 }
1408
1409 void WebViewGuest::ShowContextMenu(int request_id, 1022 void WebViewGuest::ShowContextMenu(int request_id,
1410 const MenuItemVector* items) { 1023 const MenuItemVector* items) {
1411 if (!pending_menu_.get()) 1024 if (!pending_menu_.get())
1412 return; 1025 return;
1413 1026
1414 // Make sure this was the correct request. 1027 // Make sure this was the correct request.
1415 if (request_id != pending_context_menu_request_id_) 1028 if (request_id != pending_context_menu_request_id_)
1416 return; 1029 return;
1417 1030
1418 // TODO(lazyboy): Implement. 1031 // TODO(lazyboy): Implement.
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 request_info.Set(webview::kWindowID, 1157 request_info.Set(webview::kWindowID,
1545 base::Value::CreateIntegerValue(guest->guest_instance_id())); 1158 base::Value::CreateIntegerValue(guest->guest_instance_id()));
1546 // We pass in partition info so that window-s created through newwindow 1159 // We pass in partition info so that window-s created through newwindow
1547 // API can use it to set their partition attribute. 1160 // API can use it to set their partition attribute.
1548 request_info.Set(webview::kStoragePartitionId, 1161 request_info.Set(webview::kStoragePartitionId,
1549 base::Value::CreateStringValue(storage_partition_id)); 1162 base::Value::CreateStringValue(storage_partition_id));
1550 request_info.Set(webview::kWindowOpenDisposition, 1163 request_info.Set(webview::kWindowOpenDisposition,
1551 base::Value::CreateStringValue( 1164 base::Value::CreateStringValue(
1552 WindowOpenDispositionToString(disposition))); 1165 WindowOpenDispositionToString(disposition)));
1553 1166
1554 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, 1167 if (!web_view_permission_helper_) {
1555 request_info, 1168 return;
1556 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, 1169 }
1557 base::Unretained(this), 1170 web_view_permission_helper_->
1558 guest->guest_instance_id()), 1171 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW,
1559 false /* allowed_by_default */); 1172 request_info,
1173 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse,
1174 base::Unretained(this),
1175 guest->guest_instance_id()),
1176 false /* allowed_by_default */);
1560 } 1177 }
1561 1178
1562 void WebViewGuest::DestroyUnattachedWindows() { 1179 void WebViewGuest::DestroyUnattachedWindows() {
1563 // Destroy() reaches in and removes the WebViewGuest from its opener's 1180 // Destroy() reaches in and removes the WebViewGuest from its opener's
1564 // pending_new_windows_ set. To avoid mutating the set while iterating, we 1181 // pending_new_windows_ set. To avoid mutating the set while iterating, we
1565 // create a copy of the pending new windows set and iterate over the copy. 1182 // create a copy of the pending new windows set and iterate over the copy.
1566 PendingWindowMap pending_new_windows(pending_new_windows_); 1183 PendingWindowMap pending_new_windows(pending_new_windows_);
1567 // Clean up unattached new windows opened by this guest. 1184 // Clean up unattached new windows opened by this guest.
1568 for (PendingWindowMap::const_iterator it = pending_new_windows.begin(); 1185 for (PendingWindowMap::const_iterator it = pending_new_windows.begin();
1569 it != pending_new_windows.end(); ++it) { 1186 it != pending_new_windows.end(); ++it) {
(...skipping 21 matching lines...) Expand all
1591 bool allow, 1208 bool allow,
1592 const std::string& user_input) { 1209 const std::string& user_input) {
1593 WebViewGuest* guest = 1210 WebViewGuest* guest =
1594 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); 1211 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id);
1595 if (!guest) 1212 if (!guest)
1596 return; 1213 return;
1597 1214
1598 if (!allow) 1215 if (!allow)
1599 guest->Destroy(); 1216 guest->Destroy();
1600 } 1217 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698