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