| 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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 #if defined(ENABLE_FULL_PRINTING) | 177 #if defined(ENABLE_FULL_PRINTING) |
| 178 printing::PrintViewManager::CreateForWebContents(contents); | 178 printing::PrintViewManager::CreateForWebContents(contents); |
| 179 printing::PrintPreviewMessageHandler::CreateForWebContents(contents); | 179 printing::PrintPreviewMessageHandler::CreateForWebContents(contents); |
| 180 #else | 180 #else |
| 181 printing::PrintViewManagerBasic::CreateForWebContents(contents); | 181 printing::PrintViewManagerBasic::CreateForWebContents(contents); |
| 182 #endif // defined(ENABLE_FULL_PRINTING) | 182 #endif // defined(ENABLE_FULL_PRINTING) |
| 183 #endif // defined(ENABLE_PRINTING) | 183 #endif // defined(ENABLE_PRINTING) |
| 184 PDFTabHelper::CreateForWebContents(contents); | 184 PDFTabHelper::CreateForWebContents(contents); |
| 185 } | 185 } |
| 186 | 186 |
| 187 void ParsePartitionParam(const base::DictionaryValue& create_params, |
| 188 std::string* storage_partition_id, |
| 189 bool* persist_storage) { |
| 190 std::string partition_str; |
| 191 if (!create_params.GetString(webview::kStoragePartitionId, &partition_str)) { |
| 192 return; |
| 193 } |
| 194 |
| 195 // Since the "persist:" prefix is in ASCII, StartsWith will work fine on |
| 196 // UTF-8 encoded |partition_id|. If the prefix is a match, we can safely |
| 197 // remove the prefix without splicing in the middle of a multi-byte codepoint. |
| 198 // We can use the rest of the string as UTF-8 encoded one. |
| 199 if (StartsWithASCII(partition_str, "persist:", true)) { |
| 200 size_t index = partition_str.find(":"); |
| 201 CHECK(index != std::string::npos); |
| 202 // It is safe to do index + 1, since we tested for the full prefix above. |
| 203 *storage_partition_id = partition_str.substr(index + 1); |
| 204 |
| 205 if (storage_partition_id->empty()) { |
| 206 // TODO(lazyboy): Better way to deal with this error. |
| 207 return; |
| 208 } |
| 209 *persist_storage = true; |
| 210 } else { |
| 211 *storage_partition_id = partition_str; |
| 212 *persist_storage = false; |
| 213 } |
| 214 } |
| 215 |
| 216 |
| 187 } // namespace | 217 } // namespace |
| 188 | 218 |
| 189 WebViewGuest::WebViewGuest(int guest_instance_id, | 219 WebViewGuest::WebViewGuest(int guest_instance_id) |
| 190 WebContents* guest_web_contents, | |
| 191 const std::string& embedder_extension_id) | |
| 192 : GuestView<WebViewGuest>(guest_instance_id), | 220 : GuestView<WebViewGuest>(guest_instance_id), |
| 193 script_executor_(new extensions::ScriptExecutor(guest_web_contents, | |
| 194 &script_observers_)), | |
| 195 pending_context_menu_request_id_(0), | 221 pending_context_menu_request_id_(0), |
| 196 next_permission_request_id_(0), | 222 next_permission_request_id_(0), |
| 197 is_overriding_user_agent_(false), | 223 is_overriding_user_agent_(false), |
| 198 main_frame_id_(0), | 224 main_frame_id_(0), |
| 199 chromevox_injected_(false), | 225 chromevox_injected_(false), |
| 200 find_helper_(this), | 226 find_helper_(this), |
| 201 javascript_dialog_helper_(this) { | 227 javascript_dialog_helper_(this) { |
| 202 Init(guest_web_contents, embedder_extension_id); | |
| 203 notification_registrar_.Add( | |
| 204 this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, | |
| 205 content::Source<WebContents>(guest_web_contents)); | |
| 206 | |
| 207 notification_registrar_.Add( | |
| 208 this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, | |
| 209 content::Source<WebContents>(guest_web_contents)); | |
| 210 | |
| 211 #if defined(OS_CHROMEOS) | |
| 212 chromeos::AccessibilityManager* accessibility_manager = | |
| 213 chromeos::AccessibilityManager::Get(); | |
| 214 CHECK(accessibility_manager); | |
| 215 accessibility_subscription_ = accessibility_manager->RegisterCallback( | |
| 216 base::Bind(&WebViewGuest::OnAccessibilityStatusChanged, | |
| 217 base::Unretained(this))); | |
| 218 #endif | |
| 219 | |
| 220 AttachWebViewHelpers(guest_web_contents); | |
| 221 } | 228 } |
| 222 | 229 |
| 223 // static | 230 // static |
| 224 bool WebViewGuest::GetGuestPartitionConfigForSite( | 231 bool WebViewGuest::GetGuestPartitionConfigForSite( |
| 225 const GURL& site, | 232 const GURL& site, |
| 226 std::string* partition_domain, | 233 std::string* partition_domain, |
| 227 std::string* partition_name, | 234 std::string* partition_name, |
| 228 bool* in_memory) { | 235 bool* in_memory) { |
| 229 if (!site.SchemeIs(content::kGuestScheme)) | 236 if (!site.SchemeIs(content::kGuestScheme)) |
| 230 return false; | 237 return false; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 249 // static | 256 // static |
| 250 int WebViewGuest::GetViewInstanceId(WebContents* contents) { | 257 int WebViewGuest::GetViewInstanceId(WebContents* contents) { |
| 251 WebViewGuest* guest = FromWebContents(contents); | 258 WebViewGuest* guest = FromWebContents(contents); |
| 252 if (!guest) | 259 if (!guest) |
| 253 return guestview::kInstanceIDNone; | 260 return guestview::kInstanceIDNone; |
| 254 | 261 |
| 255 return guest->view_instance_id(); | 262 return guest->view_instance_id(); |
| 256 } | 263 } |
| 257 | 264 |
| 258 // static | 265 // static |
| 259 void WebViewGuest::ParsePartitionParam( | |
| 260 const base::DictionaryValue* extra_params, | |
| 261 std::string* storage_partition_id, | |
| 262 bool* persist_storage) { | |
| 263 std::string partition_str; | |
| 264 if (!extra_params->GetString(webview::kStoragePartitionId, &partition_str)) { | |
| 265 return; | |
| 266 } | |
| 267 | |
| 268 // Since the "persist:" prefix is in ASCII, StartsWith will work fine on | |
| 269 // UTF-8 encoded |partition_id|. If the prefix is a match, we can safely | |
| 270 // remove the prefix without splicing in the middle of a multi-byte codepoint. | |
| 271 // We can use the rest of the string as UTF-8 encoded one. | |
| 272 if (StartsWithASCII(partition_str, "persist:", true)) { | |
| 273 size_t index = partition_str.find(":"); | |
| 274 CHECK(index != std::string::npos); | |
| 275 // It is safe to do index + 1, since we tested for the full prefix above. | |
| 276 *storage_partition_id = partition_str.substr(index + 1); | |
| 277 | |
| 278 if (storage_partition_id->empty()) { | |
| 279 // TODO(lazyboy): Better way to deal with this error. | |
| 280 return; | |
| 281 } | |
| 282 *persist_storage = true; | |
| 283 } else { | |
| 284 *storage_partition_id = partition_str; | |
| 285 *persist_storage = false; | |
| 286 } | |
| 287 } | |
| 288 | |
| 289 // static | |
| 290 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, | 266 void WebViewGuest::RecordUserInitiatedUMA(const PermissionResponseInfo& info, |
| 291 bool allow) { | 267 bool allow) { |
| 292 if (allow) { | 268 if (allow) { |
| 293 // Note that |allow| == true means the embedder explicitly allowed the | 269 // Note that |allow| == true means the embedder explicitly allowed the |
| 294 // request. For some requests they might still fail. An example of such | 270 // request. For some requests they might still fail. An example of such |
| 295 // scenario would be: an embedder allows geolocation request but doesn't | 271 // scenario would be: an embedder allows geolocation request but doesn't |
| 296 // have geolocation access on its own. | 272 // have geolocation access on its own. |
| 297 switch (info.permission_type) { | 273 switch (info.permission_type) { |
| 298 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: | 274 case WEB_VIEW_PERMISSION_TYPE_DOWNLOAD: |
| 299 content::RecordAction( | 275 content::RecordAction( |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 // TODO(lazyboy): We need to expose some kind of enum equivalent of | 354 // TODO(lazyboy): We need to expose some kind of enum equivalent of |
| 379 // |command_id| instead of plain integers. | 355 // |command_id| instead of plain integers. |
| 380 item_value->SetInteger(webview::kMenuItemCommandId, | 356 item_value->SetInteger(webview::kMenuItemCommandId, |
| 381 menu_model.GetCommandIdAt(i)); | 357 menu_model.GetCommandIdAt(i)); |
| 382 item_value->SetString(webview::kMenuItemLabel, menu_model.GetLabelAt(i)); | 358 item_value->SetString(webview::kMenuItemLabel, menu_model.GetLabelAt(i)); |
| 383 items->Append(item_value); | 359 items->Append(item_value); |
| 384 } | 360 } |
| 385 return items.Pass(); | 361 return items.Pass(); |
| 386 } | 362 } |
| 387 | 363 |
| 364 void WebViewGuest::CreateWebContents( |
| 365 const std::string& embedder_extension_id, |
| 366 int embedder_render_process_id, |
| 367 const base::DictionaryValue& create_params, |
| 368 const WebContentsCreatedCallback& callback) { |
| 369 content::RenderProcessHost* embedder_render_process_host = |
| 370 content::RenderProcessHost::FromID(embedder_render_process_id); |
| 371 std::string storage_partition_id; |
| 372 bool persist_storage = false; |
| 373 std::string storage_partition_string; |
| 374 ParsePartitionParam(create_params, &storage_partition_id, &persist_storage); |
| 375 // Validate that the partition id coming from the renderer is valid UTF-8, |
| 376 // since we depend on this in other parts of the code, such as FilePath |
| 377 // creation. If the validation fails, treat it as a bad message and kill the |
| 378 // renderer process. |
| 379 if (!base::IsStringUTF8(storage_partition_id)) { |
| 380 content::RecordAction( |
| 381 base::UserMetricsAction("BadMessageTerminate_BPGM")); |
| 382 base::KillProcess( |
| 383 embedder_render_process_host->GetHandle(), |
| 384 content::RESULT_CODE_KILLED_BAD_MESSAGE, false); |
| 385 return; |
| 386 } |
| 387 std::string url_encoded_partition = net::EscapeQueryParamValue( |
| 388 storage_partition_id, false); |
| 389 // The SiteInstance of a given webview tag is based on the fact that it's |
| 390 // a guest process in addition to which platform application the tag |
| 391 // belongs to and what storage partition is in use, rather than the URL |
| 392 // that the tag is being navigated to. |
| 393 GURL guest_site(base::StringPrintf("%s://%s/%s?%s", |
| 394 content::kGuestScheme, |
| 395 embedder_extension_id.c_str(), |
| 396 persist_storage ? "persist" : "", |
| 397 url_encoded_partition.c_str())); |
| 398 |
| 399 // If we already have a webview tag in the same app using the same storage |
| 400 // partition, we should use the same SiteInstance so the existing tag and |
| 401 // the new tag can script each other. |
| 402 GuestViewManager* guest_view_manager = |
| 403 GuestViewManager::FromBrowserContext( |
| 404 embedder_render_process_host->GetBrowserContext()); |
| 405 content::SiteInstance* guest_site_instance = |
| 406 guest_view_manager->GetGuestSiteInstance(guest_site); |
| 407 if (!guest_site_instance) { |
| 408 // Create the SiteInstance in a new BrowsingInstance, which will ensure |
| 409 // that webview tags are also not allowed to send messages across |
| 410 // different partitions. |
| 411 guest_site_instance = content::SiteInstance::CreateForURL( |
| 412 embedder_render_process_host->GetBrowserContext(), guest_site); |
| 413 } |
| 414 WebContents::CreateParams params( |
| 415 embedder_render_process_host->GetBrowserContext(), |
| 416 guest_site_instance); |
| 417 params.guest_delegate = this; |
| 418 callback.Run(WebContents::Create(params)); |
| 419 } |
| 420 |
| 388 void WebViewGuest::DidAttachToEmbedder() { | 421 void WebViewGuest::DidAttachToEmbedder() { |
| 389 std::string name; | 422 std::string name; |
| 390 if (extra_params()->GetString(webview::kName, &name)) { | 423 if (extra_params()->GetString(webview::kName, &name)) { |
| 391 // If the guest window's name is empty, then the WebView tag's name is | 424 // If the guest window's name is empty, then the WebView tag's name is |
| 392 // assigned. Otherwise, the guest window's name takes precedence over the | 425 // assigned. Otherwise, the guest window's name takes precedence over the |
| 393 // WebView tag's name. | 426 // WebView tag's name. |
| 394 if (name_.empty()) | 427 if (name_.empty()) |
| 395 name_ = name; | 428 name_ = name; |
| 396 } | 429 } |
| 397 ReportFrameNameChange(name_); | 430 ReportFrameNameChange(name_); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 422 } else { | 455 } else { |
| 423 NOTREACHED(); | 456 NOTREACHED(); |
| 424 } | 457 } |
| 425 | 458 |
| 426 // Once a new guest is attached to the DOM of the embedder page, then the | 459 // Once a new guest is attached to the DOM of the embedder page, then the |
| 427 // lifetime of the new guest is no longer managed by the opener guest. | 460 // lifetime of the new guest is no longer managed by the opener guest. |
| 428 GetOpener()->pending_new_windows_.erase(this); | 461 GetOpener()->pending_new_windows_.erase(this); |
| 429 } | 462 } |
| 430 } | 463 } |
| 431 | 464 |
| 465 void WebViewGuest::DidInitialize() { |
| 466 script_executor_.reset(new extensions::ScriptExecutor(guest_web_contents(), |
| 467 &script_observers_)); |
| 468 |
| 469 notification_registrar_.Add( |
| 470 this, content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, |
| 471 content::Source<WebContents>(guest_web_contents())); |
| 472 |
| 473 notification_registrar_.Add( |
| 474 this, content::NOTIFICATION_RESOURCE_RECEIVED_REDIRECT, |
| 475 content::Source<WebContents>(guest_web_contents())); |
| 476 |
| 477 #if defined(OS_CHROMEOS) |
| 478 chromeos::AccessibilityManager* accessibility_manager = |
| 479 chromeos::AccessibilityManager::Get(); |
| 480 CHECK(accessibility_manager); |
| 481 accessibility_subscription_ = accessibility_manager->RegisterCallback( |
| 482 base::Bind(&WebViewGuest::OnAccessibilityStatusChanged, |
| 483 base::Unretained(this))); |
| 484 #endif |
| 485 |
| 486 AttachWebViewHelpers(guest_web_contents()); |
| 487 } |
| 488 |
| 489 |
| 432 void WebViewGuest::DidStopLoading() { | 490 void WebViewGuest::DidStopLoading() { |
| 433 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); | 491 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); |
| 434 DispatchEvent(new GuestViewBase::Event(webview::kEventLoadStop, args.Pass())); | 492 DispatchEvent(new GuestViewBase::Event(webview::kEventLoadStop, args.Pass())); |
| 435 } | 493 } |
| 436 | 494 |
| 437 void WebViewGuest::EmbedderDestroyed() { | 495 void WebViewGuest::EmbedderDestroyed() { |
| 438 // TODO(fsamuel): WebRequest event listeners for <webview> should survive | 496 // TODO(fsamuel): WebRequest event listeners for <webview> should survive |
| 439 // reparenting of a <webview> within a single embedder. Right now, we keep | 497 // reparenting of a <webview> within a single embedder. Right now, we keep |
| 440 // around the browser state for the listener for the lifetime of the embedder. | 498 // around the browser state for the listener for the lifetime of the embedder. |
| 441 // Ideally, the lifetime of the listeners should match the lifetime of the | 499 // Ideally, the lifetime of the listeners should match the lifetime of the |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 566 const std::string& name) { | 624 const std::string& name) { |
| 567 if (!is_top_level) | 625 if (!is_top_level) |
| 568 return; | 626 return; |
| 569 | 627 |
| 570 if (name_ == name) | 628 if (name_ == name) |
| 571 return; | 629 return; |
| 572 | 630 |
| 573 ReportFrameNameChange(name); | 631 ReportFrameNameChange(name); |
| 574 } | 632 } |
| 575 | 633 |
| 576 WebViewGuest* WebViewGuest::CreateNewGuestWindow( | 634 WebViewGuest* WebViewGuest::CreateNewGuestWebViewWindow( |
| 577 const content::OpenURLParams& params) { | 635 const content::OpenURLParams& params) { |
| 578 GuestViewManager* guest_manager = | 636 GuestViewManager* guest_manager = |
| 579 GuestViewManager::FromBrowserContext(browser_context()); | 637 GuestViewManager::FromBrowserContext(browser_context()); |
| 580 // Allocate a new instance ID for the new guest. | |
| 581 int instance_id = guest_manager->GetNextInstanceID(); | |
| 582 | |
| 583 // Set the attach params to use the same partition as the opener. | 638 // Set the attach params to use the same partition as the opener. |
| 584 // We pull the partition information from the site's URL, which is of the | 639 // We pull the partition information from the site's URL, which is of the |
| 585 // form guest://site/{persist}?{partition_name}. | 640 // form guest://site/{persist}?{partition_name}. |
| 586 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); | 641 const GURL& site_url = guest_web_contents()->GetSiteInstance()->GetSiteURL(); |
| 587 scoped_ptr<base::DictionaryValue> create_params(extra_params()->DeepCopy()); | |
| 588 const std::string storage_partition_id = | 642 const std::string storage_partition_id = |
| 589 GetStoragePartitionIdFromSiteURL(site_url); | 643 GetStoragePartitionIdFromSiteURL(site_url); |
| 590 create_params->SetString(webview::kStoragePartitionId, storage_partition_id); | 644 base::DictionaryValue create_params; |
| 645 create_params.SetString(webview::kStoragePartitionId, storage_partition_id); |
| 591 | 646 |
| 592 WebContents* new_guest_web_contents = | 647 WebContents* new_guest_web_contents = |
| 593 guest_manager->CreateGuest(guest_web_contents()->GetSiteInstance(), | 648 guest_manager->CreateGuest( |
| 594 instance_id, | 649 WebViewGuest::Type, |
| 595 create_params.Pass()); | 650 embedder_extension_id(), |
| 651 embedder_web_contents()->GetRenderProcessHost()->GetID(), |
| 652 create_params); |
| 596 WebViewGuest* new_guest = | 653 WebViewGuest* new_guest = |
| 597 WebViewGuest::FromWebContents(new_guest_web_contents); | 654 WebViewGuest::FromWebContents(new_guest_web_contents); |
| 598 new_guest->SetOpener(this); | 655 new_guest->SetOpener(this); |
| 599 | 656 |
| 600 // Take ownership of |new_guest|. | 657 // Take ownership of |new_guest|. |
| 601 pending_new_windows_.insert( | 658 pending_new_windows_.insert( |
| 602 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); | 659 std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); |
| 603 | 660 |
| 604 // Request permission to show the new window. | 661 // Request permission to show the new window. |
| 605 RequestNewWindowPermission(params.disposition, gfx::Rect(), | 662 RequestNewWindowPermission(params.disposition, gfx::Rect(), |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1117 WebContents* web_contents) { | 1174 WebContents* web_contents) { |
| 1118 content::BrowserThread::PostTask( | 1175 content::BrowserThread::PostTask( |
| 1119 content::BrowserThread::IO, FROM_HERE, | 1176 content::BrowserThread::IO, FROM_HERE, |
| 1120 base::Bind( | 1177 base::Bind( |
| 1121 &ExtensionRendererState::RemoveWebView, | 1178 &ExtensionRendererState::RemoveWebView, |
| 1122 base::Unretained(ExtensionRendererState::GetInstance()), | 1179 base::Unretained(ExtensionRendererState::GetInstance()), |
| 1123 web_contents->GetRenderProcessHost()->GetID(), | 1180 web_contents->GetRenderProcessHost()->GetID(), |
| 1124 web_contents->GetRoutingID())); | 1181 web_contents->GetRoutingID())); |
| 1125 } | 1182 } |
| 1126 | 1183 |
| 1184 content::WebContents* WebViewGuest::CreateNewGuestWindow( |
| 1185 const content::WebContents::CreateParams& create_params) { |
| 1186 GuestViewManager* guest_manager = |
| 1187 GuestViewManager::FromBrowserContext(browser_context()); |
| 1188 return guest_manager->CreateGuestWithWebContentsParams( |
| 1189 WebViewGuest::Type, |
| 1190 embedder_extension_id(), |
| 1191 embedder_web_contents()->GetRenderProcessHost()->GetID(), |
| 1192 create_params); |
| 1193 } |
| 1194 |
| 1127 void WebViewGuest::SizeChanged(const gfx::Size& old_size, | 1195 void WebViewGuest::SizeChanged(const gfx::Size& old_size, |
| 1128 const gfx::Size& new_size) { | 1196 const gfx::Size& new_size) { |
| 1129 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); | 1197 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue()); |
| 1130 args->SetInteger(webview::kOldHeight, old_size.height()); | 1198 args->SetInteger(webview::kOldHeight, old_size.height()); |
| 1131 args->SetInteger(webview::kOldWidth, old_size.width()); | 1199 args->SetInteger(webview::kOldWidth, old_size.width()); |
| 1132 args->SetInteger(webview::kNewHeight, new_size.height()); | 1200 args->SetInteger(webview::kNewHeight, new_size.height()); |
| 1133 args->SetInteger(webview::kNewWidth, new_size.width()); | 1201 args->SetInteger(webview::kNewWidth, new_size.width()); |
| 1134 DispatchEvent( | 1202 DispatchEvent( |
| 1135 new GuestViewBase::Event(webview::kEventSizeChanged, args.Pass())); | 1203 new GuestViewBase::Event(webview::kEventSizeChanged, args.Pass())); |
| 1136 } | 1204 } |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1470 new_window_info.changed = new_window_info.url != info.url; | 1538 new_window_info.changed = new_window_info.url != info.url; |
| 1471 it->second = new_window_info; | 1539 it->second = new_window_info; |
| 1472 return NULL; | 1540 return NULL; |
| 1473 } | 1541 } |
| 1474 if (params.disposition == CURRENT_TAB) { | 1542 if (params.disposition == CURRENT_TAB) { |
| 1475 // This can happen for cross-site redirects. | 1543 // This can happen for cross-site redirects. |
| 1476 LoadURLWithParams(params.url, params.referrer, params.transition, source); | 1544 LoadURLWithParams(params.url, params.referrer, params.transition, source); |
| 1477 return source; | 1545 return source; |
| 1478 } | 1546 } |
| 1479 | 1547 |
| 1480 return CreateNewGuestWindow(params)->guest_web_contents(); | 1548 return CreateNewGuestWebViewWindow(params)->guest_web_contents(); |
| 1481 } | 1549 } |
| 1482 | 1550 |
| 1483 void WebViewGuest::WebContentsCreated(WebContents* source_contents, | 1551 void WebViewGuest::WebContentsCreated(WebContents* source_contents, |
| 1484 int opener_render_frame_id, | 1552 int opener_render_frame_id, |
| 1485 const base::string16& frame_name, | 1553 const base::string16& frame_name, |
| 1486 const GURL& target_url, | 1554 const GURL& target_url, |
| 1487 content::WebContents* new_contents) { | 1555 content::WebContents* new_contents) { |
| 1488 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); | 1556 WebViewGuest* guest = WebViewGuest::FromWebContents(new_contents); |
| 1489 CHECK(guest); | 1557 CHECK(guest); |
| 1490 guest->SetOpener(this); | 1558 guest->SetOpener(this); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 base::DictionaryValue request_info; | 1597 base::DictionaryValue request_info; |
| 1530 request_info.Set(webview::kInitialHeight, | 1598 request_info.Set(webview::kInitialHeight, |
| 1531 base::Value::CreateIntegerValue(initial_bounds.height())); | 1599 base::Value::CreateIntegerValue(initial_bounds.height())); |
| 1532 request_info.Set(webview::kInitialWidth, | 1600 request_info.Set(webview::kInitialWidth, |
| 1533 base::Value::CreateIntegerValue(initial_bounds.width())); | 1601 base::Value::CreateIntegerValue(initial_bounds.width())); |
| 1534 request_info.Set(webview::kTargetURL, | 1602 request_info.Set(webview::kTargetURL, |
| 1535 base::Value::CreateStringValue(new_window_info.url.spec())); | 1603 base::Value::CreateStringValue(new_window_info.url.spec())); |
| 1536 request_info.Set(webview::kName, | 1604 request_info.Set(webview::kName, |
| 1537 base::Value::CreateStringValue(new_window_info.name)); | 1605 base::Value::CreateStringValue(new_window_info.name)); |
| 1538 request_info.Set(webview::kWindowID, | 1606 request_info.Set(webview::kWindowID, |
| 1539 base::Value::CreateIntegerValue(guest->guest_instance_id())); | 1607 base::Value::CreateIntegerValue( |
| 1608 guest->GetGuestInstanceID())); |
| 1540 // We pass in partition info so that window-s created through newwindow | 1609 // We pass in partition info so that window-s created through newwindow |
| 1541 // API can use it to set their partition attribute. | 1610 // API can use it to set their partition attribute. |
| 1542 request_info.Set(webview::kStoragePartitionId, | 1611 request_info.Set(webview::kStoragePartitionId, |
| 1543 base::Value::CreateStringValue(storage_partition_id)); | 1612 base::Value::CreateStringValue(storage_partition_id)); |
| 1544 request_info.Set(webview::kWindowOpenDisposition, | 1613 request_info.Set(webview::kWindowOpenDisposition, |
| 1545 base::Value::CreateStringValue( | 1614 base::Value::CreateStringValue( |
| 1546 WindowOpenDispositionToString(disposition))); | 1615 WindowOpenDispositionToString(disposition))); |
| 1547 | 1616 |
| 1548 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, | 1617 RequestPermission(WEB_VIEW_PERMISSION_TYPE_NEW_WINDOW, |
| 1549 request_info, | 1618 request_info, |
| 1550 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, | 1619 base::Bind(&WebViewGuest::OnWebViewNewWindowResponse, |
| 1551 base::Unretained(this), | 1620 base::Unretained(this), |
| 1552 guest->guest_instance_id()), | 1621 guest->GetGuestInstanceID()), |
| 1553 false /* allowed_by_default */); | 1622 false /* allowed_by_default */); |
| 1554 } | 1623 } |
| 1555 | 1624 |
| 1556 void WebViewGuest::DestroyUnattachedWindows() { | 1625 void WebViewGuest::DestroyUnattachedWindows() { |
| 1557 // Destroy() reaches in and removes the WebViewGuest from its opener's | 1626 // Destroy() reaches in and removes the WebViewGuest from its opener's |
| 1558 // pending_new_windows_ set. To avoid mutating the set while iterating, we | 1627 // pending_new_windows_ set. To avoid mutating the set while iterating, we |
| 1559 // create a copy of the pending new windows set and iterate over the copy. | 1628 // create a copy of the pending new windows set and iterate over the copy. |
| 1560 PendingWindowMap pending_new_windows(pending_new_windows_); | 1629 PendingWindowMap pending_new_windows(pending_new_windows_); |
| 1561 // Clean up unattached new windows opened by this guest. | 1630 // Clean up unattached new windows opened by this guest. |
| 1562 for (PendingWindowMap::const_iterator it = pending_new_windows.begin(); | 1631 for (PendingWindowMap::const_iterator it = pending_new_windows.begin(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1585 bool allow, | 1654 bool allow, |
| 1586 const std::string& user_input) { | 1655 const std::string& user_input) { |
| 1587 WebViewGuest* guest = | 1656 WebViewGuest* guest = |
| 1588 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); | 1657 WebViewGuest::From(embedder_render_process_id(), new_window_instance_id); |
| 1589 if (!guest) | 1658 if (!guest) |
| 1590 return; | 1659 return; |
| 1591 | 1660 |
| 1592 if (!allow) | 1661 if (!allow) |
| 1593 guest->Destroy(); | 1662 guest->Destroy(); |
| 1594 } | 1663 } |
| OLD | NEW |