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

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

Powered by Google App Engine
This is Rietveld 408576698