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 |