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