OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } | |
OLD | NEW |