CTRL + left click on a link in a PDF document should call OnOpenURLFromTab (issue #1737)

This commit is contained in:
Marshall Greenblatt 2015-10-21 14:17:09 -04:00
parent 936e595fe5
commit 211c81cb14
15 changed files with 326 additions and 152 deletions

View File

@ -629,13 +629,13 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForView(
return GetBrowserForHost(render_view_host);
} else {
// Use the thread-safe approach.
bool is_guest_view = false;
scoped_refptr<CefBrowserInfo> info =
CefContentBrowserClient::Get()->GetBrowserInfoForView(
render_process_id,
render_routing_id);
if (info.get()) {
render_process_id, render_routing_id, &is_guest_view);
if (info.get() && !is_guest_view) {
CefRefPtr<CefBrowserHostImpl> browser = info->browser();
if (!browser.get() && !info->is_mime_handler_view()) {
if (!browser.get()) {
LOG(WARNING) << "Found browser id " << info->browser_id() <<
" but no browser object matching view process id " <<
render_process_id << " and routing id " <<
@ -662,13 +662,13 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserForFrame(
return GetBrowserForHost(render_frame_host);
} else {
// Use the thread-safe approach.
bool is_guest_view = false;
scoped_refptr<CefBrowserInfo> info =
CefContentBrowserClient::Get()->GetBrowserInfoForFrame(
render_process_id,
render_routing_id);
if (info.get()) {
render_process_id, render_routing_id, &is_guest_view);
if (info.get() && !is_guest_view) {
CefRefPtr<CefBrowserHostImpl> browser = info->browser();
if (!browser.get() && !info->is_mime_handler_view()) {
if (!browser.get()) {
LOG(WARNING) << "Found browser id " << info->browser_id() <<
" but no browser object matching frame process id " <<
render_process_id << " and routing id " <<
@ -2220,6 +2220,8 @@ void CefBrowserHostImpl::DragSourceEndedAt(
// content::WebContentsDelegate methods.
// -----------------------------------------------------------------------------
// |source| may be NULL if the navigation originates from a guest view via
// CefContentBrowserClient::CanCreateWindow.
content::WebContents* CefBrowserHostImpl::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {
@ -2484,12 +2486,17 @@ void CefBrowserHostImpl::WebContentsCreated(
content::RenderFrameHost* main_frame_host = new_contents->GetMainFrame();
CefWindowHandle opener = kNullWindowHandle;
bool is_guest_view = false;
scoped_refptr<CefBrowserInfo> info =
CefContentBrowserClient::Get()->GetOrCreateBrowserInfo(
view_host->GetProcess()->GetID(),
view_host->GetRoutingID(),
main_frame_host->GetProcess()->GetID(),
main_frame_host->GetRoutingID());
main_frame_host->GetRoutingID(),
&is_guest_view);
// A CefBrowser should never be created for a guest view WebContents.
CHECK(!is_guest_view);
if (source_contents) {
DCHECK(info->is_popup());
@ -2644,20 +2651,22 @@ bool CefBrowserHostImpl::CheckMediaAccessPermission(
void CefBrowserHostImpl::RenderFrameCreated(
content::RenderFrameHost* render_frame_host) {
browser_info_->add_render_frame_id(render_frame_host->GetProcess()->GetID(),
browser_info_->render_id_manager()->add_render_frame_id(
render_frame_host->GetProcess()->GetID(),
render_frame_host->GetRoutingID());
}
void CefBrowserHostImpl::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
browser_info_->remove_render_frame_id(
browser_info_->render_id_manager()->remove_render_frame_id(
render_frame_host->GetProcess()->GetID(),
render_frame_host->GetRoutingID());
}
void CefBrowserHostImpl::RenderViewCreated(
content::RenderViewHost* render_view_host) {
browser_info_->add_render_view_id(render_view_host->GetProcess()->GetID(),
browser_info_->render_id_manager()->add_render_view_id(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
// May be already registered if the renderer crashed previously.
@ -2671,7 +2680,8 @@ void CefBrowserHostImpl::RenderViewCreated(
void CefBrowserHostImpl::RenderViewDeleted(
content::RenderViewHost* render_view_host) {
browser_info_->remove_render_view_id(render_view_host->GetProcess()->GetID(),
browser_info_->render_id_manager()->remove_render_view_id(
render_view_host->GetProcess()->GetID(),
render_view_host->GetRoutingID());
if (registrar_->IsRegistered(

View File

@ -15,6 +15,7 @@
#include "include/cef_browser.h"
#include "include/cef_client.h"
#include "include/cef_frame.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/frame_host_impl.h"
#include "libcef/browser/javascript_dialog_manager.h"
#include "libcef/browser/menu_creator.h"
@ -303,6 +304,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
// Thread safe accessors.
const CefBrowserSettings& settings() const { return settings_; }
CefRefPtr<CefClient> client() const { return client_; }
scoped_refptr<CefBrowserInfo> browser_info() const { return browser_info_; }
int browser_id() const;
#if defined(USE_AURA)

View File

@ -3,78 +3,59 @@
// be found in the LICENSE file.
#include "libcef/browser/browser_info.h"
#include "libcef/browser/browser_host_impl.h"
#include "ipc/ipc_message.h"
CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup)
: browser_id_(browser_id),
is_popup_(is_popup),
is_windowless_(false),
is_mime_handler_view_(false) {
DCHECK_GT(browser_id, 0);
// CefBrowserInfo::RenderIDManager
CefBrowserInfo::RenderIDManager::RenderIDManager(base::Lock* lock)
: lock_(lock) {
DCHECK(lock);
}
CefBrowserInfo::~CefBrowserInfo() {
}
void CefBrowserInfo::set_windowless(bool windowless) {
is_windowless_ = windowless;
}
void CefBrowserInfo::set_mime_handler_view(bool mime_handler_view) {
is_mime_handler_view_ = mime_handler_view;
}
void CefBrowserInfo::add_render_view_id(
void CefBrowserInfo::RenderIDManager::add_render_view_id(
int render_process_id, int render_routing_id) {
add_render_id(&render_view_id_set_, render_process_id, render_routing_id);
}
void CefBrowserInfo::add_render_frame_id(
void CefBrowserInfo::RenderIDManager::add_render_frame_id(
int render_process_id, int render_routing_id) {
add_render_id(&render_frame_id_set_, render_process_id, render_routing_id);
}
void CefBrowserInfo::remove_render_view_id(
void CefBrowserInfo::RenderIDManager::remove_render_view_id(
int render_process_id, int render_routing_id) {
remove_render_id(&render_view_id_set_, render_process_id, render_routing_id);
}
void CefBrowserInfo::remove_render_frame_id(
void CefBrowserInfo::RenderIDManager::remove_render_frame_id(
int render_process_id, int render_routing_id) {
remove_render_id(&render_frame_id_set_, render_process_id, render_routing_id);
}
bool CefBrowserInfo::is_render_view_id_match(
bool CefBrowserInfo::RenderIDManager::is_render_view_id_match(
int render_process_id, int render_routing_id) {
return is_render_id_match(&render_view_id_set_,
render_process_id,
render_routing_id);
}
bool CefBrowserInfo::is_render_frame_id_match(
bool CefBrowserInfo::RenderIDManager::is_render_frame_id_match(
int render_process_id, int render_routing_id) {
return is_render_id_match(&render_frame_id_set_,
render_process_id,
render_routing_id);
}
CefRefPtr<CefBrowserHostImpl> CefBrowserInfo::browser() {
base::AutoLock lock_scope(lock_);
return browser_;
}
void CefBrowserInfo::set_browser(CefRefPtr<CefBrowserHostImpl> browser) {
base::AutoLock lock_scope(lock_);
browser_ = browser;
}
void CefBrowserInfo::add_render_id(RenderIdSet* id_set,
void CefBrowserInfo::RenderIDManager::add_render_id(RenderIdSet* id_set,
int render_process_id,
int render_routing_id) {
DCHECK_GT(render_process_id, 0);
DCHECK_GT(render_routing_id, 0);
base::AutoLock lock_scope(lock_);
base::AutoLock lock_scope(*lock_);
if (!id_set->empty()) {
RenderIdSet::const_iterator it =
@ -86,13 +67,13 @@ void CefBrowserInfo::add_render_id(RenderIdSet* id_set,
id_set->insert(std::make_pair(render_process_id, render_routing_id));
}
void CefBrowserInfo::remove_render_id(RenderIdSet* id_set,
void CefBrowserInfo::RenderIDManager::remove_render_id(RenderIdSet* id_set,
int render_process_id,
int render_routing_id) {
DCHECK_GT(render_process_id, 0);
DCHECK_GT(render_routing_id, 0);
base::AutoLock lock_scope(lock_);
base::AutoLock lock_scope(*lock_);
DCHECK(!id_set->empty());
if (id_set->empty())
@ -103,10 +84,11 @@ void CefBrowserInfo::remove_render_id(RenderIdSet* id_set,
DCHECK(erased);
}
bool CefBrowserInfo::is_render_id_match(const RenderIdSet* id_set,
bool CefBrowserInfo::RenderIDManager::is_render_id_match(
const RenderIdSet* id_set,
int render_process_id,
int render_routing_id) {
base::AutoLock lock_scope(lock_);
base::AutoLock lock_scope(*lock_);
if (id_set->empty())
return false;
@ -115,3 +97,32 @@ bool CefBrowserInfo::is_render_id_match(const RenderIdSet* id_set,
id_set->find(std::make_pair(render_process_id, render_routing_id));
return (it != id_set->end());
}
// CefBrowserInfo
CefBrowserInfo::CefBrowserInfo(int browser_id, bool is_popup)
: browser_id_(browser_id),
is_popup_(is_popup),
is_windowless_(false),
render_id_manager_(&lock_),
guest_render_id_manager_(&lock_) {
DCHECK_GT(browser_id, 0);
}
CefBrowserInfo::~CefBrowserInfo() {
}
void CefBrowserInfo::set_windowless(bool windowless) {
is_windowless_ = windowless;
}
CefRefPtr<CefBrowserHostImpl> CefBrowserInfo::browser() {
base::AutoLock lock_scope(lock_);
return browser_;
}
void CefBrowserInfo::set_browser(CefRefPtr<CefBrowserHostImpl> browser) {
base::AutoLock lock_scope(lock_);
browser_ = browser;
}

View File

@ -8,8 +8,12 @@
#include <set>
#include "libcef/browser/browser_host_impl.h"
#include "include/internal/cef_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
class CefBrowserHostImpl;
// CefBrowserInfo is used to associate a browser ID and render view/process
// IDs with a particular CefBrowserHostImpl. Render view/process IDs may change
@ -19,15 +23,9 @@
// be created directly.
class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
public:
CefBrowserInfo(int browser_id, bool is_popup);
int browser_id() const { return browser_id_; };
bool is_popup() const { return is_popup_; }
bool is_windowless() const { return is_windowless_; }
bool is_mime_handler_view() const { return is_mime_handler_view_; }
void set_windowless(bool windowless);
void set_mime_handler_view(bool mime_handler_view);
class RenderIDManager {
public:
explicit RenderIDManager(base::Lock* lock);
// Adds an ID pair if it doesn't already exist.
void add_render_view_id(int render_process_id, int render_routing_id);
@ -41,14 +39,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
bool is_render_view_id_match(int render_process_id, int render_routing_id);
bool is_render_frame_id_match(int render_process_id, int render_routing_id);
CefRefPtr<CefBrowserHostImpl> browser();
void set_browser(CefRefPtr<CefBrowserHostImpl> browser);
private:
friend class base::RefCountedThreadSafe<CefBrowserInfo>;
~CefBrowserInfo();
typedef std::set<std::pair<int, int> > RenderIdSet;
void add_render_id(RenderIdSet* id_set,
@ -61,12 +52,7 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
int render_process_id,
int render_routing_id);
int browser_id_;
bool is_popup_;
bool is_windowless_;
bool is_mime_handler_view_;
base::Lock lock_;
base::Lock* lock_;
// The below members must be protected by |lock_|.
@ -74,13 +60,52 @@ class CefBrowserInfo : public base::RefCountedThreadSafe<CefBrowserInfo> {
// necessary for the following reasons:
// 1. When navigating cross-origin the new (pending) RenderViewHost will be
// created before the old (current) RenderViewHost is destroyed.
// 2. When canceling and asynchronously continuing navigation of the same URL
// a new RenderViewHost may be created for the first (canceled) navigation
// and then destroyed as a result of the second (allowed) navigation.
// 2. When canceling and asynchronously continuing navigation of the same
// URL a new RenderViewHost may be created for the first (canceled)
// navigation and then destroyed as a result of the second (allowed)
// navigation.
// 3. Out-of-process iframes have their own render IDs which must also be
// associated with the host browser.
RenderIdSet render_view_id_set_;
RenderIdSet render_frame_id_set_;
};
CefBrowserInfo(int browser_id, bool is_popup);
int browser_id() const { return browser_id_; };
bool is_popup() const { return is_popup_; }
bool is_windowless() const { return is_windowless_; }
void set_windowless(bool windowless);
// Returns the render ID manager for this browser.
RenderIDManager* render_id_manager() {
return &render_id_manager_;
}
// Returns the render ID manager for guest views owned by this browser.
RenderIDManager* guest_render_id_manager() {
return &guest_render_id_manager_;
}
CefRefPtr<CefBrowserHostImpl> browser();
void set_browser(CefRefPtr<CefBrowserHostImpl> browser);
private:
friend class base::RefCountedThreadSafe<CefBrowserInfo>;
~CefBrowserInfo();
int browser_id_;
bool is_popup_;
bool is_windowless_;
base::Lock lock_;
// The below members must be protected by |lock_|.
RenderIDManager render_id_manager_;
RenderIDManager guest_render_id_manager_;
// May be NULL if the browser has not yet been created or if the browser has
// been destroyed.

View File

@ -97,11 +97,11 @@ void CefBrowserMessageFilter::OnGetNewBrowserInfo(
host_->GetID(),
render_view_routing_id,
host_->GetID(),
render_frame_routing_id);
render_frame_routing_id,
&params->is_guest_view);
params->browser_id = info->browser_id();
params->is_popup = info->is_popup();
params->is_windowless = info->is_windowless();
params->is_mime_handler_view = info->is_mime_handler_view();
}
void CefBrowserMessageFilter::OnCreateWindow(

View File

@ -50,6 +50,7 @@
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/quota_permission_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@ -467,24 +468,37 @@ scoped_refptr<CefBrowserInfo>
int render_view_process_id,
int render_view_routing_id,
int render_frame_process_id,
int render_frame_routing_id) {
int render_frame_routing_id,
bool* is_guest_view) {
base::AutoLock lock_scope(browser_info_lock_);
if (is_guest_view)
*is_guest_view = false;
BrowserInfoList::const_iterator it = browser_info_list_.begin();
for (; it != browser_info_list_.end(); ++it) {
const scoped_refptr<CefBrowserInfo>& browser_info = *it;
if (browser_info->is_render_view_id_match(render_view_process_id,
render_view_routing_id)) {
if (browser_info->render_id_manager()->is_render_view_id_match(
render_view_process_id, render_view_routing_id)) {
// Make sure the frame id is also registered.
browser_info->add_render_frame_id(render_frame_process_id,
render_frame_routing_id);
browser_info->render_id_manager()->add_render_frame_id(
render_frame_process_id, render_frame_routing_id);
return browser_info;
} else if (browser_info->is_render_frame_id_match(
render_frame_process_id,
render_frame_routing_id)) {
}
if (browser_info->render_id_manager()->is_render_frame_id_match(
render_frame_process_id, render_frame_routing_id)) {
// Make sure the view id is also registered.
browser_info->add_render_view_id(render_view_process_id,
render_view_routing_id);
browser_info->render_id_manager()->add_render_view_id(
render_view_process_id, render_view_routing_id);
return browser_info;
}
if (extensions::ExtensionsEnabled() &&
(browser_info->guest_render_id_manager()->is_render_view_id_match(
render_view_process_id, render_view_routing_id) ||
browser_info->guest_render_id_manager()->is_render_frame_id_match(
render_frame_process_id, render_frame_routing_id))) {
if (is_guest_view)
*is_guest_view = true;
return browser_info;
}
}
@ -492,10 +506,10 @@ scoped_refptr<CefBrowserInfo>
// Must be a popup if it hasn't already been created.
scoped_refptr<CefBrowserInfo> browser_info =
new CefBrowserInfo(++next_browser_id_, true);
browser_info->add_render_view_id(render_view_process_id,
render_view_routing_id);
browser_info->add_render_frame_id(render_frame_process_id,
render_frame_routing_id);
browser_info->render_id_manager()->add_render_view_id(
render_view_process_id, render_view_routing_id);
browser_info->render_id_manager()->add_render_frame_id(
render_frame_process_id, render_frame_routing_id);
browser_info_list_.push_back(browser_info);
return browser_info;
}
@ -550,16 +564,28 @@ void CefContentBrowserClient::DestroyAllBrowsers() {
}
scoped_refptr<CefBrowserInfo> CefContentBrowserClient::GetBrowserInfoForView(
int render_process_id, int render_routing_id) {
int render_process_id,
int render_routing_id,
bool* is_guest_view) {
base::AutoLock lock_scope(browser_info_lock_);
if (is_guest_view)
*is_guest_view = false;
BrowserInfoList::const_iterator it = browser_info_list_.begin();
for (; it != browser_info_list_.end(); ++it) {
const scoped_refptr<CefBrowserInfo>& browser_info = *it;
if (browser_info->is_render_view_id_match(
if (browser_info->render_id_manager()->is_render_view_id_match(
render_process_id, render_routing_id)) {
return browser_info;
}
if (extensions::ExtensionsEnabled() &&
browser_info->guest_render_id_manager()->is_render_view_id_match(
render_process_id, render_routing_id)) {
if (is_guest_view)
*is_guest_view = true;
return browser_info;
}
}
LOG(WARNING) << "No browser info matching view process id " <<
@ -569,16 +595,28 @@ scoped_refptr<CefBrowserInfo> CefContentBrowserClient::GetBrowserInfoForView(
}
scoped_refptr<CefBrowserInfo> CefContentBrowserClient::GetBrowserInfoForFrame(
int render_process_id, int render_routing_id) {
int render_process_id,
int render_routing_id,
bool* is_guest_view) {
base::AutoLock lock_scope(browser_info_lock_);
if (is_guest_view)
*is_guest_view = false;
BrowserInfoList::const_iterator it = browser_info_list_.begin();
for (; it != browser_info_list_.end(); ++it) {
const scoped_refptr<CefBrowserInfo>& browser_info = *it;
if (browser_info->is_render_frame_id_match(
if (browser_info->render_id_manager()->is_render_frame_id_match(
render_process_id, render_routing_id)) {
return browser_info;
}
if (extensions::ExtensionsEnabled() &&
browser_info->guest_render_id_manager()->is_render_frame_id_match(
render_process_id, render_routing_id)) {
if (is_guest_view)
*is_guest_view = true;
return browser_info;
}
}
LOG(WARNING) << "No browser info matching frame process id " <<
@ -924,12 +962,36 @@ bool CefContentBrowserClient::CanCreateWindow(
if (last_create_window_params_.opener_process_id == MSG_ROUTING_NONE)
return false;
bool is_guest_view = false;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForView(
extensions::GetOwnerBrowserForView(
last_create_window_params_.opener_process_id,
last_create_window_params_.opener_view_id);
if (!browser.get())
last_create_window_params_.opener_view_id,
&is_guest_view);
DCHECK(browser.get());
if (!browser.get()) {
// Cancel the popup.
last_create_window_params_.opener_process_id = MSG_ROUTING_NONE;
return false;
}
if (is_guest_view) {
content::OpenURLParams params(target_url,
referrer,
disposition,
ui::PAGE_TRANSITION_LINK,
true);
params.user_gesture = user_gesture;
// Pass navigation to the owner browser.
CEF_POST_TASK(CEF_UIT,
base::Bind(base::IgnoreResult(&CefBrowserHostImpl::OpenURLFromTab),
browser.get(), nullptr, params));
// Cancel the popup.
last_create_window_params_.opener_process_id = MSG_ROUTING_NONE;
return false;
}
CefRefPtr<CefClient> client = browser->GetClient();
bool allow = true;

View File

@ -50,23 +50,30 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
// to CefBrowserHostImpl::ShouldCreateWebContents on the UI thread. To resolve
// this race CefBrowserInfo may be created when requested for the first time
// and before the associated CefBrowserHostImpl is created.
// |is_guest_view| will be set to true if the IDs match a guest view
// associated with the returned browser info instead of the browser itself.
scoped_refptr<CefBrowserInfo> CreateBrowserInfo(bool is_popup);
scoped_refptr<CefBrowserInfo> GetOrCreateBrowserInfo(
int render_view_process_id,
int render_view_routing_id,
int render_frame_process_id,
int render_frame_routing_id);
int render_frame_routing_id,
bool* is_guest_view);
void RemoveBrowserInfo(scoped_refptr<CefBrowserInfo> browser_info);
void DestroyAllBrowsers();
// Retrieves the CefBrowserInfo matching the specified IDs or an empty
// pointer if no match is found. It is allowed to add new callers of this
// method but consider using CefBrowserHostImpl::GetBrowserFor[View|Frame]()
// instead.
// or extensions::GetOwnerBrowserForView() instead.
// |is_guest_view| will be set to true if the IDs match a guest view
// associated with the returned browser info instead of the browser itself.
scoped_refptr<CefBrowserInfo> GetBrowserInfoForView(int render_process_id,
int render_routing_id);
int render_routing_id,
bool* is_guest_view);
scoped_refptr<CefBrowserInfo> GetBrowserInfoForFrame(int render_process_id,
int render_routing_id);
int render_routing_id,
bool* is_guest_view);
// ContentBrowserClient implementation.
content::BrowserMainParts* CreateBrowserMainParts(

View File

@ -4,6 +4,8 @@
#include "libcef/browser/extensions/browser_extensions_util.h"
#include "libcef/browser/content_browser_client.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/extensions/extensions_util.h"
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
@ -58,24 +60,51 @@ content::WebContents* GetOwnerForGuestContents(content::WebContents* guest) {
}
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForView(int render_process_id,
int render_routing_id) {
int render_routing_id,
bool* is_guest_view) {
if (CEF_CURRENTLY_ON_UIT()) {
// Use the non-thread-safe but potentially faster approach.
content::RenderViewHost* host =
content::RenderViewHost::FromID(render_process_id, render_routing_id);
if (host)
return GetOwnerBrowserForHost(host);
return GetOwnerBrowserForHost(host, is_guest_view);
return NULL;
} else {
// Use the thread-safe approach.
scoped_refptr<CefBrowserInfo> info =
CefContentBrowserClient::Get()->GetBrowserInfoForView(
render_process_id, render_routing_id, is_guest_view);
if (info.get()) {
CefRefPtr<CefBrowserHostImpl> browser = info->browser();
if (!browser.get()) {
LOG(WARNING) << "Found browser id " << info->browser_id() <<
" but no browser object matching view process id " <<
render_process_id << " and routing id " <<
render_routing_id;
}
return browser;
}
return NULL;
}
}
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForHost(
content::RenderViewHost* host) {
content::RenderViewHost* host,
bool* is_guest_view) {
if (is_guest_view)
*is_guest_view = false;
CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForHost(host);
if (!browser.get() && ExtensionsEnabled()) {
// Retrieve the owner browser, if any.
content::WebContents* owner = GetOwnerForGuestContents(
content::WebContents::FromRenderViewHost(host));
if (owner)
if (owner) {
browser = CefBrowserHostImpl::GetBrowserForContents(owner);
if (browser.get() && is_guest_view)
*is_guest_view = true;
}
}
return browser;
}

View File

@ -28,13 +28,19 @@ void GetAllGuestsForOwnerContents(content::WebContents* owner,
content::WebContents* GetOwnerForGuestContents(content::WebContents* guest);
// Returns the CefBrowserHostImpl that owns the host identified by the specified
// view routing IDs, if any.
// view routing IDs, if any. |is_guest_view| will be set to true if the IDs
// match a guest view associated with the returned browser instead of the
// browser itself.
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForView(int render_process_id,
int render_routing_id);
int render_routing_id,
bool* is_guest_view);
// Returns the CefBrowserHostImpl that owns the specified |host|, if any.
// |is_guest_view| will be set to true if the host matches a guest view
// associated with the returned browser instead of the browser itself.
CefRefPtr<CefBrowserHostImpl> GetOwnerBrowserForHost(
content::RenderViewHost* host);
content::RenderViewHost* host,
bool* is_guest_view);
} // namespace extensions

View File

@ -55,18 +55,20 @@ bool CefMimeHandlerViewGuestDelegate::OnGuestAttached(
content::WebContents* web_contents = guest_->web_contents();
DCHECK(web_contents);
// Associate state information with the new WebContents.
content::RenderViewHost* view_host = web_contents->GetRenderViewHost();
content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame();
scoped_refptr<CefBrowserInfo> info =
CefContentBrowserClient::Get()->GetOrCreateBrowserInfo(
view_host->GetProcess()->GetID(),
view_host->GetRoutingID(),
main_frame_host->GetProcess()->GetID(),
main_frame_host->GetRoutingID());
info->set_mime_handler_view(true);
CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_);
// Associate guest state information with the owner browser.
scoped_refptr<CefBrowserInfo> info = owner_browser->browser_info();
info->guest_render_id_manager()->add_render_view_id(
view_host->GetProcess()->GetID(),
view_host->GetRoutingID());
info->guest_render_id_manager()->add_render_frame_id(
main_frame_host->GetProcess()->GetID(),
main_frame_host->GetRoutingID());
if (owner_browser->IsWindowless()) {
// Use the OSR view instead of the default WebContentsViewGuest.
content::WebContentsImpl* web_contents_impl =
@ -85,8 +87,25 @@ bool CefMimeHandlerViewGuestDelegate::OnGuestAttached(
bool CefMimeHandlerViewGuestDelegate::OnGuestDetached(
content::WebContentsView* guest_view,
content::WebContentsView* parent_view) {
content::WebContents* web_contents = guest_->web_contents();
DCHECK(web_contents);
content::RenderViewHost* view_host = web_contents->GetRenderViewHost();
content::RenderFrameHost* main_frame_host = web_contents->GetMainFrame();
CefRefPtr<CefBrowserHostImpl> owner_browser = GetOwnerBrowser(guest_);
// Disassociate guest state information with the owner browser.
scoped_refptr<CefBrowserInfo> info = owner_browser->browser_info();
info->guest_render_id_manager()->remove_render_view_id(
view_host->GetProcess()->GetID(),
view_host->GetRoutingID());
info->guest_render_id_manager()->remove_render_frame_id(
main_frame_host->GetProcess()->GetID(),
main_frame_host->GetRoutingID());
// Do nothing when the browser is windowless.
return GetOwnerBrowser(guest_)->IsWindowless();
return owner_browser->IsWindowless();
}
bool CefMimeHandlerViewGuestDelegate::CreateViewForWidget(

View File

@ -366,7 +366,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
void PopulateWebPreferences(content::RenderViewHost* rvh,
content::WebPreferences& web) {
CefRefPtr<CefBrowserHostImpl> browser =
extensions::GetOwnerBrowserForHost(rvh);
extensions::GetOwnerBrowserForHost(rvh, NULL);
// Set defaults for preferences that are not handled by PrefService.
SetDefaultPrefs(web);

View File

@ -160,7 +160,9 @@ void CefPrintDialogLinux::OnPrintStart(int render_process_id,
return;
CefRefPtr<CefBrowserHostImpl> browser =
extensions::GetOwnerBrowserForView(render_process_id, render_routing_id);
extensions::GetOwnerBrowserForView(render_process_id,
render_routing_id,
NULL);
if (browser.get())
handler->OnPrintStart(browser.get());
}

View File

@ -202,7 +202,7 @@ IPC_STRUCT_BEGIN(CefProcessHostMsg_GetNewBrowserInfo_Params)
IPC_STRUCT_MEMBER(int, browser_id)
IPC_STRUCT_MEMBER(bool, is_popup)
IPC_STRUCT_MEMBER(bool, is_windowless)
IPC_STRUCT_MEMBER(bool, is_mime_handler_view)
IPC_STRUCT_MEMBER(bool, is_guest_view)
IPC_STRUCT_END()
// Retrieve information about a newly created browser.

View File

@ -920,8 +920,8 @@ void CefContentRendererClient::BrowserCreated(
&params));
DCHECK_GT(params.browser_id, 0);
if (params.is_mime_handler_view) {
// Don't create a CefBrowser for mime handler views.
if (params.is_guest_view) {
// Don't create a CefBrowser for guest views.
return;
}

View File

@ -459,7 +459,8 @@ bool ClientHandler::OnOpenURLFromTab(
const CefString& target_url,
CefRequestHandler::WindowOpenDisposition target_disposition,
bool user_gesture) {
if (user_gesture && target_disposition == WOD_NEW_BACKGROUND_TAB) {
if (target_disposition == WOD_NEW_BACKGROUND_TAB ||
target_disposition == WOD_NEW_FOREGROUND_TAB) {
// Handle middle-click and ctrl + left-click by opening the URL in a new
// browser window.
MainContext::Get()->GetRootWindowManager()->CreateRootWindow(