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

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

Issue 272573005: <webview>: Move NewWindow API to chrome (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@guestview_manager_rename
Patch Set: Addressed Istiaque's comments Created 6 years, 7 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/debug/stack_trace.h"
7 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
8 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/extensions/api/web_request/web_request_api.h" 12 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
11 #include "chrome/browser/extensions/api/webview/webview_api.h" 13 #include "chrome/browser/extensions/api/webview/webview_api.h"
12 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" 14 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
13 #include "chrome/browser/extensions/extension_renderer_state.h" 15 #include "chrome/browser/extensions/extension_renderer_state.h"
14 #include "chrome/browser/extensions/menu_manager.h" 16 #include "chrome/browser/extensions/menu_manager.h"
15 #include "chrome/browser/extensions/script_executor.h" 17 #include "chrome/browser/extensions/script_executor.h"
16 #include "chrome/browser/favicon/favicon_tab_helper.h" 18 #include "chrome/browser/favicon/favicon_tab_helper.h"
17 #include "chrome/browser/guest_view/guest_view_constants.h" 19 #include "chrome/browser/guest_view/guest_view_constants.h"
20 #include "chrome/browser/guest_view/guest_view_manager.h"
18 #include "chrome/browser/guest_view/web_view/web_view_constants.h" 21 #include "chrome/browser/guest_view/web_view/web_view_constants.h"
19 #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"
20 #include "chrome/browser/renderer_context_menu/context_menu_delegate.h" 23 #include "chrome/browser/renderer_context_menu/context_menu_delegate.h"
21 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h" 24 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
22 #include "chrome/common/chrome_version_info.h" 25 #include "chrome/common/chrome_version_info.h"
23 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/child_process_security_policy.h"
24 #include "content/public/browser/geolocation_permission_context.h" 28 #include "content/public/browser/geolocation_permission_context.h"
25 #include "content/public/browser/native_web_keyboard_event.h" 29 #include "content/public/browser/native_web_keyboard_event.h"
26 #include "content/public/browser/navigation_entry.h" 30 #include "content/public/browser/navigation_entry.h"
27 #include "content/public/browser/notification_details.h" 31 #include "content/public/browser/notification_details.h"
28 #include "content/public/browser/notification_service.h" 32 #include "content/public/browser/notification_service.h"
29 #include "content/public/browser/notification_source.h" 33 #include "content/public/browser/notification_source.h"
30 #include "content/public/browser/notification_types.h" 34 #include "content/public/browser/notification_types.h"
31 #include "content/public/browser/render_process_host.h" 35 #include "content/public/browser/render_process_host.h"
32 #include "content/public/browser/resource_request_details.h" 36 #include "content/public/browser/resource_request_details.h"
33 #include "content/public/browser/site_instance.h" 37 #include "content/public/browser/site_instance.h"
34 #include "content/public/browser/storage_partition.h" 38 #include "content/public/browser/storage_partition.h"
35 #include "content/public/browser/user_metrics.h" 39 #include "content/public/browser/user_metrics.h"
36 #include "content/public/browser/web_contents.h" 40 #include "content/public/browser/web_contents.h"
37 #include "content/public/browser/web_contents_delegate.h" 41 #include "content/public/browser/web_contents_delegate.h"
38 #include "content/public/common/media_stream_request.h" 42 #include "content/public/common/media_stream_request.h"
39 #include "content/public/common/page_zoom.h" 43 #include "content/public/common/page_zoom.h"
40 #include "content/public/common/result_codes.h" 44 #include "content/public/common/result_codes.h"
41 #include "content/public/common/stop_find_action.h" 45 #include "content/public/common/stop_find_action.h"
46 #include "content/public/common/url_constants.h"
42 #include "extensions/common/constants.h" 47 #include "extensions/common/constants.h"
43 #include "net/base/net_errors.h" 48 #include "net/base/net_errors.h"
44 #include "third_party/WebKit/public/web/WebFindOptions.h" 49 #include "third_party/WebKit/public/web/WebFindOptions.h"
45 #include "ui/base/models/simple_menu_model.h" 50 #include "ui/base/models/simple_menu_model.h"
46 51
47 #if defined(ENABLE_PLUGINS) 52 #if defined(ENABLE_PLUGINS)
48 #include "chrome/browser/guest_view/web_view/plugin_permission_helper.h" 53 #include "chrome/browser/guest_view/web_view/plugin_permission_helper.h"
49 #endif 54 #endif
50 55
51 #if defined(OS_CHROMEOS) 56 #if defined(OS_CHROMEOS)
52 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" 57 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
53 #endif 58 #endif
54 59
55 using base::UserMetricsAction; 60 using base::UserMetricsAction;
56 using content::WebContents; 61 using content::WebContents;
57 62
58 namespace { 63 namespace {
59 64
65 std::string WindowOpenDispositionToString(
66 WindowOpenDisposition window_open_disposition) {
67 switch (window_open_disposition) {
68 case IGNORE_ACTION:
69 return "ignore";
70 case SAVE_TO_DISK:
71 return "save_to_disk";
72 case CURRENT_TAB:
73 return "current_tab";
74 case NEW_BACKGROUND_TAB:
75 return "new_background_tab";
76 case NEW_FOREGROUND_TAB:
77 return "new_foreground_tab";
78 case NEW_WINDOW:
79 return "new_window";
80 case NEW_POPUP:
81 return "new_popup";
82 default:
83 NOTREACHED() << "Unknown Window Open Disposition";
84 return "ignore";
85 }
86 }
87
60 static std::string TerminationStatusToString(base::TerminationStatus status) { 88 static std::string TerminationStatusToString(base::TerminationStatus status) {
61 switch (status) { 89 switch (status) {
62 case base::TERMINATION_STATUS_NORMAL_TERMINATION: 90 case base::TERMINATION_STATUS_NORMAL_TERMINATION:
63 return "normal"; 91 return "normal";
64 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: 92 case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
65 case base::TERMINATION_STATUS_STILL_RUNNING: 93 case base::TERMINATION_STATUS_STILL_RUNNING:
66 return "abnormal"; 94 return "abnormal";
67 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: 95 case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
68 return "killed"; 96 return "killed";
69 case base::TERMINATION_STATUS_PROCESS_CRASHED: 97 case base::TERMINATION_STATUS_PROCESS_CRASHED:
70 #if defined(OS_ANDROID) 98 #if defined(OS_ANDROID)
71 case base::TERMINATION_STATUS_OOM_PROTECTED: 99 case base::TERMINATION_STATUS_OOM_PROTECTED:
72 #endif 100 #endif
73 return "crashed"; 101 return "crashed";
74 case base::TERMINATION_STATUS_MAX_ENUM: 102 case base::TERMINATION_STATUS_MAX_ENUM:
75 break; 103 break;
76 } 104 }
77 NOTREACHED() << "Unknown Termination Status."; 105 NOTREACHED() << "Unknown Termination Status.";
78 return "unknown"; 106 return "unknown";
79 } 107 }
80 108
81 static std::string PermissionTypeToString(BrowserPluginPermissionType type) { 109 static std::string PermissionTypeToString(WebViewPermissionType type) {
82 switch (type) { 110 switch (type) {
83 case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: 111 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD:
112 return webview::kPermissionTypeDownload;
113 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
114 return webview::kPermissionTypeGeolocation;
115 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG:
116 return webview::kPermissionTypeDialog;
117 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
118 return webview::kPermissionTypeLoadPlugin;
119 case WEB_VIEW_PERMISSION_TYPE_MEDIA:
120 return webview::kPermissionTypeMedia;
121 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW:
84 return webview::kPermissionTypeNewWindow; 122 return webview::kPermissionTypeNewWindow;
85 case BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN: 123 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK:
124 return webview::kPermissionTypePointerLock;
125 default:
86 NOTREACHED(); 126 NOTREACHED();
87 break; 127 return std::string();
88 default: {
89 WebViewPermissionType webview = static_cast<WebViewPermissionType>(type);
90 switch (webview) {
91 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD:
92 return webview::kPermissionTypeDownload;
93 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
94 return webview::kPermissionTypeGeolocation;
95 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG:
96 return webview::kPermissionTypeDialog;
97 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
98 return webview::kPermissionTypeLoadPlugin;
99 case WEB_VIEW_PERMISSION_TYPE_MEDIA:
100 return webview::kPermissionTypeMedia;
101 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK:
102 return webview::kPermissionTypePointerLock;
103 }
104 NOTREACHED();
105 }
106 } 128 }
107 return std::string();
108 } 129 }
109 130
110 void RemoveWebViewEventListenersOnIOThread( 131 void RemoveWebViewEventListenersOnIOThread(
111 void* profile, 132 void* profile,
112 const std::string& extension_id, 133 const std::string& extension_id,
113 int embedder_process_id, 134 int embedder_process_id,
114 int view_instance_id) { 135 int view_instance_id) {
115 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 136 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
116 ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners( 137 ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners(
117 profile, 138 profile,
118 extension_id, 139 extension_id,
119 embedder_process_id, 140 embedder_process_id,
120 view_instance_id); 141 view_instance_id);
121 } 142 }
122 143
123 void AttachWebViewHelpers(WebContents* contents) { 144 void AttachWebViewHelpers(WebContents* contents) {
124 FaviconTabHelper::CreateForWebContents(contents); 145 FaviconTabHelper::CreateForWebContents(contents);
125 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( 146 extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
126 contents); 147 contents);
127 #if defined(ENABLE_PLUGINS) 148 #if defined(ENABLE_PLUGINS)
128 PluginPermissionHelper::CreateForWebContents(contents); 149 PluginPermissionHelper::CreateForWebContents(contents);
129 #endif 150 #endif
130 } 151 }
131 152
132 } // namespace 153 } // namespace
133 154
134 WebViewGuest::WebViewGuest(WebContents* guest_web_contents, 155 WebViewGuest::WebViewGuest(int guest_instance_id,
135 const std::string& embedder_extension_id, 156 WebContents* guest_web_contents,
136 const base::WeakPtr<GuestViewBase>& opener) 157 const std::string& embedder_extension_id)
137 : GuestView<WebViewGuest>(guest_web_contents, 158 : GuestView<WebViewGuest>(guest_instance_id,
138 embedder_extension_id, 159 guest_web_contents,
139 opener), 160 embedder_extension_id),
140 WebContentsObserver(guest_web_contents), 161 WebContentsObserver(guest_web_contents),
141 script_executor_(new extensions::ScriptExecutor(guest_web_contents, 162 script_executor_(new extensions::ScriptExecutor(guest_web_contents,
142 &script_observers_)), 163 &script_observers_)),
143 pending_context_menu_request_id_(0), 164 pending_context_menu_request_id_(0),
144 next_permission_request_id_(0), 165 next_permission_request_id_(0),
145 is_overriding_user_agent_(false), 166 is_overriding_user_agent_(false),
146 pending_reload_on_attachment_(false), 167 pending_reload_on_attachment_(false),
147 main_frame_id_(0), 168 main_frame_id_(0),
148 chromevox_injected_(false), 169 chromevox_injected_(false),
149 find_helper_(this), 170 find_helper_(this),
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 203
183 // static 204 // static
184 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, 205 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info,
185 bool allow) { 206 bool allow) {
186 if (allow) { 207 if (allow) {
187 // Note that |allow| == true means the embedder explicitly allowed the 208 // Note that |allow| == true means the embedder explicitly allowed the
188 // request. For some requests they might still fail. An example of such 209 // request. For some requests they might still fail. An example of such
189 // scenario would be: an embedder allows geolocation request but doesn't 210 // scenario would be: an embedder allows geolocation request but doesn't
190 // have geolocation access on its own. 211 // have geolocation access on its own.
191 switch (info.permission_type) { 212 switch (info.permission_type) {
192 case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: 213 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD:
214 content::RecordAction(
215 UserMetricsAction("WebView.PermissionAllow.Download"));
216 break;
217 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
218 content::RecordAction(
219 UserMetricsAction("WebView.PermissionAllow.Geolocation"));
220 break;
221 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG:
222 content::RecordAction(
223 UserMetricsAction("WebView.PermissionAllow.JSDialog"));
224 break;
225 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
226 content::RecordAction(
227 UserMetricsAction("WebView.Guest.PermissionAllow.PluginLoad"));
228 case WEB_VIEW_PERMISSION_TYPE_MEDIA:
229 content::RecordAction(
230 UserMetricsAction("WebView.PermissionAllow.Media"));
231 break;
232 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW:
193 content::RecordAction( 233 content::RecordAction(
194 UserMetricsAction("BrowserPlugin.PermissionAllow.NewWindow")); 234 UserMetricsAction("BrowserPlugin.PermissionAllow.NewWindow"));
195 break; 235 break;
196 case BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN: 236 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK:
237 content::RecordAction(
238 UserMetricsAction("WebView.PermissionAllow.PointerLock"));
197 break; 239 break;
198 default: { 240 default:
199 WebViewPermissionType webview_permission_type = 241 break;
200 static_cast<WebViewPermissionType>(info.permission_type);
201 switch (webview_permission_type) {
202 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD:
203 content::RecordAction(
204 UserMetricsAction("WebView.PermissionAllow.Download"));
205 break;
206 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
207 content::RecordAction(
208 UserMetricsAction("WebView.PermissionAllow.Geolocation"));
209 break;
210 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG:
211 content::RecordAction(
212 UserMetricsAction("WebView.PermissionAllow.JSDialog"));
213 break;
214 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
215 content::RecordAction(
216 UserMetricsAction("WebView.Guest.PermissionAllow.PluginLoad"));
217 case WEB_VIEW_PERMISSION_TYPE_MEDIA:
218 content::RecordAction(
219 UserMetricsAction("WebView.PermissionAllow.Media"));
220 break;
221 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK:
222 content::RecordAction(
223 UserMetricsAction("WebView.PermissionAllow.PointerLock"));
224 break;
225 default:
226 break;
227 }
228 }
229 } 242 }
230 } else { 243 } else {
231 switch (info.permission_type) { 244 switch (info.permission_type) {
232 case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: 245 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD:
246 content::RecordAction(
247 UserMetricsAction("WebView.PermissionDeny.Download"));
248 break;
249 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
250 content::RecordAction(
251 UserMetricsAction("WebView.PermissionDeny.Geolocation"));
252 break;
253 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG:
254 content::RecordAction(
255 UserMetricsAction("WebView.PermissionDeny.JSDialog"));
256 break;
257 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
258 content::RecordAction(
259 UserMetricsAction("WebView.Guest.PermissionDeny.PluginLoad"));
260 case WEB_VIEW_PERMISSION_TYPE_MEDIA:
261 content::RecordAction(
262 UserMetricsAction("WebView.PermissionDeny.Media"));
263 break;
264 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW:
233 content::RecordAction( 265 content::RecordAction(
234 UserMetricsAction("BrowserPlugin.PermissionDeny.NewWindow")); 266 UserMetricsAction("BrowserPlugin.PermissionDeny.NewWindow"));
235 break; 267 break;
236 case BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN: 268 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK:
269 content::RecordAction(
270 UserMetricsAction("WebView.PermissionDeny.PointerLock"));
237 break; 271 break;
238 default: { 272 default:
239 WebViewPermissionType webview_permission_type = 273 break;
240 static_cast<WebViewPermissionType>(info.permission_type);
241 switch (webview_permission_type) {
242 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD:
243 content::RecordAction(
244 UserMetricsAction("WebView.PermissionDeny.Download"));
245 break;
246 case WEB_VIEW_PERMISSION_TYPE_GEOLOCATION:
247 content::RecordAction(
248 UserMetricsAction("WebView.PermissionDeny.Geolocation"));
249 break;
250 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG:
251 content::RecordAction(
252 UserMetricsAction("WebView.PermissionDeny.JSDialog"));
253 break;
254 case WEB_VIEW_PERMISSION_TYPE_LOAD_PLUGIN:
255 content::RecordAction(
256 UserMetricsAction("WebView.Guest.PermissionDeny.PluginLoad"));
257 case WEB_VIEW_PERMISSION_TYPE_MEDIA:
258 content::RecordAction(
259 UserMetricsAction("WebView.PermissionDeny.Media"));
260 break;
261 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK:
262 content::RecordAction(
263 UserMetricsAction("WebView.PermissionDeny.PointerLock"));
264 break;
265 default:
266 break;
267 }
268 }
269 } 274 }
270 } 275 }
271 } 276 }
272 277
273 // static 278 // static
274 scoped_ptr<base::ListValue> WebViewGuest::MenuModelToValue( 279 scoped_ptr<base::ListValue> WebViewGuest::MenuModelToValue(
275 const ui::SimpleMenuModel& menu_model) { 280 const ui::SimpleMenuModel& menu_model) {
276 scoped_ptr<base::ListValue> items(new base::ListValue()); 281 scoped_ptr<base::ListValue> items(new base::ListValue());
277 for (int i = 0; i < menu_model.GetItemCount(); ++i) { 282 for (int i = 0; i < menu_model.GetItemCount(); ++i) {
278 base::DictionaryValue* item_value = new base::DictionaryValue(); 283 base::DictionaryValue* item_value = new base::DictionaryValue();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 DispatchEvent( 339 DispatchEvent(
335 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); 340 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass()));
336 } 341 }
337 342
338 void WebViewGuest::Close() { 343 void WebViewGuest::Close() {
339 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); 344 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
340 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); 345 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass()));
341 } 346 }
342 347
343 void WebViewGuest::DidAttach() { 348 void WebViewGuest::DidAttach() {
349 if (GetOpener()) {
350 // We need to do a navigation here if the target URL has changed between
351 // the time the WebContents was created and the time it was attached.
352 // We also need to do an initial navigation if a RenderView was never
353 // created for the new window in cases where there is no referrer.
354 PendingWindowMap::iterator it =
355 GetOpener()->pending_new_windows_.find(this);
356 if (it != GetOpener()->pending_new_windows_.end()) {
357 const NewWindowInfo& new_window_info = it->second;
358 NavigateGuest(new_window_info.url.spec());
359 } else {
360 NOTREACHED();
361 }
362
363 // Once a new guest is attached to the DOM of the embedder page, then the
364 // lifetime of the new guest is no longer managed by the opener guest.
365 GetOpener()->pending_new_windows_.erase(this);
366 }
367
344 if (pending_reload_on_attachment_) { 368 if (pending_reload_on_attachment_) {
345 pending_reload_on_attachment_ = false; 369 pending_reload_on_attachment_ = false;
346 guest_web_contents()->GetController().Reload(false); 370 guest_web_contents()->GetController().Reload(false);
347 } 371 }
348 } 372 }
349 373
350 void WebViewGuest::EmbedderDestroyed() { 374 void WebViewGuest::EmbedderDestroyed() {
351 // TODO(fsamuel): WebRequest event listeners for <webview> should survive 375 // TODO(fsamuel): WebRequest event listeners for <webview> should survive
352 // reparenting of a <webview> within a single embedder. Right now, we keep 376 // reparenting of a <webview> within a single embedder. Right now, we keep
353 // around the browser state for the listener for the lifetime of the embedder. 377 // around the browser state for the listener for the lifetime of the embedder.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 const GURL& url, 461 const GURL& url,
438 const std::string& error_type) { 462 const std::string& error_type) {
439 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); 463 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
440 args->SetBoolean(guestview::kIsTopLevel, is_top_level); 464 args->SetBoolean(guestview::kIsTopLevel, is_top_level);
441 args->SetString(guestview::kUrl, url.possibly_invalid_spec()); 465 args->SetString(guestview::kUrl, url.possibly_invalid_spec());
442 args->SetString(guestview::kReason, error_type); 466 args->SetString(guestview::kReason, error_type);
443 DispatchEvent( 467 DispatchEvent(
444 new GuestViewBase::Event(webview::kEventLoadAbort, args.Pass())); 468 new GuestViewBase::Event(webview::kEventLoadAbort, args.Pass()));
445 } 469 }
446 470
471 WebViewGuest* WebViewGuest::CreateNewGuestWindow(
472 const content::OpenURLParams& params) {
473
474 GuestViewManager* guest_manager =
475 GuestViewManager::FromBrowserContext(browser_context());
476 // Allocate a new instance ID for the new guest.
477 int instance_id = guest_manager->GetNextInstanceID();
478
479 // Set the attach params to use the same partition as the opener.
480 // We pull the partition information from the site's URL, which is of the
481 // form guest://site/{persist}?{partition_name}.
482 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL();
483
484 scoped_ptr<base::DictionaryValue> create_params(extra_params()->DeepCopy());
485 const std::string& storage_partition_id = site_url.query();
486 bool persist_storage =
487 site_url.path().find("persist") != std::string::npos;
488 WebContents* new_guest_web_contents =
489 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(),
490 instance_id,
491 storage_partition_id,
492 persist_storage,
493 create_params.Pass());
494 WebViewGuest* new_guest =
495 WebViewGuest::FromWebContents(new_guest_web_contents);
496 new_guest->SetOpener(this);
497
498 // Take ownership of |new_guest|.
499 pending_new_windows_.insert(
500 std::make_pair(new_guest, NewWindowInfo(params.url, std::string())));
501
502 // Request permission to show the new window.
503 RequestNewWindowPermission(params.disposition, gfx::Rect(),
504 params.user_gesture,
505 new_guest->guest_web_contents());
506
507 return new_guest;
508 }
509
447 // TODO(fsamuel): Find a reliable way to test the 'responsive' and 510 // TODO(fsamuel): Find a reliable way to test the 'responsive' and
448 // 'unresponsive' events. 511 // 'unresponsive' events.
449 void WebViewGuest::RendererResponsive() { 512 void WebViewGuest::RendererResponsive() {
450 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); 513 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
451 args->SetInteger(webview::kProcessId, 514 args->SetInteger(webview::kProcessId,
452 guest_web_contents()->GetRenderProcessHost()->GetID()); 515 guest_web_contents()->GetRenderProcessHost()->GetID());
453 DispatchEvent( 516 DispatchEvent(
454 new GuestViewBase::Event(webview::kEventResponsive, args.Pass())); 517 new GuestViewBase::Event(webview::kEventResponsive, args.Pass()));
455 } 518 }
456 519
457 void WebViewGuest::RendererUnresponsive() { 520 void WebViewGuest::RendererUnresponsive() {
458 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); 521 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
459 args->SetInteger(webview::kProcessId, 522 args->SetInteger(webview::kProcessId,
460 guest_web_contents()->GetRenderProcessHost()->GetID()); 523 guest_web_contents()->GetRenderProcessHost()->GetID());
461 DispatchEvent( 524 DispatchEvent(
462 new GuestViewBase::Event(webview::kEventUnresponsive, args.Pass())); 525 new GuestViewBase::Event(webview::kEventUnresponsive, args.Pass()));
463 } 526 }
464 527
465 void WebViewGuest::RequestPermission(
466 BrowserPluginPermissionType permission_type,
467 const base::DictionaryValue& request_info,
468 const PermissionResponseCallback& callback,
469 bool allowed_by_default) {
470 RequestPermissionInternal(permission_type,
471 request_info,
472 callback,
473 allowed_by_default);
474 }
475
476 void WebViewGuest::Observe(int type, 528 void WebViewGuest::Observe(int type,
477 const content::NotificationSource& source, 529 const content::NotificationSource& source,
478 const content::NotificationDetails& details) { 530 const content::NotificationDetails& details) {
479 switch (type) { 531 switch (type) {
480 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: { 532 case content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME: {
481 DCHECK_EQ(content::Source<WebContents>(source).ptr(), 533 DCHECK_EQ(content::Source<WebContents>(source).ptr(),
482 guest_web_contents()); 534 guest_web_contents());
483 if (content::Source<WebContents>(source).ptr() == guest_web_contents()) 535 if (content::Source<WebContents>(source).ptr() == guest_web_contents())
484 LoadHandlerCalled(); 536 LoadHandlerCalled();
485 break; 537 break;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 guest_web_contents()->GetController().GoToOffset(relative_index); 587 guest_web_contents()->GetController().GoToOffset(relative_index);
536 } 588 }
537 589
538 void WebViewGuest::Reload() { 590 void WebViewGuest::Reload() {
539 // TODO(fsamuel): Don't check for repost because we don't want to show 591 // TODO(fsamuel): Don't check for repost because we don't want to show
540 // Chromium's repost warning. We might want to implement a separate API 592 // Chromium's repost warning. We might want to implement a separate API
541 // for registering a callback if a repost is about to happen. 593 // for registering a callback if a repost is about to happen.
542 guest_web_contents()->GetController().Reload(false); 594 guest_web_contents()->GetController().Reload(false);
543 } 595 }
544 596
545
546 void WebViewGuest::RequestGeolocationPermission( 597 void WebViewGuest::RequestGeolocationPermission(
547 int bridge_id, 598 int bridge_id,
548 const GURL& requesting_frame, 599 const GURL& requesting_frame,
549 bool user_gesture, 600 bool user_gesture,
550 const base::Callback<void(bool)>& callback) { 601 const base::Callback<void(bool)>& callback) {
551 base::DictionaryValue request_info; 602 base::DictionaryValue request_info;
552 request_info.Set(guestview::kUrl, 603 request_info.Set(guestview::kUrl,
553 base::Value::CreateStringValue(requesting_frame.spec())); 604 base::Value::CreateStringValue(requesting_frame.spec()));
554 request_info.Set(guestview::kUserGesture, 605 request_info.Set(guestview::kUserGesture,
555 base::Value::CreateBooleanValue(user_gesture)); 606 base::Value::CreateBooleanValue(user_gesture));
556 607
557 // It is safe to hold an unretained pointer to WebViewGuest because this 608 // It is safe to hold an unretained pointer to WebViewGuest because this
558 // callback is called from WebViewGuest::SetPermission. 609 // callback is called from WebViewGuest::SetPermission.
559 const PermissionResponseCallback permission_callback = 610 const PermissionResponseCallback permission_callback =
560 base::Bind(&WebViewGuest::OnWebViewGeolocationPermissionResponse, 611 base::Bind(&WebViewGuest::OnWebViewGeolocationPermissionResponse,
561 base::Unretained(this), 612 base::Unretained(this),
562 bridge_id, 613 bridge_id,
563 user_gesture, 614 user_gesture,
564 callback); 615 callback);
565 int request_id = RequestPermissionInternal( 616 int request_id = RequestPermission(
566 static_cast<BrowserPluginPermissionType>( 617 WEB_VIEW_PERMISSION_TYPE_GEOLOCATION,
567 WEB_VIEW_PERMISSION_TYPE_GEOLOCATION),
568 request_info, 618 request_info,
569 permission_callback, 619 permission_callback,
570 false /* allowed_by_default */); 620 false /* allowed_by_default */);
571 bridge_id_to_request_id_map_[bridge_id] = request_id; 621 bridge_id_to_request_id_map_[bridge_id] = request_id;
572 } 622 }
573 623
574 void WebViewGuest::OnWebViewGeolocationPermissionResponse( 624 void WebViewGuest::OnWebViewGeolocationPermissionResponse(
575 int bridge_id, 625 int bridge_id,
576 bool user_gesture, 626 bool user_gesture,
577 const base::Callback<void(bool)>& callback, 627 const base::Callback<void(bool)>& callback,
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 WebContents* web_contents) { 916 WebContents* web_contents) {
867 content::BrowserThread::PostTask( 917 content::BrowserThread::PostTask(
868 content::BrowserThread::IO, FROM_HERE, 918 content::BrowserThread::IO, FROM_HERE,
869 base::Bind( 919 base::Bind(
870 &ExtensionRendererState::RemoveWebView, 920 &ExtensionRendererState::RemoveWebView,
871 base::Unretained(ExtensionRendererState::GetInstance()), 921 base::Unretained(ExtensionRendererState::GetInstance()),
872 web_contents->GetRenderProcessHost()->GetID(), 922 web_contents->GetRenderProcessHost()->GetID(),
873 web_contents->GetRoutingID())); 923 web_contents->GetRoutingID()));
874 } 924 }
875 925
876 GURL WebViewGuest::ResolveURL(const std::string& src) {
877 if (!in_extension()) {
878 NOTREACHED();
879 return GURL(src);
880 }
881
882 GURL default_url(base::StringPrintf("%s://%s/",
883 extensions::kExtensionScheme,
884 embedder_extension_id().c_str()));
885 return default_url.Resolve(src);
886 }
887
888 void WebViewGuest::SizeChanged(const gfx::Size& old_size, 926 void WebViewGuest::SizeChanged(const gfx::Size& old_size,
889 const gfx::Size& new_size) { 927 const gfx::Size& new_size) {
890 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); 928 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
891 args->SetInteger(webview::kOldHeight, old_size.height()); 929 args->SetInteger(webview::kOldHeight, old_size.height());
892 args->SetInteger(webview::kOldWidth, old_size.width()); 930 args->SetInteger(webview::kOldWidth, old_size.width());
893 args->SetInteger(webview::kNewHeight, new_size.height()); 931 args->SetInteger(webview::kNewHeight, new_size.height());
894 args->SetInteger(webview::kNewWidth, new_size.width()); 932 args->SetInteger(webview::kNewWidth, new_size.width());
895 DispatchEvent( 933 DispatchEvent(
896 new GuestViewBase::Event(webview::kEventSizeChanged, args.Pass())); 934 new GuestViewBase::Event(webview::kEventSizeChanged, args.Pass()));
897 } 935 }
898 936
899 void WebViewGuest::RequestMediaAccessPermission( 937 void WebViewGuest::RequestMediaAccessPermission(
900 const content::MediaStreamRequest& request, 938 const content::MediaStreamRequest& request,
901 const content::MediaResponseCallback& callback) { 939 const content::MediaResponseCallback& callback) {
902 base::DictionaryValue request_info; 940 base::DictionaryValue request_info;
903 request_info.Set( 941 request_info.Set(
904 guestview::kUrl, 942 guestview::kUrl,
905 base::Value::CreateStringValue(request.security_origin.spec())); 943 base::Value::CreateStringValue(request.security_origin.spec()));
906 RequestPermission(static_cast<BrowserPluginPermissionType>( 944 RequestPermission(WEB_VIEW_PERMISSION_TYPE_MEDIA,
907 WEB_VIEW_PERMISSION_TYPE_MEDIA),
908 request_info, 945 request_info,
909 base::Bind(&WebViewGuest::OnWebViewMediaPermissionResponse, 946 base::Bind(&WebViewGuest::OnWebViewMediaPermissionResponse,
910 base::Unretained(this), 947 base::Unretained(this),
911 request, 948 request,
912 callback), 949 callback),
913 false /* allowed_by_default */); 950 false /* allowed_by_default */);
914 } 951 }
915 952
916 void WebViewGuest::CanDownload( 953 void WebViewGuest::CanDownload(
917 const std::string& request_method, 954 const std::string& request_method,
918 const GURL& url, 955 const GURL& url,
919 const base::Callback<void(bool)>& callback) { 956 const base::Callback<void(bool)>& callback) {
920 base::DictionaryValue request_info; 957 base::DictionaryValue request_info;
921 request_info.Set( 958 request_info.Set(
922 guestview::kUrl, 959 guestview::kUrl,
923 base::Value::CreateStringValue(url.spec())); 960 base::Value::CreateStringValue(url.spec()));
924 RequestPermission( 961 RequestPermission(
925 static_cast<BrowserPluginPermissionType>( 962 WEB_VIEW_PERMISSION_TYPE_DOWNLOAD,
926 WEB_VIEW_PERMISSION_TYPE_DOWNLOAD),
927 request_info, 963 request_info,
928 base::Bind(&WebViewGuest::OnWebViewDownloadPermissionResponse, 964 base::Bind(&WebViewGuest::OnWebViewDownloadPermissionResponse,
929 base::Unretained(this), 965 base::Unretained(this),
930 callback), 966 callback),
931 false /* allowed_by_default */); 967 false /* allowed_by_default */);
932 } 968 }
933 969
934 void WebViewGuest::RequestPointerLockPermission( 970 void WebViewGuest::RequestPointerLockPermission(
935 bool user_gesture, 971 bool user_gesture,
936 bool last_unlocked_by_target, 972 bool last_unlocked_by_target,
937 const base::Callback<void(bool)>& callback) { 973 const base::Callback<void(bool)>& callback) {
938 base::DictionaryValue request_info; 974 base::DictionaryValue request_info;
939 request_info.Set(guestview::kUserGesture, 975 request_info.Set(guestview::kUserGesture,
940 base::Value::CreateBooleanValue(user_gesture)); 976 base::Value::CreateBooleanValue(user_gesture));
941 request_info.Set(webview::kLastUnlockedBySelf, 977 request_info.Set(webview::kLastUnlockedBySelf,
942 base::Value::CreateBooleanValue(last_unlocked_by_target)); 978 base::Value::CreateBooleanValue(last_unlocked_by_target));
943 request_info.Set(guestview::kUrl, 979 request_info.Set(guestview::kUrl,
944 base::Value::CreateStringValue( 980 base::Value::CreateStringValue(
945 guest_web_contents()->GetLastCommittedURL().spec())); 981 guest_web_contents()->GetLastCommittedURL().spec()));
946 982
947 RequestPermission( 983 RequestPermission(
948 static_cast<BrowserPluginPermissionType>( 984 WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK,
949 WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK),
950 request_info, 985 request_info,
951 base::Bind(&WebViewGuest::OnWebViewPointerLockPermissionResponse, 986 base::Bind(&WebViewGuest::OnWebViewPointerLockPermissionResponse,
952 base::Unretained(this), 987 base::Unretained(this),
953 callback), 988 callback),
954 false /* allowed_by_default */); 989 false /* allowed_by_default */);
955 } 990 }
956 991
957 content::JavaScriptDialogManager* 992 content::JavaScriptDialogManager*
958 WebViewGuest::GetJavaScriptDialogManager() { 993 WebViewGuest::GetJavaScriptDialogManager() {
959 return &javascript_dialog_helper_; 994 return &javascript_dialog_helper_;
960 } 995 }
961 996
997 void WebViewGuest::NavigateGuest(const std::string& src) {
998 GURL url = ResolveURL(src);
999
1000 // Do not allow navigating a guest to schemes other than known safe schemes.
1001 // This will block the embedder trying to load unwanted schemes, e.g.
1002 // chrome://settings.
1003 bool scheme_is_blocked =
1004 (!content::ChildProcessSecurityPolicy::GetInstance()->IsWebSafeScheme(
1005 url.scheme()) &&
1006 !content::ChildProcessSecurityPolicy::GetInstance()->IsPseudoScheme(
1007 url.scheme())) ||
1008 url.SchemeIs(content::kJavaScriptScheme);
1009 if (scheme_is_blocked || !url.is_valid()) {
1010 std::string error_type;
1011 base::RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::",
1012 &error_type);
1013 LoadAbort(true /* is_top_level */, url, error_type);
1014 return;
1015 }
1016
1017 GURL validated_url(url);
1018 guest_web_contents()->GetRenderProcessHost()->
1019 FilterURL(false, &validated_url);
1020 // As guests do not swap processes on navigation, only navigations to
1021 // normal web URLs are supported. No protocol handlers are installed for
1022 // other schemes (e.g., WebUI or extensions), and no permissions or bindings
1023 // can be granted to the guest process.
1024 LoadURLWithParams(validated_url,
1025 content::Referrer(),
1026 content::PAGE_TRANSITION_AUTO_TOPLEVEL,
1027 guest_web_contents());
1028 }
1029
962 #if defined(OS_CHROMEOS) 1030 #if defined(OS_CHROMEOS)
963 void WebViewGuest::OnAccessibilityStatusChanged( 1031 void WebViewGuest::OnAccessibilityStatusChanged(
964 const chromeos::AccessibilityStatusEventDetails& details) { 1032 const chromeos::AccessibilityStatusEventDetails& details) {
965 if (details.notification_type == chromeos::ACCESSIBILITY_MANAGER_SHUTDOWN) { 1033 if (details.notification_type == chromeos::ACCESSIBILITY_MANAGER_SHUTDOWN) {
966 accessibility_subscription_.reset(); 1034 accessibility_subscription_.reset();
967 } else if (details.notification_type == 1035 } else if (details.notification_type ==
968 chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) { 1036 chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) {
969 if (details.enabled) 1037 if (details.enabled)
970 InjectChromeVoxIfNeeded(guest_web_contents()->GetRenderViewHost()); 1038 InjectChromeVoxIfNeeded(guest_web_contents()->GetRenderViewHost());
971 else 1039 else
(...skipping 20 matching lines...) Expand all
992 std::map<int, int>::iterator bridge_itr = 1060 std::map<int, int>::iterator bridge_itr =
993 bridge_id_to_request_id_map_.find(bridge_id); 1061 bridge_id_to_request_id_map_.find(bridge_id);
994 if (bridge_itr == bridge_id_to_request_id_map_.end()) 1062 if (bridge_itr == bridge_id_to_request_id_map_.end())
995 return webview::kInvalidPermissionRequestID; 1063 return webview::kInvalidPermissionRequestID;
996 1064
997 int request_id = bridge_itr->second; 1065 int request_id = bridge_itr->second;
998 bridge_id_to_request_id_map_.erase(bridge_itr); 1066 bridge_id_to_request_id_map_.erase(bridge_itr);
999 return request_id; 1067 return request_id;
1000 } 1068 }
1001 1069
1002 int WebViewGuest::RequestPermissionInternal( 1070 int WebViewGuest::RequestPermission(
1003 BrowserPluginPermissionType permission_type, 1071 WebViewPermissionType permission_type,
1004 const base::DictionaryValue& request_info, 1072 const base::DictionaryValue& request_info,
1005 const PermissionResponseCallback& callback, 1073 const PermissionResponseCallback& callback,
1006 bool allowed_by_default) { 1074 bool allowed_by_default) {
1007 // If there are too many pending permission requests then reject this request. 1075 // If there are too many pending permission requests then reject this request.
1008 if (pending_permission_requests_.size() >= 1076 if (pending_permission_requests_.size() >=
1009 webview::kMaxOutstandingPermissionRequests) { 1077 webview::kMaxOutstandingPermissionRequests) {
1010 // Let the stack unwind before we deny the permission request so that 1078 // Let the stack unwind before we deny the permission request so that
1011 // objects held by the permission request are not destroyed immediately 1079 // objects held by the permission request are not destroyed immediately
1012 // after creation. This is to allow those same objects to be accessed again 1080 // after creation. This is to allow those same objects to be accessed again
1013 // in the same scope without fear of use after freeing. 1081 // in the same scope without fear of use after freeing.
1014 base::MessageLoop::current()->PostTask( 1082 base::MessageLoop::current()->PostTask(
1015 FROM_HERE, 1083 FROM_HERE,
1016 base::Bind(&PermissionResponseCallback::Run, 1084 base::Bind(&PermissionResponseCallback::Run,
1017 base::Owned(new PermissionResponseCallback(callback)), 1085 base::Owned(new PermissionResponseCallback(callback)),
1018 allowed_by_default, 1086 allowed_by_default,
1019 std::string())); 1087 std::string()));
1020 return webview::kInvalidPermissionRequestID; 1088 return webview::kInvalidPermissionRequestID;
1021 } 1089 }
1022 1090
1023 int request_id = next_permission_request_id_++; 1091 int request_id = next_permission_request_id_++;
1024 pending_permission_requests_[request_id] = 1092 pending_permission_requests_[request_id] =
1025 PermissionResponseInfo(callback, permission_type, allowed_by_default); 1093 PermissionResponseInfo(callback, permission_type, allowed_by_default);
1026 scoped_ptr<base::DictionaryValue> args(request_info.DeepCopy()); 1094 scoped_ptr<base::DictionaryValue> args(request_info.DeepCopy());
1027 args->SetInteger(webview::kRequestId, request_id); 1095 args->SetInteger(webview::kRequestId, request_id);
1028 switch (static_cast<int>(permission_type)) { 1096 switch (permission_type) {
1029 case BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW: { 1097 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: {
1030 DispatchEvent( 1098 DispatchEvent(
1031 new GuestViewBase::Event(webview::kEventNewWindow, args.Pass())); 1099 new GuestViewBase::Event(webview::kEventNewWindow, args.Pass()));
1032 break; 1100 break;
1033 } 1101 }
1034 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: { 1102 case WEB_VIEW_PERMISSION_TYPE_JAVASCRIPT_DIALOG: {
1035 DispatchEvent( 1103 DispatchEvent(
1036 new GuestViewBase::Event(webview::kEventDialog, args.Pass())); 1104 new GuestViewBase::Event(webview::kEventDialog, args.Pass()));
1037 break; 1105 break;
1038 } 1106 }
1039 default: { 1107 default: {
1040 args->SetString(webview::kPermission, 1108 args->SetString(webview::kPermission,
1041 PermissionTypeToString(permission_type)); 1109 PermissionTypeToString(permission_type));
1042 DispatchEvent(new GuestViewBase::Event(webview::kEventPermissionRequest, 1110 DispatchEvent(new GuestViewBase::Event(webview::kEventPermissionRequest,
1043 args.Pass())); 1111 args.Pass()));
1044 break; 1112 break;
1045 } 1113 }
1046 } 1114 }
1047 return request_id; 1115 return request_id;
1048 } 1116 }
1049 1117
1050 WebViewGuest::PermissionResponseInfo::PermissionResponseInfo() 1118 WebViewGuest::PermissionResponseInfo::PermissionResponseInfo()
1051 : permission_type(BROWSER_PLUGIN_PERMISSION_TYPE_UNKNOWN), 1119 : permission_type(WEB_VIEW_PERMISSION_TYPE_UNKNOWN),
1052 allowed_by_default(false) { 1120 allowed_by_default(false) {
1053 } 1121 }
1054 1122
1055 WebViewGuest::PermissionResponseInfo::PermissionResponseInfo( 1123 WebViewGuest::PermissionResponseInfo::PermissionResponseInfo(
1056 const PermissionResponseCallback& callback, 1124 const PermissionResponseCallback& callback,
1057 BrowserPluginPermissionType permission_type, 1125 WebViewPermissionType permission_type,
1058 bool allowed_by_default) 1126 bool allowed_by_default)
1059 : callback(callback), 1127 : callback(callback),
1060 permission_type(permission_type), 1128 permission_type(permission_type),
1061 allowed_by_default(allowed_by_default) { 1129 allowed_by_default(allowed_by_default) {
1062 } 1130 }
1063 1131
1064 WebViewGuest::PermissionResponseInfo::~PermissionResponseInfo() { 1132 WebViewGuest::PermissionResponseInfo::~PermissionResponseInfo() {
1065 } 1133 }
1066 1134
1067 void WebViewGuest::ShowContextMenu(int request_id, 1135 void WebViewGuest::ShowContextMenu(int request_id,
1068 const MenuItemVector* items) { 1136 const MenuItemVector* items) {
1069 if (!pending_menu_.get()) 1137 if (!pending_menu_.get())
1070 return; 1138 return;
1071 1139
1072 // Make sure this was the correct request. 1140 // Make sure this was the correct request.
1073 if (request_id != pending_context_menu_request_id_) 1141 if (request_id != pending_context_menu_request_id_)
1074 return; 1142 return;
1075 1143
1076 // TODO(lazyboy): Implement. 1144 // TODO(lazyboy): Implement.
1077 DCHECK(!items); 1145 DCHECK(!items);
1078 1146
1079 ContextMenuDelegate* menu_delegate = 1147 ContextMenuDelegate* menu_delegate =
1080 ContextMenuDelegate::FromWebContents(guest_web_contents()); 1148 ContextMenuDelegate::FromWebContents(guest_web_contents());
1081 menu_delegate->ShowMenu(pending_menu_.Pass()); 1149 menu_delegate->ShowMenu(pending_menu_.Pass());
1082 } 1150 }
1151
1152 void WebViewGuest::Destroy() {
1153 if (!attached() && GetOpener())
1154 GetOpener()->pending_new_windows_.erase(this);
1155 DestroyUnattachedWindows();
1156 GuestViewBase::Destroy();
1157 }
1158
1159 void WebViewGuest::AddNewContents(content::WebContents* source,
1160 content::WebContents* new_contents,
1161 WindowOpenDisposition disposition,
1162 const gfx::Rect& initial_pos,
1163 bool user_gesture,
1164 bool* was_blocked) {
1165 if (was_blocked)
1166 *was_blocked = false;
1167 RequestNewWindowPermission(disposition,
1168 initial_pos,
1169 user_gesture,
1170 new_contents);
1171 }
1172
1173 content::WebContents* WebViewGuest::OpenURLFromTab(
1174 content::WebContents* source,
1175 const content::OpenURLParams& params) {
1176 // If the guest wishes to navigate away prior to attachment then we save the
1177 // navigation to perform upon attachment. Navigation initializes a lot of
1178 // state that assumes an embedder exists, such as RenderWidgetHostViewGuest.
1179 // Navigation also resumes resource loading which we don't want to allow
1180 // until attachment.
1181 if (!attached()) {
1182 WebViewGuest* opener = GetOpener();
1183 PendingWindowMap::iterator it =
1184 opener->pending_new_windows_.find(this);
1185 if (it == opener->pending_new_windows_.end())
1186 return NULL;
1187 const NewWindowInfo& old_target_url = it->second;
1188 NewWindowInfo new_window_info(params.url, old_target_url.name);
1189 it->second = new_window_info;
1190 return NULL;
1191 }
1192 if (params.disposition == CURRENT_TAB) {
1193 // This can happen for cross-site redirects.
1194 LoadURLWithParams(params.url, params.referrer, params.transition, source);
1195 return source;
1196 }
1197
1198 return CreateNewGuestWindow(params)->guest_web_contents();
1199 }
1200
1201 void WebViewGuest::WebContentsCreated(WebContents* source_contents,
1202 int opener_render_frame_id,
1203 const base::string16& frame_name,
1204 const GURL& target_url,
1205 content::WebContents* new_contents) {
1206 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents);
1207 CHECK(guest);
1208 guest->SetOpener(this);
1209 std::string guest_name = base::UTF16ToUTF8(frame_name);
1210 pending_new_windows_.insert(
1211 std::make_pair(guest, NewWindowInfo(target_url, guest_name)));
1212 }
1213
1214 void WebViewGuest::LoadURLWithParams(const GURL& url,
1215 const content::Referrer& referrer,
1216 content::PageTransition transition_type,
1217 content::WebContents* web_contents) {
1218 content::NavigationController::LoadURLParams load_url_params(url);
1219 load_url_params.referrer = referrer;
1220 load_url_params.transition_type = transition_type;
1221 load_url_params.extra_headers = std::string();
1222 if (IsOverridingUserAgent()) {
1223 load_url_params.override_user_agent =
1224 content::NavigationController::UA_OVERRIDE_TRUE;
1225 }
1226 web_contents->GetController().LoadURLWithParams(load_url_params);
1227 }
1228
1229 void WebViewGuest::RequestNewWindowPermission(
1230 WindowOpenDisposition disposition,
1231 const gfx::Rect& initial_bounds,
1232 bool user_gesture,
1233 content::WebContents* new_contents) {
1234 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents);
1235 if (!guest)
1236 return;
1237 PendingWindowMap::iterator it = pending_new_windows_.find(guest);
1238 if (it == pending_new_windows_.end())
1239 return;
1240 const NewWindowInfo& new_window_info = it->second;
1241
1242 base::DictionaryValue request_info;
1243 request_info.Set(webview::kInitialHeight,
1244 base::Value::CreateIntegerValue(initial_bounds.height()));
1245 request_info.Set(webview::kInitialWidth,
1246 base::Value::CreateIntegerValue(initial_bounds.width()));
1247 request_info.Set(webview::kTargetURL,
1248 base::Value::CreateStringValue(new_window_info.url.spec()));
1249 request_info.Set(webview::kName,
1250 base::Value::CreateStringValue(new_window_info.name));
1251 request_info.Set(webview::kWindowID,
1252 base::Value::CreateIntegerValue(guest->guest_instance_id()));
1253 request_info.Set(webview::kWindowOpenDisposition,
1254 base::Value::CreateStringValue(
1255 WindowOpenDispositionToString(disposition)));
1256
1257 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW,
1258 request_info,
1259 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse,
1260 base::Unretained(this),
1261 guest->guest_instance_id()),
1262 false /* allowed_by_default */);
1263 }
1264
1265 void WebViewGuest::DestroyUnattachedWindows() {
1266 // Destroy() reaches in and removes the WebViewGuest from its opener's
1267 // pending_new_windows_ set. To avoid mutating the set while iterating, we
1268 // create a copy of the pending new windows set and iterate over the copy.
1269 PendingWindowMap pending_new_windows(pending_new_windows_);
1270 // Clean up unattached new windows opened by this guest.
1271 for (PendingWindowMap::const_iterator it = pending_new_windows.begin();
1272 it != pending_new_windows.end(); ++it) {
1273 it->first->Destroy();
1274 }
1275 // All pending windows should be removed from the set after Destroy() is
1276 // called on all of them.
1277 DCHECK(pending_new_windows_.empty());
1278 }
1279
1280 GURL WebViewGuest::ResolveURL(const std::string& src) {
1281 if (!in_extension()) {
1282 NOTREACHED();
1283 return GURL(src);
1284 }
1285
1286 GURL default_url(base::StringPrintf("%s://%s/",
1287 extensions::kExtensionScheme,
1288 embedder_extension_id().c_str()));
1289 return default_url.Resolve(src);
1290 }
1291
1292 void WebViewGuest::OnWebViewNewWindowResponse(
1293 int new_window_instance_id,
1294 bool allow,
1295 const std::string& user_input) {
1296 WebViewGuest* guest =
1297 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id);
1298 if (!guest)
1299 return;
1300
1301 if (!allow)
1302 guest->Destroy();
1303 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698