Chromium Code Reviews| Index: content/browser/browser_plugin/browser_plugin_guest.cc |
| diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc |
| index b1ca054488c5db69d3f66f25cf398be5dcdb4779..c0bee728b569b74ad552fbd4c6995153fab6cb09 100644 |
| --- a/content/browser/browser_plugin/browser_plugin_guest.cc |
| +++ b/content/browser/browser_plugin/browser_plugin_guest.cc |
| @@ -55,103 +55,7 @@ namespace content { |
| // static |
| BrowserPluginHostFactory* BrowserPluginGuest::factory_ = NULL; |
| -// Parent class for the various types of permission requests, each of which |
| -// should be able to handle the response to their permission request. |
| -class BrowserPluginGuest::PermissionRequest : |
| - public base::RefCounted<BrowserPluginGuest::PermissionRequest> { |
| - public: |
| - void Respond(bool should_allow, const std::string& user_input) { |
| - if (!guest_) |
| - return; |
| - RespondImpl(should_allow, user_input); |
| - } |
| - virtual bool AllowedByDefault() const { |
| - return false; |
| - } |
| - protected: |
| - explicit PermissionRequest(const base::WeakPtr<BrowserPluginGuest>& guest) |
| - : guest_(guest) { |
| - RecordAction( |
| - base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest")); |
| - } |
| - virtual ~PermissionRequest() {} |
| - |
| - virtual void RespondImpl(bool should_allow, |
| - const std::string& user_input) = 0; |
| - // Friend RefCounted so that the dtor can be non-public. |
| - friend class base::RefCounted<BrowserPluginGuest::PermissionRequest>; |
| - |
| - base::WeakPtr<BrowserPluginGuest> guest_; |
| -}; |
| - |
| -class BrowserPluginGuest::NewWindowRequest : public PermissionRequest { |
| - public: |
| - NewWindowRequest(const base::WeakPtr<BrowserPluginGuest>& guest, |
| - int instance_id) |
| - : PermissionRequest(guest), |
| - instance_id_(instance_id) { |
| - RecordAction( |
| - base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.NewWindow")); |
| - } |
| - |
| - virtual void RespondImpl(bool should_allow, |
| - const std::string& user_input) OVERRIDE { |
| - int embedder_render_process_id = |
| - guest_->embedder_web_contents()->GetRenderProcessHost()->GetID(); |
| - guest_->GetBrowserPluginGuestManager()-> |
| - MaybeGetGuestByInstanceIDOrKill( |
| - instance_id_, |
| - embedder_render_process_id, |
| - base::Bind(&BrowserPluginGuest::NewWindowRequest::RespondInternal, |
| - base::Unretained(this), |
| - should_allow)); |
| - } |
| - |
| - private: |
| - virtual ~NewWindowRequest() {} |
| - |
| - void RespondInternal(bool should_allow, |
| - WebContents* guest_web_contents) { |
| - if (!guest_web_contents) { |
| - VLOG(0) << "Guest not found. Instance ID: " << instance_id_; |
| - return; |
| - } |
| - |
| - BrowserPluginGuest* guest = |
| - static_cast<WebContentsImpl*>(guest_web_contents)-> |
| - GetBrowserPluginGuest(); |
| - DCHECK(guest); |
| - // If we do not destroy the guest then we allow the new window. |
| - if (!should_allow) |
| - guest->Destroy(); |
| - } |
| - |
| - int instance_id_; |
| -}; |
| - |
| namespace { |
| -std::string WindowOpenDispositionToString( |
| - WindowOpenDisposition window_open_disposition) { |
| - switch (window_open_disposition) { |
| - case IGNORE_ACTION: |
| - return "ignore"; |
| - case SAVE_TO_DISK: |
| - return "save_to_disk"; |
| - case CURRENT_TAB: |
| - return "current_tab"; |
| - case NEW_BACKGROUND_TAB: |
| - return "new_background_tab"; |
| - case NEW_FOREGROUND_TAB: |
| - return "new_foreground_tab"; |
| - case NEW_WINDOW: |
| - return "new_window"; |
| - case NEW_POPUP: |
| - return "new_popup"; |
| - default: |
| - NOTREACHED() << "Unknown Window Open Disposition"; |
| - return "ignore"; |
| - } |
| -} |
| // Called on IO thread. |
| static GURL RetrieveDownloadURLFromRequestId( |
| @@ -215,7 +119,6 @@ BrowserPluginGuest::BrowserPluginGuest( |
| embedder_visible_(true), |
| auto_size_enabled_(false), |
| copy_request_id_(0), |
| - next_permission_request_id_(browser_plugin::kInvalidPermissionRequestID), |
| has_render_view_(has_render_view), |
| last_seen_auto_size_enabled_(false), |
| is_in_destruction_(false), |
| @@ -239,116 +142,9 @@ bool BrowserPluginGuest::AddMessageToConsole(WebContents* source, |
| return true; |
| } |
| -void BrowserPluginGuest::DestroyUnattachedWindows() { |
| - // Destroy() reaches in and removes the BrowserPluginGuest from its opener's |
| - // pending_new_windows_ set. To avoid mutating the set while iterating, we |
| - // create a copy of the pending new windows set and iterate over the copy. |
| - PendingWindowMap pending_new_windows(pending_new_windows_); |
| - // Clean up unattached new windows opened by this guest. |
| - for (PendingWindowMap::const_iterator it = pending_new_windows.begin(); |
| - it != pending_new_windows.end(); ++it) { |
| - it->first->Destroy(); |
| - } |
| - // All pending windows should be removed from the set after Destroy() is |
| - // called on all of them. |
| - DCHECK(pending_new_windows_.empty()); |
| -} |
| - |
| -void BrowserPluginGuest::LoadURLWithParams(const GURL& url, |
| - const Referrer& referrer, |
| - PageTransition transition_type, |
| - WebContents* web_contents) { |
| - NavigationController::LoadURLParams load_url_params(url); |
| - load_url_params.referrer = referrer; |
| - load_url_params.transition_type = transition_type; |
| - load_url_params.extra_headers = std::string(); |
| - if (delegate_ && delegate_->IsOverridingUserAgent()) { |
| - load_url_params.override_user_agent = |
| - NavigationController::UA_OVERRIDE_TRUE; |
| - } |
| - web_contents->GetController().LoadURLWithParams(load_url_params); |
| -} |
| - |
| -void BrowserPluginGuest::RespondToPermissionRequest( |
| - int request_id, |
| - bool should_allow, |
| - const std::string& user_input) { |
| - RequestMap::iterator request_itr = permission_request_map_.find(request_id); |
| - if (request_itr == permission_request_map_.end()) { |
| - VLOG(0) << "Not a valid request ID."; |
| - return; |
| - } |
| - request_itr->second->Respond(should_allow, user_input); |
| - permission_request_map_.erase(request_itr); |
| -} |
| - |
| -void BrowserPluginGuest::RequestPermission( |
| - BrowserPluginPermissionType permission_type, |
| - scoped_refptr<BrowserPluginGuest::PermissionRequest> request, |
| - const base::DictionaryValue& request_info) { |
| - if (!delegate_) { |
| - // Let the stack unwind before we deny the permission request so that |
| - // objects held by the permission request are not destroyed immediately |
| - // after creation. This is to allow those same objects to be accessed again |
| - // in the same scope without fear of use after freeing. |
| - base::MessageLoop::current()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&BrowserPluginGuest::PermissionRequest::Respond, |
| - request, false, "")); |
| - } |
| - |
| - int request_id = ++next_permission_request_id_; |
| - permission_request_map_[request_id] = request; |
| - |
| - BrowserPluginGuestDelegate::PermissionResponseCallback callback = |
| - base::Bind(&BrowserPluginGuest::RespondToPermissionRequest, |
| - AsWeakPtr(), |
| - request_id); |
| - delegate_->RequestPermission( |
| - permission_type, request_info, callback, request->AllowedByDefault()); |
| -} |
| - |
| -BrowserPluginGuest* BrowserPluginGuest::CreateNewGuestWindow( |
| - const OpenURLParams& params) { |
| - BrowserPluginGuestManager* guest_manager = |
| - GetBrowserPluginGuestManager(); |
| - |
| - // Allocate a new instance ID for the new guest. |
| - int instance_id = guest_manager->GetNextInstanceID(); |
| - |
| - // Set the attach params to use the same partition as the opener. |
| - // We pull the partition information from the site's URL, which is of the form |
| - // guest://site/{persist}?{partition_name}. |
| - const GURL& site_url = GetWebContents()->GetSiteInstance()->GetSiteURL(); |
| - |
| - // The new guest gets a copy of this guest's extra params so that the content |
| - // embedder exposes the same API for this guest as its opener. |
| - scoped_ptr<base::DictionaryValue> extra_params( |
| - extra_attach_params_->DeepCopy()); |
| - const std::string& storage_partition_id = site_url.query(); |
| - bool persist_storage = |
| - site_url.path().find("persist") != std::string::npos; |
| - WebContents* new_guest_web_contents = |
| - guest_manager->CreateGuest(GetWebContents()->GetSiteInstance(), |
| - instance_id, |
| - storage_partition_id, |
| - persist_storage, |
| - extra_params.Pass()); |
| - BrowserPluginGuest* new_guest = |
| - static_cast<WebContentsImpl*>(new_guest_web_contents)-> |
| - GetBrowserPluginGuest(); |
| - if (new_guest->delegate_) |
| - new_guest->delegate_->SetOpener(GetWebContents()); |
| - |
| - // Take ownership of |new_guest|. |
| - pending_new_windows_.insert( |
| - std::make_pair(new_guest, NewWindowInfo(params.url, std::string()))); |
| - |
| - // Request permission to show the new window. |
| - RequestNewWindowPermission(params.disposition, gfx::Rect(), |
| - params.user_gesture, new_guest->GetWebContents()); |
| - |
| - return new_guest; |
| +void BrowserPluginGuest::WillDestroy(WebContents* web_contents) { |
| + DCHECK_EQ(web_contents, GetWebContents()); |
| + is_in_destruction_ = true; |
| } |
| base::WeakPtr<BrowserPluginGuest> BrowserPluginGuest::AsWeakPtr() { |
| @@ -363,11 +159,9 @@ void BrowserPluginGuest::EmbedderDestroyed() { |
| } |
| void BrowserPluginGuest::Destroy() { |
| - is_in_destruction_ = true; |
| - if (!attached() && GetOpener()) |
| - GetOpener()->pending_new_windows_.erase(this); |
| - DestroyUnattachedWindows(); |
| - delete GetWebContents(); |
| + if (!delegate_) |
| + return; |
| + delegate_->Destroy(); |
| } |
| bool BrowserPluginGuest::OnMessageReceivedFromEmbedder( |
| @@ -471,10 +265,9 @@ void BrowserPluginGuest::Initialize( |
| if (!params.src.empty()) { |
| // params.src will be validated in BrowserPluginGuest::OnNavigateGuest. |
| OnNavigateGuest(instance_id_, params.src); |
| + has_render_view_ = true; |
| } |
| - has_render_view_ = true; |
| - |
| WebPreferences prefs = GetWebContents()->GetWebkitPrefs(); |
| prefs.navigate_on_drag_drop = false; |
| GetWebContents()->GetRenderViewHost()->UpdateWebkitPreferences(prefs); |
| @@ -515,39 +308,36 @@ BrowserPluginGuest* BrowserPluginGuest::Create( |
| int instance_id, |
| SiteInstance* guest_site_instance, |
| WebContentsImpl* web_contents, |
| - scoped_ptr<base::DictionaryValue> extra_params) { |
| + scoped_ptr<base::DictionaryValue> extra_params, |
| + BrowserPluginGuest* opener) { |
| RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Create")); |
| BrowserPluginGuest* guest = NULL; |
| if (factory_) { |
| guest = factory_->CreateBrowserPluginGuest(instance_id, web_contents); |
| } else { |
| - guest = new BrowserPluginGuest(instance_id, false, web_contents); |
| + guest = new BrowserPluginGuest(instance_id, |
| + web_contents->opener() != NULL, |
| + web_contents); |
| } |
| - guest->extra_attach_params_.reset(extra_params->DeepCopy()); |
| - web_contents->SetBrowserPluginGuest(guest); |
| - BrowserPluginGuestDelegate* delegate = NULL; |
| - GetContentClient()->browser()->GuestWebContentsCreated( |
| - guest_site_instance, web_contents, NULL, &delegate, extra_params.Pass()); |
| - guest->SetDelegate(delegate); |
| - return guest; |
| -} |
| - |
| -// static |
| -BrowserPluginGuest* BrowserPluginGuest::CreateWithOpener( |
| - int instance_id, |
| - bool has_render_view, |
| - WebContentsImpl* web_contents, |
| - BrowserPluginGuest* opener) { |
| - BrowserPluginGuest* guest = |
| - new BrowserPluginGuest( |
| - instance_id, has_render_view, web_contents); |
| web_contents->SetBrowserPluginGuest(guest); |
| + WebContents* opener_web_contents = NULL; |
| + if (opener) { |
| + opener_web_contents = opener->GetWebContents(); |
| + guest_site_instance = opener_web_contents->GetSiteInstance(); |
| + } |
| BrowserPluginGuestDelegate* delegate = NULL; |
| GetContentClient()->browser()->GuestWebContentsCreated( |
| - opener->GetWebContents()->GetSiteInstance(), |
| - web_contents, opener->GetWebContents(), &delegate, |
| - scoped_ptr<base::DictionaryValue>()); |
| - guest->SetDelegate(delegate); |
| + guest_site_instance, |
| + web_contents, |
| + opener_web_contents, |
| + &delegate, |
| + extra_params.Pass()); |
| + if (delegate) { |
| + delegate->RegisterDestructionCallback( |
| + base::Bind(&BrowserPluginGuest::WillDestroy, |
| + base::Unretained(guest))); |
| + guest->SetDelegate(delegate); |
| + } |
| return guest; |
| } |
| @@ -557,17 +347,6 @@ RenderWidgetHostView* BrowserPluginGuest::GetEmbedderRenderWidgetHostView() { |
| return embedder_web_contents_->GetRenderWidgetHostView(); |
| } |
| -BrowserPluginGuest* BrowserPluginGuest::GetOpener() const { |
| - if (!delegate_) |
| - return NULL; |
| - |
| - WebContents* opener = delegate_->GetOpener(); |
| - if (!opener) |
| - return NULL; |
| - |
| - return static_cast<WebContentsImpl*>(opener)->GetBrowserPluginGuest(); |
| -} |
| - |
| void BrowserPluginGuest::UpdateVisibility() { |
| OnSetVisibility(instance_id_, visible()); |
| } |
| @@ -605,10 +384,11 @@ void BrowserPluginGuest::AddNewContents(WebContents* source, |
| const gfx::Rect& initial_pos, |
| bool user_gesture, |
| bool* was_blocked) { |
| - if (was_blocked) |
| - *was_blocked = false; |
| - RequestNewWindowPermission(disposition, initial_pos, user_gesture, |
| - static_cast<WebContentsImpl*>(new_contents)); |
| + if (!delegate_) |
| + return; |
| + |
| + delegate_->AddNewContents(source, new_contents, disposition, |
| + initial_pos, user_gesture, was_blocked); |
| } |
| void BrowserPluginGuest::CanDownload( |
| @@ -726,29 +506,9 @@ void BrowserPluginGuest::FindReply(WebContents* contents, |
| WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source, |
| const OpenURLParams& params) { |
| - // If the guest wishes to navigate away prior to attachment then we save the |
| - // navigation to perform upon attachment. Navigation initializes a lot of |
| - // state that assumes an embedder exists, such as RenderWidgetHostViewGuest. |
| - // Navigation also resumes resource loading which we don't want to allow |
| - // until attachment. |
| - if (!attached()) { |
| - PendingWindowMap::iterator it = |
| - GetOpener()->pending_new_windows_.find(this); |
| - if (it == GetOpener()->pending_new_windows_.end()) |
| - return NULL; |
| - const NewWindowInfo& old_target_url = it->second; |
| - NewWindowInfo new_window_info(params.url, old_target_url.name); |
| - new_window_info.changed = new_window_info.url != old_target_url.url; |
| - it->second = new_window_info; |
| + if (!delegate_) |
| return NULL; |
| - } |
| - if (params.disposition == CURRENT_TAB) { |
| - // This can happen for cross-site redirects. |
| - LoadURLWithParams(params.url, params.referrer, params.transition, source); |
| - return source; |
| - } |
| - |
| - return CreateNewGuestWindow(params)->GetWebContents(); |
| + return delegate_->OpenURLFromTab(source, params); |
| } |
| void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents, |
| @@ -759,15 +519,17 @@ void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents, |
| WebContentsImpl* new_contents_impl = |
| static_cast<WebContentsImpl*>(new_contents); |
| BrowserPluginGuest* guest = new_contents_impl->GetBrowserPluginGuest(); |
| - if (guest->delegate_) |
| - guest->delegate_->SetOpener(GetWebContents()); |
| std::string guest_name = base::UTF16ToUTF8(frame_name); |
| guest->name_ = guest_name; |
| - // Take ownership of the new guest until it is attached to the embedder's DOM |
| - // tree to avoid leaking a guest if this guest is destroyed before attaching |
| - // the new guest. |
| - pending_new_windows_.insert( |
| - std::make_pair(guest, NewWindowInfo(target_url, guest_name))); |
| + |
| + if (!delegate_) |
| + return; |
| + |
| + delegate_->WebContentsCreated(source_contents, |
| + opener_render_frame_id, |
| + frame_name, |
| + target_url, |
| + new_contents); |
| } |
| void BrowserPluginGuest::RendererUnresponsive(WebContents* source) { |
| @@ -817,38 +579,6 @@ bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const { |
| size.height() <= max_auto_size_.height(); |
| } |
| -void BrowserPluginGuest::RequestNewWindowPermission( |
| - WindowOpenDisposition disposition, |
| - const gfx::Rect& initial_bounds, |
| - bool user_gesture, |
| - WebContentsImpl* new_contents) { |
| - BrowserPluginGuest* guest = new_contents->GetBrowserPluginGuest(); |
| - PendingWindowMap::iterator it = pending_new_windows_.find(guest); |
| - if (it == pending_new_windows_.end()) |
| - return; |
| - const NewWindowInfo& new_window_info = it->second; |
| - |
| - base::DictionaryValue request_info; |
| - request_info.Set(browser_plugin::kInitialHeight, |
|
lazyboy
2014/05/12 23:00:20
Remove these from browser_plugin_constants.cc
Fady Samuel
2014/05/13 18:59:02
Done.
|
| - base::Value::CreateIntegerValue(initial_bounds.height())); |
| - request_info.Set(browser_plugin::kInitialWidth, |
| - base::Value::CreateIntegerValue(initial_bounds.width())); |
| - request_info.Set(browser_plugin::kTargetURL, |
| - base::Value::CreateStringValue(new_window_info.url.spec())); |
| - request_info.Set(browser_plugin::kName, |
| - base::Value::CreateStringValue(new_window_info.name)); |
| - request_info.Set(browser_plugin::kWindowID, |
| - base::Value::CreateIntegerValue(guest->instance_id())); |
| - request_info.Set(browser_plugin::kWindowOpenDisposition, |
| - base::Value::CreateStringValue( |
| - WindowOpenDispositionToString(disposition))); |
| - |
| - RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW, |
| - new NewWindowRequest(weak_ptr_factory_.GetWeakPtr(), |
| - guest->instance_id()), |
| - request_info); |
| -} |
| - |
| bool BrowserPluginGuest::UnlockMouseIfNecessary( |
| const NativeWebKeyboardEvent& event) { |
| if (!mouse_locked_) |
| @@ -960,8 +690,6 @@ void BrowserPluginGuest::RenderProcessGone(base::TerminationStatus status) { |
| default: |
| break; |
| } |
| - // TODO(fsamuel): Consider whether we should be clearing |
| - // |permission_request_map_| here. |
| if (delegate_) |
| delegate_->GuestProcessGone(status); |
| } |
| @@ -1035,8 +763,6 @@ void BrowserPluginGuest::Attach( |
| if (attached()) |
| return; |
| - extra_attach_params_.reset(extra_params.DeepCopy()); |
| - |
| // Clear parameters that get inherited from the opener. |
| params.storage_partition_id.clear(); |
| params.persist_storage = false; |
| @@ -1053,23 +779,6 @@ void BrowserPluginGuest::Attach( |
| new_view->CreateViewForWidget(web_contents()->GetRenderViewHost()); |
| } |
| - // We need to do a navigation here if the target URL has changed between |
| - // the time the WebContents was created and the time it was attached. |
| - // We also need to do an initial navigation if a RenderView was never |
| - // created for the new window in cases where there is no referrer. |
| - PendingWindowMap::iterator it = GetOpener()->pending_new_windows_.find(this); |
| - if (it != GetOpener()->pending_new_windows_.end()) { |
| - const NewWindowInfo& new_window_info = it->second; |
| - if (new_window_info.changed || !has_render_view_) |
| - params.src = it->second.url.spec(); |
| - } else { |
| - NOTREACHED(); |
| - } |
| - |
| - // Once a new guest is attached to the DOM of the embedder page, then the |
| - // lifetime of the new guest is no longer managed by the opener guest. |
| - GetOpener()->pending_new_windows_.erase(this); |
| - |
| // The guest's frame name takes precedence over the BrowserPlugin's name. |
| // The guest's frame name is assigned in |
| // BrowserPluginGuest::WebContentsCreated. |
| @@ -1249,38 +958,11 @@ void BrowserPluginGuest::OnLockMouseAck(int instance_id, bool succeeded) { |
| mouse_locked_ = true; |
| } |
| -void BrowserPluginGuest::OnNavigateGuest( |
| - int instance_id, |
| - const std::string& src) { |
| - GURL url = delegate_ ? delegate_->ResolveURL(src) : GURL(src); |
| - |
| - // Do not allow navigating a guest to schemes other than known safe schemes. |
| - // This will block the embedder trying to load unwanted schemes, e.g. |
| - // chrome://settings. |
| - bool scheme_is_blocked = |
| - (!ChildProcessSecurityPolicyImpl::GetInstance()->IsWebSafeScheme( |
| - url.scheme()) && |
| - !ChildProcessSecurityPolicyImpl::GetInstance()->IsPseudoScheme( |
| - url.scheme())) || |
| - url.SchemeIs(kJavaScriptScheme); |
| - if (scheme_is_blocked || !url.is_valid()) { |
| - if (delegate_) { |
| - std::string error_type; |
| - base::RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::", |
| - &error_type); |
| - delegate_->LoadAbort(true /* is_top_level */, url, error_type); |
| - } |
| +void BrowserPluginGuest::OnNavigateGuest(int instance_id, |
| + const std::string& src) { |
| + if (!delegate_) |
| return; |
| - } |
| - |
| - GURL validated_url(url); |
| - GetWebContents()->GetRenderProcessHost()->FilterURL(false, &validated_url); |
| - // As guests do not swap processes on navigation, only navigations to |
| - // normal web URLs are supported. No protocol handlers are installed for |
| - // other schemes (e.g., WebUI or extensions), and no permissions or bindings |
| - // can be granted to the guest process. |
| - LoadURLWithParams(validated_url, Referrer(), PAGE_TRANSITION_AUTO_TOPLEVEL, |
| - GetWebContents()); |
| + delegate_->NavigateGuest(src); |
| } |
| void BrowserPluginGuest::OnPluginDestroyed(int instance_id) { |