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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 DispatchEvent( | 431 DispatchEvent( |
394 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); | 432 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); |
395 return true; | 433 return true; |
396 } | 434 } |
397 | 435 |
398 void WebViewGuest::CloseContents(WebContents* source) { | 436 void WebViewGuest::CloseContents(WebContents* source) { |
399 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); | 437 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); |
400 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); | 438 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); |
401 } | 439 } |
402 | 440 |
403 void WebViewGuest::DidAttach() { | 441 void WebViewGuest::DidAttach(const base::DictionaryValue& extra_params) { |
| 442 std::string src; |
| 443 if (extra_params.GetString("src", &src) && !src.empty()) |
| 444 NavigateGuest(src); |
| 445 |
404 if (GetOpener()) { | 446 if (GetOpener()) { |
405 // We need to do a navigation here if the target URL has changed between | 447 // We need to do a navigation here if the target URL has changed between |
406 // the time the WebContents was created and the time it was attached. | 448 // the time the WebContents was created and the time it was attached. |
407 // We also need to do an initial navigation if a RenderView was never | 449 // We also need to do an initial navigation if a RenderView was never |
408 // created for the new window in cases where there is no referrer. | 450 // created for the new window in cases where there is no referrer. |
409 PendingWindowMap::iterator it = | 451 PendingWindowMap::iterator it = |
410 GetOpener()->pending_new_windows_.find(this); | 452 GetOpener()->pending_new_windows_.find(this); |
411 if (it != GetOpener()->pending_new_windows_.end()) { | 453 if (it != GetOpener()->pending_new_windows_.end()) { |
412 const NewWindowInfo& new_window_info = it->second; | 454 const NewWindowInfo& new_window_info = it->second; |
413 NavigateGuest(new_window_info.url.spec()); | 455 NavigateGuest(new_window_info.url.spec()); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 const content::OpenURLParams& params) { | 552 const content::OpenURLParams& params) { |
511 GuestViewManager* guest_manager = | 553 GuestViewManager* guest_manager = |
512 GuestViewManager::FromBrowserContext(browser_context()); | 554 GuestViewManager::FromBrowserContext(browser_context()); |
513 // Allocate a new instance ID for the new guest. | 555 // Allocate a new instance ID for the new guest. |
514 int instance_id = guest_manager->GetNextInstanceID(); | 556 int instance_id = guest_manager->GetNextInstanceID(); |
515 | 557 |
516 // Set the attach params to use the same partition as the opener. | 558 // Set the attach params to use the same partition as the opener. |
517 // We pull the partition information from the site's URL, which is of the | 559 // We pull the partition information from the site's URL, which is of the |
518 // form guest://site/{persist}?{partition_name}. | 560 // form guest://site/{persist}?{partition_name}. |
519 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); | 561 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); |
| 562 scoped_ptr<base::DictionaryValue> create_params(extra_params()->DeepCopy()); |
| 563 const std::string storage_partition_id = |
| 564 GetStoragePartitionIdFromSiteURL(site_url); |
| 565 create_params->SetString(webview::kStoragePartitionId, storage_partition_id); |
520 | 566 |
521 scoped_ptr<base::DictionaryValue> create_params(extra_params()->DeepCopy()); | |
522 const std::string& storage_partition_id = site_url.query(); | |
523 bool persist_storage = | |
524 site_url.path().find("persist") != std::string::npos; | |
525 WebContents* new_guest_web_contents = | 567 WebContents* new_guest_web_contents = |
526 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(), | 568 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(), |
527 instance_id, | 569 instance_id, |
528 storage_partition_id, | |
529 persist_storage, | |
530 create_params.Pass()); | 570 create_params.Pass()); |
531 WebViewGuest* new_guest = | 571 WebViewGuest* new_guest = |
532 WebViewGuest::FromWebContents(new_guest_web_contents); | 572 WebViewGuest::FromWebContents(new_guest_web_contents); |
533 new_guest->SetOpener(this); | 573 new_guest->SetOpener(this); |
534 | 574 |
535 // Take ownership of |new_guest|. | 575 // Take ownership of |new_guest|. |
536 pending_new_windows_.insert( | 576 pending_new_windows_.insert( |
537 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); | 577 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); |
538 | 578 |
539 // Request permission to show the new window. | 579 // Request permission to show the new window. |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1351 bool user_gesture, | 1391 bool user_gesture, |
1352 content::WebContents* new_contents) { | 1392 content::WebContents* new_contents) { |
1353 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); | 1393 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); |
1354 if (!guest) | 1394 if (!guest) |
1355 return; | 1395 return; |
1356 PendingWindowMap::iterator it = pending_new_windows_.find(guest); | 1396 PendingWindowMap::iterator it = pending_new_windows_.find(guest); |
1357 if (it == pending_new_windows_.end()) | 1397 if (it == pending_new_windows_.end()) |
1358 return; | 1398 return; |
1359 const NewWindowInfo& new_window_info = it->second; | 1399 const NewWindowInfo& new_window_info = it->second; |
1360 | 1400 |
| 1401 // Retrieve the opener partition info if we have it. |
| 1402 const GURL& site_url = new_contents->GetSiteInstance()->GetSiteURL(); |
| 1403 std::string storage_partition_id = GetStoragePartitionIdFromSiteURL(site_url); |
| 1404 |
1361 base::DictionaryValue request_info; | 1405 base::DictionaryValue request_info; |
1362 request_info.Set(webview::kInitialHeight, | 1406 request_info.Set(webview::kInitialHeight, |
1363 base::Value::CreateIntegerValue(initial_bounds.height())); | 1407 base::Value::CreateIntegerValue(initial_bounds.height())); |
1364 request_info.Set(webview::kInitialWidth, | 1408 request_info.Set(webview::kInitialWidth, |
1365 base::Value::CreateIntegerValue(initial_bounds.width())); | 1409 base::Value::CreateIntegerValue(initial_bounds.width())); |
1366 request_info.Set(webview::kTargetURL, | 1410 request_info.Set(webview::kTargetURL, |
1367 base::Value::CreateStringValue(new_window_info.url.spec())); | 1411 base::Value::CreateStringValue(new_window_info.url.spec())); |
1368 request_info.Set(webview::kName, | 1412 request_info.Set(webview::kName, |
1369 base::Value::CreateStringValue(new_window_info.name)); | 1413 base::Value::CreateStringValue(new_window_info.name)); |
1370 request_info.Set(webview::kWindowID, | 1414 request_info.Set(webview::kWindowID, |
1371 base::Value::CreateIntegerValue(guest->guest_instance_id())); | 1415 base::Value::CreateIntegerValue(guest->guest_instance_id())); |
| 1416 // We pass in partition info so that window-s created through newwindow |
| 1417 // API can use it to set their partition attribute. |
| 1418 request_info.Set(webview::kStoragePartitionId, |
| 1419 base::Value::CreateStringValue(storage_partition_id)); |
1372 request_info.Set(webview::kWindowOpenDisposition, | 1420 request_info.Set(webview::kWindowOpenDisposition, |
1373 base::Value::CreateStringValue( | 1421 base::Value::CreateStringValue( |
1374 WindowOpenDispositionToString(disposition))); | 1422 WindowOpenDispositionToString(disposition))); |
1375 | 1423 |
1376 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, | 1424 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, |
1377 request_info, | 1425 request_info, |
1378 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, | 1426 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, |
1379 base::Unretained(this), | 1427 base::Unretained(this), |
1380 guest->guest_instance_id()), | 1428 guest->guest_instance_id()), |
1381 false /* allowed_by_default */); | 1429 false /* allowed_by_default */); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1413 bool allow, | 1461 bool allow, |
1414 const std::string& user_input) { | 1462 const std::string& user_input) { |
1415 WebViewGuest* guest = | 1463 WebViewGuest* guest = |
1416 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); | 1464 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); |
1417 if (!guest) | 1465 if (!guest) |
1418 return; | 1466 return; |
1419 | 1467 |
1420 if (!allow) | 1468 if (!allow) |
1421 guest->Destroy(); | 1469 guest->Destroy(); |
1422 } | 1470 } |
OLD | NEW |