| 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: | 135 case WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW: |
| 136 return webview::kPermissionTypeNewWindow; | 136 return webview::kPermissionTypeNewWindow; |
| 137 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: | 137 case WEB_VIEW_PERMISSION_TYPE_POINTER_LOCK: |
| 138 return webview::kPermissionTypePointerLock; | 138 return webview::kPermissionTypePointerLock; |
| 139 default: | 139 default: |
| 140 NOTREACHED(); | 140 NOTREACHED(); |
| 141 return std::string(); | 141 return std::string(); |
| 142 } | 142 } |
| 143 } | 143 } |
| 144 | 144 |
| 145 std::string GetStoragePartitionIdFromSiteURL(const GURL& site_url) { |
| 146 const std::string& partition_id = site_url.query(); |
| 147 bool persist_storage = site_url.path().find("persist") != std::string::npos; |
| 148 return (persist_storage ? webview::kPersistPrefix : "") + partition_id; |
| 149 } |
| 150 |
| 145 void RemoveWebViewEventListenersOnIOThread( | 151 void RemoveWebViewEventListenersOnIOThread( |
| 146 void* profile, | 152 void* profile, |
| 147 const std::string& extension_id, | 153 const std::string& extension_id, |
| 148 int embedder_process_id, | 154 int embedder_process_id, |
| 149 int view_instance_id) { | 155 int view_instance_id) { |
| 150 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | 156 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 151 ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners( | 157 ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners( |
| 152 profile, | 158 profile, |
| 153 extension_id, | 159 extension_id, |
| 154 embedder_process_id, | 160 embedder_process_id, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 // static | 245 // static |
| 240 int WebViewGuest::GetViewInstanceId(WebContents* contents) { | 246 int WebViewGuest::GetViewInstanceId(WebContents* contents) { |
| 241 WebViewGuest* guest = FromWebContents(contents); | 247 WebViewGuest* guest = FromWebContents(contents); |
| 242 if (!guest) | 248 if (!guest) |
| 243 return guestview::kInstanceIDNone; | 249 return guestview::kInstanceIDNone; |
| 244 | 250 |
| 245 return guest->view_instance_id(); | 251 return guest->view_instance_id(); |
| 246 } | 252 } |
| 247 | 253 |
| 248 // static | 254 // static |
| 255 void WebViewGuest::ParsePartitionParam( |
| 256 const base::DictionaryValue* extra_params, |
| 257 std::string* storage_partition_id, |
| 258 bool* persist_storage) { |
| 259 std::string partition_str; |
| 260 if (!extra_params->GetString(webview::kStoragePartitionId, &partition_str)) { |
| 261 return; |
| 262 } |
| 263 |
| 264 // Since the "persist:" prefix is in ASCII, StartsWith will work fine on |
| 265 // UTF-8 encoded |partition_id|. If the prefix is a match, we can safely |
| 266 // remove the prefix without splicing in the middle of a multi-byte codepoint. |
| 267 // We can use the rest of the string as UTF-8 encoded one. |
| 268 if (StartsWithASCII(partition_str, "persist:", true)) { |
| 269 size_t index = partition_str.find(":"); |
| 270 CHECK(index != std::string::npos); |
| 271 // It is safe to do index + 1, since we tested for the full prefix above. |
| 272 *storage_partition_id = partition_str.substr(index + 1); |
| 273 |
| 274 if (storage_partition_id->empty()) { |
| 275 // TODO(lazyboy): Better way to deal with this error. |
| 276 return; |
| 277 } |
| 278 *persist_storage = true; |
| 279 } else { |
| 280 *storage_partition_id = partition_str; |
| 281 *persist_storage = false; |
| 282 } |
| 283 } |
| 284 |
| 285 // static |
| 249 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, | 286 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, |
| 250 bool allow) { | 287 bool allow) { |
| 251 if (allow) { | 288 if (allow) { |
| 252 // Note that |allow| == true means the embedder explicitly allowed the | 289 // Note that |allow| == true means the embedder explicitly allowed the |
| 253 // request. For some requests they might still fail. An example of such | 290 // request. For some requests they might still fail. An example of such |
| 254 // scenario would be: an embedder allows geolocation request but doesn't | 291 // scenario would be: an embedder allows geolocation request but doesn't |
| 255 // have geolocation access on its own. | 292 // have geolocation access on its own. |
| 256 switch (info.permission_type) { | 293 switch (info.permission_type) { |
| 257 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: | 294 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: |
| 258 content::RecordAction( | 295 content::RecordAction( |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 DispatchEvent( | 454 DispatchEvent( |
| 418 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); | 455 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); |
| 419 return true; | 456 return true; |
| 420 } | 457 } |
| 421 | 458 |
| 422 void WebViewGuest::CloseContents(WebContents* source) { | 459 void WebViewGuest::CloseContents(WebContents* source) { |
| 423 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); | 460 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); |
| 424 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); | 461 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); |
| 425 } | 462 } |
| 426 | 463 |
| 427 void WebViewGuest::DidAttach() { | 464 void WebViewGuest::DidAttach(const base::DictionaryValue& extra_params) { |
| 465 std::string src; |
| 466 if (extra_params.GetString("src", &src) && !src.empty()) |
| 467 NavigateGuest(src); |
| 468 |
| 428 if (GetOpener()) { | 469 if (GetOpener()) { |
| 429 // We need to do a navigation here if the target URL has changed between | 470 // We need to do a navigation here if the target URL has changed between |
| 430 // the time the WebContents was created and the time it was attached. | 471 // the time the WebContents was created and the time it was attached. |
| 431 // We also need to do an initial navigation if a RenderView was never | 472 // We also need to do an initial navigation if a RenderView was never |
| 432 // created for the new window in cases where there is no referrer. | 473 // created for the new window in cases where there is no referrer. |
| 433 PendingWindowMap::iterator it = | 474 PendingWindowMap::iterator it = |
| 434 GetOpener()->pending_new_windows_.find(this); | 475 GetOpener()->pending_new_windows_.find(this); |
| 435 if (it != GetOpener()->pending_new_windows_.end()) { | 476 if (it != GetOpener()->pending_new_windows_.end()) { |
| 436 const NewWindowInfo& new_window_info = it->second; | 477 const NewWindowInfo& new_window_info = it->second; |
| 437 NavigateGuest(new_window_info.url.spec()); | 478 NavigateGuest(new_window_info.url.spec()); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 const content::OpenURLParams& params) { | 575 const content::OpenURLParams& params) { |
| 535 GuestViewManager* guest_manager = | 576 GuestViewManager* guest_manager = |
| 536 GuestViewManager::FromBrowserContext(browser_context()); | 577 GuestViewManager::FromBrowserContext(browser_context()); |
| 537 // Allocate a new instance ID for the new guest. | 578 // Allocate a new instance ID for the new guest. |
| 538 int instance_id = guest_manager->GetNextInstanceID(); | 579 int instance_id = guest_manager->GetNextInstanceID(); |
| 539 | 580 |
| 540 // Set the attach params to use the same partition as the opener. | 581 // Set the attach params to use the same partition as the opener. |
| 541 // We pull the partition information from the site's URL, which is of the | 582 // We pull the partition information from the site's URL, which is of the |
| 542 // form guest://site/{persist}?{partition_name}. | 583 // form guest://site/{persist}?{partition_name}. |
| 543 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); | 584 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); |
| 585 scoped_ptr<base::DictionaryValue> create_params(extra_params()->DeepCopy()); |
| 586 const std::string storage_partition_id = |
| 587 GetStoragePartitionIdFromSiteURL(site_url); |
| 588 create_params->SetString(webview::kStoragePartitionId, storage_partition_id); |
| 544 | 589 |
| 545 scoped_ptr<base::DictionaryValue> create_params(extra_params()->DeepCopy()); | |
| 546 const std::string& storage_partition_id = site_url.query(); | |
| 547 bool persist_storage = | |
| 548 site_url.path().find("persist") != std::string::npos; | |
| 549 WebContents* new_guest_web_contents = | 590 WebContents* new_guest_web_contents = |
| 550 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(), | 591 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(), |
| 551 instance_id, | 592 instance_id, |
| 552 storage_partition_id, | |
| 553 persist_storage, | |
| 554 create_params.Pass()); | 593 create_params.Pass()); |
| 555 WebViewGuest* new_guest = | 594 WebViewGuest* new_guest = |
| 556 WebViewGuest::FromWebContents(new_guest_web_contents); | 595 WebViewGuest::FromWebContents(new_guest_web_contents); |
| 557 new_guest->SetOpener(this); | 596 new_guest->SetOpener(this); |
| 558 | 597 |
| 559 // Take ownership of |new_guest|. | 598 // Take ownership of |new_guest|. |
| 560 pending_new_windows_.insert( | 599 pending_new_windows_.insert( |
| 561 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); | 600 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); |
| 562 | 601 |
| 563 // Request permission to show the new window. | 602 // Request permission to show the new window. |
| (...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1375 bool user_gesture, | 1414 bool user_gesture, |
| 1376 content::WebContents* new_contents) { | 1415 content::WebContents* new_contents) { |
| 1377 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); | 1416 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); |
| 1378 if (!guest) | 1417 if (!guest) |
| 1379 return; | 1418 return; |
| 1380 PendingWindowMap::iterator it = pending_new_windows_.find(guest); | 1419 PendingWindowMap::iterator it = pending_new_windows_.find(guest); |
| 1381 if (it == pending_new_windows_.end()) | 1420 if (it == pending_new_windows_.end()) |
| 1382 return; | 1421 return; |
| 1383 const NewWindowInfo& new_window_info = it->second; | 1422 const NewWindowInfo& new_window_info = it->second; |
| 1384 | 1423 |
| 1424 // Retrieve the opener partition info if we have it. |
| 1425 const GURL& site_url = new_contents->GetSiteInstance()->GetSiteURL(); |
| 1426 std::string storage_partition_id = GetStoragePartitionIdFromSiteURL(site_url); |
| 1427 |
| 1385 base::DictionaryValue request_info; | 1428 base::DictionaryValue request_info; |
| 1386 request_info.Set(webview::kInitialHeight, | 1429 request_info.Set(webview::kInitialHeight, |
| 1387 base::Value::CreateIntegerValue(initial_bounds.height())); | 1430 base::Value::CreateIntegerValue(initial_bounds.height())); |
| 1388 request_info.Set(webview::kInitialWidth, | 1431 request_info.Set(webview::kInitialWidth, |
| 1389 base::Value::CreateIntegerValue(initial_bounds.width())); | 1432 base::Value::CreateIntegerValue(initial_bounds.width())); |
| 1390 request_info.Set(webview::kTargetURL, | 1433 request_info.Set(webview::kTargetURL, |
| 1391 base::Value::CreateStringValue(new_window_info.url.spec())); | 1434 base::Value::CreateStringValue(new_window_info.url.spec())); |
| 1392 request_info.Set(webview::kName, | 1435 request_info.Set(webview::kName, |
| 1393 base::Value::CreateStringValue(new_window_info.name)); | 1436 base::Value::CreateStringValue(new_window_info.name)); |
| 1394 request_info.Set(webview::kWindowID, | 1437 request_info.Set(webview::kWindowID, |
| 1395 base::Value::CreateIntegerValue(guest->guest_instance_id())); | 1438 base::Value::CreateIntegerValue(guest->guest_instance_id())); |
| 1439 // We pass in partition info so that window-s created through newwindow |
| 1440 // API can use it to set their partition attribute. |
| 1441 request_info.Set(webview::kStoragePartitionId, |
| 1442 base::Value::CreateStringValue(storage_partition_id)); |
| 1396 request_info.Set(webview::kWindowOpenDisposition, | 1443 request_info.Set(webview::kWindowOpenDisposition, |
| 1397 base::Value::CreateStringValue( | 1444 base::Value::CreateStringValue( |
| 1398 WindowOpenDispositionToString(disposition))); | 1445 WindowOpenDispositionToString(disposition))); |
| 1399 | 1446 |
| 1400 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, | 1447 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, |
| 1401 request_info, | 1448 request_info, |
| 1402 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, | 1449 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, |
| 1403 base::Unretained(this), | 1450 base::Unretained(this), |
| 1404 guest->guest_instance_id()), | 1451 guest->guest_instance_id()), |
| 1405 false /* allowed_by_default */); | 1452 false /* allowed_by_default */); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1437 bool allow, | 1484 bool allow, |
| 1438 const std::string& user_input) { | 1485 const std::string& user_input) { |
| 1439 WebViewGuest* guest = | 1486 WebViewGuest* guest = |
| 1440 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); | 1487 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); |
| 1441 if (!guest) | 1488 if (!guest) |
| 1442 return; | 1489 return; |
| 1443 | 1490 |
| 1444 if (!allow) | 1491 if (!allow) |
| 1445 guest->Destroy(); | 1492 guest->Destroy(); |
| 1446 } | 1493 } |
| OLD | NEW |