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(const std::string& partition_str, |
| 232 std::string* storage_partition_id, |
| 233 bool* persist_storage) { |
| 234 // Since the "persist:" prefix is in ASCII, StartsWith will work fine on |
| 235 // UTF-8 encoded |partition_id|. If the prefix is a match, we can safely |
| 236 // remove the prefix without splicing in the middle of a multi-byte codepoint. |
| 237 // We can use the rest of the string as UTF-8 encoded one. |
| 238 if (StartsWithASCII(partition_str, "persist:", true)) { |
| 239 size_t index = partition_str.find(":"); |
| 240 CHECK(index != std::string::npos); |
| 241 // It is safe to do index + 1, since we tested for the full prefix above. |
| 242 *storage_partition_id = partition_str.substr(index + 1); |
| 243 |
| 244 if (storage_partition_id->empty()) { |
| 245 // TODO(lazyboy): Better way to deal with this error. |
| 246 return; |
| 247 } |
| 248 *persist_storage = true; |
| 249 } else { |
| 250 *storage_partition_id = partition_str; |
| 251 *persist_storage = false; |
| 252 } |
| 253 } |
| 254 |
| 255 // static |
225 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, | 256 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, |
226 bool allow) { | 257 bool allow) { |
227 if (allow) { | 258 if (allow) { |
228 // Note that |allow| == true means the embedder explicitly allowed the | 259 // Note that |allow| == true means the embedder explicitly allowed the |
229 // request. For some requests they might still fail. An example of such | 260 // request. For some requests they might still fail. An example of such |
230 // scenario would be: an embedder allows geolocation request but doesn't | 261 // scenario would be: an embedder allows geolocation request but doesn't |
231 // have geolocation access on its own. | 262 // have geolocation access on its own. |
232 switch (info.permission_type) { | 263 switch (info.permission_type) { |
233 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: | 264 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: |
234 content::RecordAction( | 265 content::RecordAction( |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 DispatchEvent( | 408 DispatchEvent( |
378 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); | 409 new GuestViewBase::Event(webview::kEventConsoleMessage, args.Pass())); |
379 return true; | 410 return true; |
380 } | 411 } |
381 | 412 |
382 void WebViewGuest::CloseContents(WebContents* source) { | 413 void WebViewGuest::CloseContents(WebContents* source) { |
383 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); | 414 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); |
384 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); | 415 DispatchEvent(new GuestViewBase::Event(webview::kEventClose, args.Pass())); |
385 } | 416 } |
386 | 417 |
387 void WebViewGuest::DidAttach() { | 418 void WebViewGuest::DidAttach(const base::DictionaryValue& extra_params) { |
| 419 std::string src; |
| 420 if (extra_params.GetString("src", &src) && !src.empty()) |
| 421 NavigateGuest(src); |
| 422 |
388 if (GetOpener()) { | 423 if (GetOpener()) { |
389 // We need to do a navigation here if the target URL has changed between | 424 // 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. | 425 // 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 | 426 // 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. | 427 // created for the new window in cases where there is no referrer. |
393 PendingWindowMap::iterator it = | 428 PendingWindowMap::iterator it = |
394 GetOpener()->pending_new_windows_.find(this); | 429 GetOpener()->pending_new_windows_.find(this); |
395 if (it != GetOpener()->pending_new_windows_.end()) { | 430 if (it != GetOpener()->pending_new_windows_.end()) { |
396 const NewWindowInfo& new_window_info = it->second; | 431 const NewWindowInfo& new_window_info = it->second; |
397 NavigateGuest(new_window_info.url.spec()); | 432 NavigateGuest(new_window_info.url.spec()); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 const content::OpenURLParams& params) { | 529 const content::OpenURLParams& params) { |
495 GuestViewManager* guest_manager = | 530 GuestViewManager* guest_manager = |
496 GuestViewManager::FromBrowserContext(browser_context()); | 531 GuestViewManager::FromBrowserContext(browser_context()); |
497 // Allocate a new instance ID for the new guest. | 532 // Allocate a new instance ID for the new guest. |
498 int instance_id = guest_manager->GetNextInstanceID(); | 533 int instance_id = guest_manager->GetNextInstanceID(); |
499 | 534 |
500 // Set the attach params to use the same partition as the opener. | 535 // 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 | 536 // We pull the partition information from the site's URL, which is of the |
502 // form guest://site/{persist}?{partition_name}. | 537 // form guest://site/{persist}?{partition_name}. |
503 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); | 538 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); |
| 539 scoped_ptr<base::DictionaryValue> create_params(extra_params()->DeepCopy()); |
| 540 const std::string storage_partition_id = |
| 541 GetStoragePartitionIdFromSiteURL(site_url); |
| 542 create_params->SetString(guestview::kStoragePartitionId, |
| 543 storage_partition_id); |
504 | 544 |
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 = | 545 WebContents* new_guest_web_contents = |
510 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(), | 546 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(), |
511 instance_id, | 547 instance_id, |
512 storage_partition_id, | |
513 persist_storage, | |
514 create_params.Pass()); | 548 create_params.Pass()); |
515 WebViewGuest* new_guest = | 549 WebViewGuest* new_guest = |
516 WebViewGuest::FromWebContents(new_guest_web_contents); | 550 WebViewGuest::FromWebContents(new_guest_web_contents); |
517 new_guest->SetOpener(this); | 551 new_guest->SetOpener(this); |
518 | 552 |
519 // Take ownership of |new_guest|. | 553 // Take ownership of |new_guest|. |
520 pending_new_windows_.insert( | 554 pending_new_windows_.insert( |
521 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); | 555 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); |
522 | 556 |
523 // Request permission to show the new window. | 557 // Request permission to show the new window. |
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1353 bool user_gesture, | 1387 bool user_gesture, |
1354 content::WebContents* new_contents) { | 1388 content::WebContents* new_contents) { |
1355 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); | 1389 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); |
1356 if (!guest) | 1390 if (!guest) |
1357 return; | 1391 return; |
1358 PendingWindowMap::iterator it = pending_new_windows_.find(guest); | 1392 PendingWindowMap::iterator it = pending_new_windows_.find(guest); |
1359 if (it == pending_new_windows_.end()) | 1393 if (it == pending_new_windows_.end()) |
1360 return; | 1394 return; |
1361 const NewWindowInfo& new_window_info = it->second; | 1395 const NewWindowInfo& new_window_info = it->second; |
1362 | 1396 |
| 1397 // Retrieve the opener partition info if we have it. |
| 1398 const GURL& site_url = new_contents->GetSiteInstance()->GetSiteURL(); |
| 1399 std::string storage_partition_id = GetStoragePartitionIdFromSiteURL(site_url); |
| 1400 |
1363 base::DictionaryValue request_info; | 1401 base::DictionaryValue request_info; |
1364 request_info.Set(webview::kInitialHeight, | 1402 request_info.Set(webview::kInitialHeight, |
1365 base::Value::CreateIntegerValue(initial_bounds.height())); | 1403 base::Value::CreateIntegerValue(initial_bounds.height())); |
1366 request_info.Set(webview::kInitialWidth, | 1404 request_info.Set(webview::kInitialWidth, |
1367 base::Value::CreateIntegerValue(initial_bounds.width())); | 1405 base::Value::CreateIntegerValue(initial_bounds.width())); |
1368 request_info.Set(webview::kTargetURL, | 1406 request_info.Set(webview::kTargetURL, |
1369 base::Value::CreateStringValue(new_window_info.url.spec())); | 1407 base::Value::CreateStringValue(new_window_info.url.spec())); |
1370 request_info.Set(webview::kName, | 1408 request_info.Set(webview::kName, |
1371 base::Value::CreateStringValue(new_window_info.name)); | 1409 base::Value::CreateStringValue(new_window_info.name)); |
1372 request_info.Set(webview::kWindowID, | 1410 request_info.Set(webview::kWindowID, |
1373 base::Value::CreateIntegerValue(guest->guest_instance_id())); | 1411 base::Value::CreateIntegerValue(guest->guest_instance_id())); |
| 1412 // We pass in partition info so that window-s created through newwindow |
| 1413 // API can use it to set their partition attribute. |
| 1414 request_info.Set(guestview::kStoragePartitionId, |
| 1415 base::Value::CreateStringValue(storage_partition_id)); |
1374 request_info.Set(webview::kWindowOpenDisposition, | 1416 request_info.Set(webview::kWindowOpenDisposition, |
1375 base::Value::CreateStringValue( | 1417 base::Value::CreateStringValue( |
1376 WindowOpenDispositionToString(disposition))); | 1418 WindowOpenDispositionToString(disposition))); |
1377 | 1419 |
1378 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, | 1420 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, |
1379 request_info, | 1421 request_info, |
1380 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, | 1422 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, |
1381 base::Unretained(this), | 1423 base::Unretained(this), |
1382 guest->guest_instance_id()), | 1424 guest->guest_instance_id()), |
1383 false /* allowed_by_default */); | 1425 false /* allowed_by_default */); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1415 bool allow, | 1457 bool allow, |
1416 const std::string& user_input) { | 1458 const std::string& user_input) { |
1417 WebViewGuest* guest = | 1459 WebViewGuest* guest = |
1418 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); | 1460 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); |
1419 if (!guest) | 1461 if (!guest) |
1420 return; | 1462 return; |
1421 | 1463 |
1422 if (!allow) | 1464 if (!allow) |
1423 guest->Destroy(); | 1465 guest->Destroy(); |
1424 } | 1466 } |
OLD | NEW |