| 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/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/chrome_notification_types.h" | 10 #include "chrome/browser/chrome_notification_types.h" |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: | 134 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: |
| 135 return webview::kPermissionTypeNewWindow; | 135 return webview::kPermissionTypeNewWindow; |
| 136 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: | 136 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: |
| 137 return webview::kPermissionTypePointerLock; | 137 return webview::kPermissionTypePointerLock; |
| 138 default: | 138 default: |
| 139 NOTREACHED(); | 139 NOTREACHED(); |
| 140 return std::string(); | 140 return std::string(); |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 | 143 |
| 144 std::string GetStoragePartitionIdFromSiteURL(const GURL& site_url) { |
| 145 const std::string& partition_id = site_url.query(); |
| 146 bool persist_storage = site_url.path().find("persist") != std::string::npos; |
| 147 return (persist_storage ? webview::kPersistPrefix : "") + partition_id; |
| 148 } |
| 149 |
| 144 void RemoveWebViewEventListenersOnIOThread( | 150 void RemoveWebViewEventListenersOnIOThread( |
| 145 void* profile, | 151 void* profile, |
| 146 const std::string& extension_id, | 152 const std::string& extension_id, |
| 147 int embedder_process_id, | 153 int embedder_process_id, |
| 148 int view_instance_id) { | 154 int view_instance_id) { |
| 149 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 155 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 150 ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners( | 156 ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners( |
| 151 profile, | 157 profile, |
| 152 extension_id, | 158 extension_id, |
| 153 embedder_process_id, | 159 embedder_process_id, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 base::Bind(&WebViewGuest::OnAccessibilityStatusChanged, | 211 base::Bind(&WebViewGuest::OnAccessibilityStatusChanged, |
| 206 base::Unretained(this))); | 212 base::Unretained(this))); |
| 207 #endif | 213 #endif |
| 208 | 214 |
| 209 AttachWebViewHelpers(guest_web_contents); | 215 AttachWebViewHelpers(guest_web_contents); |
| 210 } | 216 } |
| 211 | 217 |
| 212 // static | 218 // static |
| 213 const char WebViewGuest::Type[] = "webview"; | 219 const char WebViewGuest::Type[] = "webview"; |
| 214 | 220 |
| 215 // static. | 221 // static |
| 216 int WebViewGuest::GetViewInstanceId(WebContents* contents) { | 222 int WebViewGuest::GetViewInstanceId(WebContents* contents) { |
| 217 WebViewGuest* guest = FromWebContents(contents); | 223 WebViewGuest* guest = FromWebContents(contents); |
| 218 if (!guest) | 224 if (!guest) |
| 219 return guestview::kInstanceIDNone; | 225 return guestview::kInstanceIDNone; |
| 220 | 226 |
| 221 return guest->view_instance_id(); | 227 return guest->view_instance_id(); |
| 222 } | 228 } |
| 223 | 229 |
| 224 // static | 230 // static |
| 231 void WebViewGuest::ParsePartitionParam( |
| 232 const base::DictionaryValue* extra_params, |
| 233 std::string* storage_partition_id, |
| 234 bool* persist_storage) { |
| 235 std::string partition_str; |
| 236 if (!extra_params->GetString(webview::kStoragePartitionId, |
| 237 &partition_str)) { |
| 238 return; |
| 239 } |
| 240 |
| 241 // Since the "persist:" prefix is in ASCII, StartsWith will work fine on |
| 242 // UTF-8 encoded |partition_id|. If the prefix is a match, we can safely |
| 243 // remove the prefix without splicing in the middle of a multi-byte codepoint. |
| 244 // We can use the rest of the string as UTF-8 encoded one. |
| 245 if (StartsWithASCII(partition_str, "persist:", true)) { |
| 246 size_t index = partition_str.find(":"); |
| 247 CHECK(index != std::string::npos); |
| 248 // It is safe to do index + 1, since we tested for the full prefix above. |
| 249 *storage_partition_id = partition_str.substr(index + 1); |
| 250 |
| 251 if (storage_partition_id->empty()) { |
| 252 // TODO(lazyboy): Better way to deal with this error. |
| 253 return; |
| 254 } |
| 255 *persist_storage = true; |
| 256 } else { |
| 257 *storage_partition_id = partition_str; |
| 258 *persist_storage = false; |
| 259 } |
| 260 } |
| 261 |
| 262 // static |
| 225 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, | 263 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, |
| 226 bool allow) { | 264 bool allow) { |
| 227 if (allow) { | 265 if (allow) { |
| 228 // Note that |allow| == true means the embedder explicitly allowed the | 266 // Note that |allow| == true means the embedder explicitly allowed the |
| 229 // request. For some requests they might still fail. An example of such | 267 // request. For some requests they might still fail. An example of such |
| 230 // scenario would be: an embedder allows geolocation request but doesn't | 268 // scenario would be: an embedder allows geolocation request but doesn't |
| 231 // have geolocation access on its own. | 269 // have geolocation access on its own. |
| 232 switch (info.permission_type) { | 270 switch (info.permission_type) { |
| 233 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: | 271 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: |
| 234 content::RecordAction( | 272 content::RecordAction( |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 DispatchEvent( | 415 DispatchEvent( |
| 378 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); | 416 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); |
| 379 return true; | 417 return true; |
| 380 } | 418 } |
| 381 | 419 |
| 382 void WebViewGuest::CloseContents(WebContents* source) { | 420 void WebViewGuest::CloseContents(WebContents* source) { |
| 383 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); | 421 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); |
| 384 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); | 422 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); |
| 385 } | 423 } |
| 386 | 424 |
| 387 void WebViewGuest::DidAttach() { | 425 void WebViewGuest::DidAttach(const base::DictionaryValue& extra_params) { |
| 426 std::string src; |
| 427 if (extra_params.GetString("src", &src) && !src.empty()) |
| 428 NavigateGuest(src); |
| 429 |
| 388 if (GetOpener()) { | 430 if (GetOpener()) { |
| 389 // We need to do a navigation here if the target URL has changed between | 431 // We need to do a navigation here if the target URL has changed between |
| 390 // the time the WebContents was created and the time it was attached. | 432 // the time the WebContents was created and the time it was attached. |
| 391 // We also need to do an initial navigation if a RenderView was never | 433 // We also need to do an initial navigation if a RenderView was never |
| 392 // created for the new window in cases where there is no referrer. | 434 // created for the new window in cases where there is no referrer. |
| 393 PendingWindowMap::iterator it = | 435 PendingWindowMap::iterator it = |
| 394 GetOpener()->pending_new_windows_.find(this); | 436 GetOpener()->pending_new_windows_.find(this); |
| 395 if (it != GetOpener()->pending_new_windows_.end()) { | 437 if (it != GetOpener()->pending_new_windows_.end()) { |
| 396 const NewWindowInfo& new_window_info = it->second; | 438 const NewWindowInfo& new_window_info = it->second; |
| 397 NavigateGuest(new_window_info.url.spec()); | 439 NavigateGuest(new_window_info.url.spec()); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 const content::OpenURLParams& params) { | 536 const content::OpenURLParams& params) { |
| 495 GuestViewManager* guest_manager = | 537 GuestViewManager* guest_manager = |
| 496 GuestViewManager::FromBrowserContext(browser_context()); | 538 GuestViewManager::FromBrowserContext(browser_context()); |
| 497 // Allocate a new instance ID for the new guest. | 539 // Allocate a new instance ID for the new guest. |
| 498 int instance_id = guest_manager->GetNextInstanceID(); | 540 int instance_id = guest_manager->GetNextInstanceID(); |
| 499 | 541 |
| 500 // Set the attach params to use the same partition as the opener. | 542 // Set the attach params to use the same partition as the opener. |
| 501 // We pull the partition information from the site's URL, which is of the | 543 // We pull the partition information from the site's URL, which is of the |
| 502 // form guest://site/{persist}?{partition_name}. | 544 // form guest://site/{persist}?{partition_name}. |
| 503 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); | 545 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); |
| 546 scoped_ptr<base::DictionaryValue> create_params(extra_params()->DeepCopy()); |
| 547 const std::string storage_partition_id = |
| 548 GetStoragePartitionIdFromSiteURL(site_url); |
| 549 create_params->SetString(webview::kStoragePartitionId, storage_partition_id); |
| 504 | 550 |
| 505 scoped_ptr<base::DictionaryValue> create_params(extra_params()->DeepCopy()); | |
| 506 const std::string& storage_partition_id = site_url.query(); | |
| 507 bool persist_storage = | |
| 508 site_url.path().find("persist") != std::string::npos; | |
| 509 WebContents* new_guest_web_contents = | 551 WebContents* new_guest_web_contents = |
| 510 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(), | 552 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(), |
| 511 instance_id, | 553 instance_id, |
| 512 storage_partition_id, | |
| 513 persist_storage, | |
| 514 create_params.Pass()); | 554 create_params.Pass()); |
| 515 WebViewGuest* new_guest = | 555 WebViewGuest* new_guest = |
| 516 WebViewGuest::FromWebContents(new_guest_web_contents); | 556 WebViewGuest::FromWebContents(new_guest_web_contents); |
| 517 new_guest->SetOpener(this); | 557 new_guest->SetOpener(this); |
| 518 | 558 |
| 519 // Take ownership of |new_guest|. | 559 // Take ownership of |new_guest|. |
| 520 pending_new_windows_.insert( | 560 pending_new_windows_.insert( |
| 521 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); | 561 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); |
| 522 | 562 |
| 523 // Request permission to show the new window. | 563 // Request permission to show the new window. |
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 bool user_gesture, | 1393 bool user_gesture, |
| 1354 content::WebContents* new_contents) { | 1394 content::WebContents* new_contents) { |
| 1355 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); | 1395 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); |
| 1356 if (!guest) | 1396 if (!guest) |
| 1357 return; | 1397 return; |
| 1358 PendingWindowMap::iterator it = pending_new_windows_.find(guest); | 1398 PendingWindowMap::iterator it = pending_new_windows_.find(guest); |
| 1359 if (it == pending_new_windows_.end()) | 1399 if (it == pending_new_windows_.end()) |
| 1360 return; | 1400 return; |
| 1361 const NewWindowInfo& new_window_info = it->second; | 1401 const NewWindowInfo& new_window_info = it->second; |
| 1362 | 1402 |
| 1403 // Retrieve the opener partition info if we have it. |
| 1404 const GURL& site_url = new_contents->GetSiteInstance()->GetSiteURL(); |
| 1405 std::string storage_partition_id = GetStoragePartitionIdFromSiteURL(site_url); |
| 1406 |
| 1363 base::DictionaryValue request_info; | 1407 base::DictionaryValue request_info; |
| 1364 request_info.Set(webview::kInitialHeight, | 1408 request_info.Set(webview::kInitialHeight, |
| 1365 base::Value::CreateIntegerValue(initial_bounds.height())); | 1409 base::Value::CreateIntegerValue(initial_bounds.height())); |
| 1366 request_info.Set(webview::kInitialWidth, | 1410 request_info.Set(webview::kInitialWidth, |
| 1367 base::Value::CreateIntegerValue(initial_bounds.width())); | 1411 base::Value::CreateIntegerValue(initial_bounds.width())); |
| 1368 request_info.Set(webview::kTargetURL, | 1412 request_info.Set(webview::kTargetURL, |
| 1369 base::Value::CreateStringValue(new_window_info.url.spec())); | 1413 base::Value::CreateStringValue(new_window_info.url.spec())); |
| 1370 request_info.Set(webview::kName, | 1414 request_info.Set(webview::kName, |
| 1371 base::Value::CreateStringValue(new_window_info.name)); | 1415 base::Value::CreateStringValue(new_window_info.name)); |
| 1372 request_info.Set(webview::kWindowID, | 1416 request_info.Set(webview::kWindowID, |
| 1373 base::Value::CreateIntegerValue(guest->guest_instance_id())); | 1417 base::Value::CreateIntegerValue(guest->guest_instance_id())); |
| 1418 // We pass in partition info so that window-s created through newwindow |
| 1419 // API can use it to set their partition attribute. |
| 1420 request_info.Set(webview::kStoragePartitionId, |
| 1421 base::Value::CreateStringValue(storage_partition_id)); |
| 1374 request_info.Set(webview::kWindowOpenDisposition, | 1422 request_info.Set(webview::kWindowOpenDisposition, |
| 1375 base::Value::CreateStringValue( | 1423 base::Value::CreateStringValue( |
| 1376 WindowOpenDispositionToString(disposition))); | 1424 WindowOpenDispositionToString(disposition))); |
| 1377 | 1425 |
| 1378 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, | 1426 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, |
| 1379 request_info, | 1427 request_info, |
| 1380 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, | 1428 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, |
| 1381 base::Unretained(this), | 1429 base::Unretained(this), |
| 1382 guest->guest_instance_id()), | 1430 guest->guest_instance_id()), |
| 1383 false /* allowed_by_default */); | 1431 false /* allowed_by_default */); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1415 bool allow, | 1463 bool allow, |
| 1416 const std::string& user_input) { | 1464 const std::string& user_input) { |
| 1417 WebViewGuest* guest = | 1465 WebViewGuest* guest = |
| 1418 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); | 1466 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); |
| 1419 if (!guest) | 1467 if (!guest) |
| 1420 return; | 1468 return; |
| 1421 | 1469 |
| 1422 if (!allow) | 1470 if (!allow) |
| 1423 guest->Destroy(); | 1471 guest->Destroy(); |
| 1424 } | 1472 } |
| OLD | NEW |