mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
- Pass information to the renderer process synchronously on render thread creation and new browser creation to avoid race conditions (issue #744).
- Add the ability to pass extra information to child processes using a new CefBrowserProcessHandler::OnRenderProcessThreadCreated callback (issue #744). - Fix OnBeforeChildProcessLaunch documentation (issue #754). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@910 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "libcef/browser/browser_context.h"
|
||||
#include "libcef/browser/chrome_scheme_handler.h"
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/devtools_delegate.h"
|
||||
#include "libcef/browser/navigate_params.h"
|
||||
@@ -251,8 +252,10 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int browser_id = _Context->GetNextBrowserID();
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::Create(windowInfo, settings, client, NULL, NULL);
|
||||
CefBrowserHostImpl::Create(windowInfo, settings, client, NULL, browser_id,
|
||||
NULL);
|
||||
if (!url.empty())
|
||||
browser->LoadURL(CefFrameHostImpl::kMainFrameId, url);
|
||||
return browser.get();
|
||||
@@ -268,6 +271,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
content::WebContents* web_contents,
|
||||
int browser_id,
|
||||
CefWindowHandle opener) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
@@ -281,7 +285,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::Create(
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
new CefBrowserHostImpl(window_info, settings, client, web_contents,
|
||||
opener);
|
||||
browser_id, opener);
|
||||
if (!browser->PlatformCreateWindow())
|
||||
return NULL;
|
||||
|
||||
@@ -561,7 +565,7 @@ void CefBrowserHostImpl::StopLoad() {
|
||||
}
|
||||
|
||||
int CefBrowserHostImpl::GetIdentifier() {
|
||||
return unique_id();
|
||||
return browser_id();
|
||||
}
|
||||
|
||||
bool CefBrowserHostImpl::IsPopup() {
|
||||
@@ -669,12 +673,6 @@ bool CefBrowserHostImpl::SendProcessMessage(
|
||||
// CefBrowserHostImpl public methods.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void CefBrowserHostImpl::SetUniqueId(int unique_id) {
|
||||
CEF_REQUIRE_UIT();
|
||||
unique_id_ = unique_id;
|
||||
Send(new CefMsg_UpdateBrowserWindowId(routing_id(), unique_id, IsPopup()));
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DestroyBrowser() {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
@@ -1218,9 +1216,16 @@ void CefBrowserHostImpl::WebContentsCreated(
|
||||
if (source_contents)
|
||||
opener = GetBrowserForContents(source_contents)->GetWindowHandle();
|
||||
|
||||
CefContentBrowserClient::NewPopupBrowserInfo info;
|
||||
CefContentBrowserClient::Get()->GetNewPopupBrowserInfo(
|
||||
new_contents->GetRenderProcessHost()->GetID(),
|
||||
new_contents->GetRoutingID(),
|
||||
&info);
|
||||
DCHECK_GT(info.browser_id, 0);
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser = CefBrowserHostImpl::Create(
|
||||
pending_window_info_, pending_settings_, pending_client_, new_contents,
|
||||
opener);
|
||||
info.browser_id, opener);
|
||||
|
||||
pending_client_ = NULL;
|
||||
}
|
||||
@@ -1288,6 +1293,12 @@ void CefBrowserHostImpl::RenderViewDeleted(
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::RenderViewReady() {
|
||||
if (IsPopup()) {
|
||||
CefContentBrowserClient::Get()->ClearNewPopupBrowserInfo(
|
||||
web_contents()->GetRenderProcessHost()->GetID(),
|
||||
web_contents()->GetRoutingID());
|
||||
}
|
||||
|
||||
// Send the queued messages.
|
||||
queue_messages_ = false;
|
||||
while (!queued_messages_.empty()) {
|
||||
@@ -1511,15 +1522,16 @@ CefBrowserHostImpl::CefBrowserHostImpl(const CefWindowInfo& window_info,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
content::WebContents* web_contents,
|
||||
int browser_id,
|
||||
CefWindowHandle opener)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
window_info_(window_info),
|
||||
settings_(settings),
|
||||
client_(client),
|
||||
browser_id_(browser_id),
|
||||
opener_(opener),
|
||||
render_process_id_(0),
|
||||
render_view_id_(0),
|
||||
unique_id_(0),
|
||||
render_process_id_(MSG_ROUTING_NONE),
|
||||
render_view_id_(MSG_ROUTING_NONE),
|
||||
is_loading_(false),
|
||||
can_go_back_(false),
|
||||
can_go_forward_(false),
|
||||
|
@@ -78,6 +78,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
content::WebContents* web_contents,
|
||||
int browser_id,
|
||||
CefWindowHandle opener);
|
||||
|
||||
// Returns the browser associated with the specified RenderViewHost.
|
||||
@@ -138,9 +139,6 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
CefProcessId target_process,
|
||||
CefRefPtr<CefProcessMessage> message) OVERRIDE;
|
||||
|
||||
// Set the unique identifier for this browser.
|
||||
void SetUniqueId(int unique_id);
|
||||
|
||||
// Destroy the browser members. This method should only be called after the
|
||||
// native browser window is not longer processing messages.
|
||||
void DestroyBrowser();
|
||||
@@ -198,7 +196,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
// Thread safe accessors.
|
||||
const CefBrowserSettings& settings() const { return settings_; }
|
||||
CefRefPtr<CefClient> client() const { return client_; }
|
||||
int unique_id() const { return unique_id_; }
|
||||
int browser_id() const { return browser_id_; }
|
||||
|
||||
// Returns the URL that is currently loading (or loaded) in the main frame.
|
||||
GURL GetLoadingURL();
|
||||
@@ -323,6 +321,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
content::WebContents* web_contents,
|
||||
int browser_id,
|
||||
CefWindowHandle opener);
|
||||
|
||||
// Initialize settings based on the specified RenderViewHost.
|
||||
@@ -398,6 +397,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
CefBrowserSettings settings_;
|
||||
CefRefPtr<CefClient> client_;
|
||||
scoped_ptr<content::WebContents> web_contents_;
|
||||
int browser_id_;
|
||||
CefWindowHandle opener_;
|
||||
|
||||
// Unique ids used for routing communication to/from the renderer. We keep a
|
||||
@@ -406,9 +406,6 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
int render_process_id_;
|
||||
int render_view_id_;
|
||||
|
||||
// Unique id for the browser.
|
||||
int unique_id_;
|
||||
|
||||
// Used when creating a new popup window.
|
||||
CefWindowInfo pending_window_info_;
|
||||
CefBrowserSettings pending_settings_;
|
||||
|
@@ -5,12 +5,17 @@
|
||||
|
||||
#include "libcef/browser/browser_message_filter.h"
|
||||
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/content_browser_client.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/origin_whitelist_impl.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/cef_messages.h"
|
||||
#include "libcef/common/values_impl.h"
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/bind.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
|
||||
CefBrowserMessageFilter::CefBrowserMessageFilter(
|
||||
content::RenderProcessHost* host)
|
||||
@@ -31,22 +36,50 @@ void CefBrowserMessageFilter::OnFilterRemoved() {
|
||||
bool CefBrowserMessageFilter::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(CefBrowserMessageFilter, message)
|
||||
IPC_MESSAGE_HANDLER(CefProcessHostMsg_RenderThreadStarted,
|
||||
OnRenderThreadStarted)
|
||||
IPC_MESSAGE_HANDLER(CefProcessHostMsg_GetNewRenderThreadInfo,
|
||||
OnGetNewRenderThreadInfo)
|
||||
IPC_MESSAGE_HANDLER(CefProcessHostMsg_GetNewBrowserInfo,
|
||||
OnGetNewBrowserInfo)
|
||||
IPC_MESSAGE_UNHANDLED(handled = false)
|
||||
IPC_END_MESSAGE_MAP()
|
||||
return handled;
|
||||
}
|
||||
|
||||
void CefBrowserMessageFilter::OnRenderThreadStarted() {
|
||||
// Execute registration on the UI thread.
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefBrowserMessageFilter::RegisterOnUIThread, this));
|
||||
bool CefBrowserMessageFilter::Send(IPC::Message* message) {
|
||||
return host_->Send(message);
|
||||
}
|
||||
|
||||
void CefBrowserMessageFilter::RegisterOnUIThread() {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
// Send existing registrations to the new render process.
|
||||
RegisterCrossOriginWhitelistEntriesWithHost(host_);
|
||||
void CefBrowserMessageFilter::OnGetNewRenderThreadInfo(
|
||||
CefProcessHostMsg_GetNewRenderThreadInfo_Params* params) {
|
||||
GetCrossOriginWhitelistEntries(¶ms->cross_origin_whitelist_entries);
|
||||
|
||||
CefRefPtr<CefApp> app = _Context->application();
|
||||
if (app.get()) {
|
||||
CefRefPtr<CefBrowserProcessHandler> handler =
|
||||
app->GetBrowserProcessHandler();
|
||||
if (handler.get()) {
|
||||
CefRefPtr<CefListValueImpl> listValuePtr(
|
||||
new CefListValueImpl(¶ms->extra_info, false, false));
|
||||
handler->OnRenderProcessThreadCreated(listValuePtr.get());
|
||||
listValuePtr->Detach(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserMessageFilter::OnGetNewBrowserInfo(
|
||||
int routing_id, CefProcessHostMsg_GetNewBrowserInfo_Params* params) {
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::GetBrowserByRoutingID(host_->GetID(), routing_id);
|
||||
if (browser.get()) {
|
||||
params->browser_id = browser->GetIdentifier();
|
||||
params->is_popup = browser->IsPopup();
|
||||
} else {
|
||||
CefContentBrowserClient::NewPopupBrowserInfo info;
|
||||
CefContentBrowserClient::Get()->GetNewPopupBrowserInfo(host_->GetID(),
|
||||
routing_id,
|
||||
&info);
|
||||
DCHECK_GT(info.browser_id, 0);
|
||||
params->browser_id = info.browser_id;
|
||||
params->is_popup = true;
|
||||
}
|
||||
}
|
||||
|
@@ -13,6 +13,9 @@ namespace content {
|
||||
class RenderProcessHost;
|
||||
}
|
||||
|
||||
struct CefProcessHostMsg_GetNewBrowserInfo_Params;
|
||||
struct CefProcessHostMsg_GetNewRenderThreadInfo_Params;
|
||||
|
||||
// This class sends and receives control messages on the browser process.
|
||||
class CefBrowserMessageFilter : public IPC::ChannelProxy::MessageFilter {
|
||||
public:
|
||||
@@ -24,11 +27,14 @@ class CefBrowserMessageFilter : public IPC::ChannelProxy::MessageFilter {
|
||||
virtual void OnFilterRemoved() OVERRIDE;
|
||||
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
|
||||
|
||||
bool Send(IPC::Message* message);
|
||||
|
||||
private:
|
||||
// Message handlers.
|
||||
void OnRenderThreadStarted();
|
||||
|
||||
void RegisterOnUIThread();
|
||||
void OnGetNewRenderThreadInfo(
|
||||
CefProcessHostMsg_GetNewRenderThreadInfo_Params* params);
|
||||
void OnGetNewBrowserInfo(int routing_id,
|
||||
CefProcessHostMsg_GetNewBrowserInfo_Params* params);
|
||||
|
||||
content::RenderProcessHost* host_;
|
||||
IPC::Channel* channel_;
|
||||
|
@@ -247,6 +247,44 @@ CefContentBrowserClient::CefContentBrowserClient()
|
||||
CefContentBrowserClient::~CefContentBrowserClient() {
|
||||
}
|
||||
|
||||
// static
|
||||
CefContentBrowserClient* CefContentBrowserClient::Get() {
|
||||
return static_cast<CefContentBrowserClient*>(
|
||||
content::GetContentClient()->browser());
|
||||
}
|
||||
|
||||
void CefContentBrowserClient::GetNewPopupBrowserInfo(
|
||||
int render_process_id, int render_view_id, NewPopupBrowserInfo* info) {
|
||||
base::AutoLock lock_scope(new_popup_browser_lock_);
|
||||
|
||||
NewPopupBrowserInfoMap::const_iterator it =
|
||||
new_popup_browser_info_map_.find(
|
||||
std::make_pair(render_process_id, render_view_id));
|
||||
if (it != new_popup_browser_info_map_.end()) {
|
||||
*info = it->second;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the info now.
|
||||
NewPopupBrowserInfo new_info;
|
||||
new_info.browser_id = _Context->GetNextBrowserID();
|
||||
new_popup_browser_info_map_.insert(
|
||||
std::make_pair(
|
||||
std::make_pair(render_process_id, render_view_id), new_info));
|
||||
*info = new_info;
|
||||
}
|
||||
|
||||
void CefContentBrowserClient::ClearNewPopupBrowserInfo(int render_process_id,
|
||||
int render_view_id) {
|
||||
base::AutoLock lock_scope(new_popup_browser_lock_);
|
||||
|
||||
NewPopupBrowserInfoMap::iterator it =
|
||||
new_popup_browser_info_map_.find(
|
||||
std::make_pair(render_process_id, render_view_id));
|
||||
if (it != new_popup_browser_info_map_.end())
|
||||
new_popup_browser_info_map_.erase(it);
|
||||
}
|
||||
|
||||
content::BrowserMainParts* CefContentBrowserClient::CreateBrowserMainParts(
|
||||
const content::MainFunctionParams& parameters) {
|
||||
browser_main_parts_ = new CefBrowserMainParts(parameters);
|
||||
|
@@ -6,12 +6,14 @@
|
||||
#define CEF_LIBCEF_BROWSER_CONTENT_BROWSER_CLIENT_H_
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "content/public/browser/content_browser_client.h"
|
||||
|
||||
class CefBrowserMainParts;
|
||||
@@ -28,10 +30,29 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
||||
CefContentBrowserClient();
|
||||
virtual ~CefContentBrowserClient();
|
||||
|
||||
// Returns the singleton CefContentBrowserClient instance.
|
||||
static CefContentBrowserClient* Get();
|
||||
|
||||
CefBrowserMainParts* browser_main_parts() const {
|
||||
return browser_main_parts_;
|
||||
}
|
||||
|
||||
// During popup window creation there is a race between the call to
|
||||
// CefBrowserMessageFilter::OnGetNewBrowserInfo on the IO thread and the call
|
||||
// to CefBrowserHostImpl::WebContentsCreated on the UI thread. To resolve this
|
||||
// race we create the info when requested for the first time.
|
||||
class NewPopupBrowserInfo {
|
||||
public:
|
||||
NewPopupBrowserInfo()
|
||||
: browser_id(0) {}
|
||||
int browser_id;
|
||||
};
|
||||
void GetNewPopupBrowserInfo(int render_process_id,
|
||||
int render_view_id,
|
||||
NewPopupBrowserInfo* info);
|
||||
void ClearNewPopupBrowserInfo(int render_process_id,
|
||||
int render_view_id);
|
||||
|
||||
virtual content::BrowserMainParts* CreateBrowserMainParts(
|
||||
const content::MainFunctionParams& parameters) OVERRIDE;
|
||||
virtual void RenderProcessHostCreated(
|
||||
@@ -60,6 +81,14 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
||||
scoped_ptr<content::PluginServiceFilter> plugin_service_filter_;
|
||||
scoped_ptr<CefResourceDispatcherHostDelegate>
|
||||
resource_dispatcher_host_delegate_;
|
||||
|
||||
base::Lock new_popup_browser_lock_;
|
||||
|
||||
// Map of (render_process_id, render_view_id) to info. Access must be
|
||||
// protected by |new_popup_browser_lock_|.
|
||||
typedef std::map<std::pair<int, int>, NewPopupBrowserInfo>
|
||||
NewPopupBrowserInfoMap;
|
||||
NewPopupBrowserInfoMap new_popup_browser_info_map_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_CONTENT_BROWSER_CLIENT_H_
|
||||
|
@@ -167,8 +167,7 @@ void CefQuitMessageLoop() {
|
||||
CefContext::CefContext()
|
||||
: initialized_(false),
|
||||
shutting_down_(false),
|
||||
init_thread_id_(0),
|
||||
next_browser_id_(kNextBrowserIdReset) {
|
||||
init_thread_id_(0) {
|
||||
}
|
||||
|
||||
CefContext::~CefContext() {
|
||||
@@ -271,48 +270,26 @@ bool CefContext::OnInitThread() {
|
||||
return (base::PlatformThread::CurrentId() == init_thread_id_);
|
||||
}
|
||||
|
||||
bool CefContext::AddBrowser(CefRefPtr<CefBrowserHostImpl> browser) {
|
||||
bool found = false;
|
||||
int CefContext::GetNextBrowserID() {
|
||||
return next_browser_id_.GetNext() + 1;
|
||||
}
|
||||
|
||||
void CefContext::AddBrowser(CefRefPtr<CefBrowserHostImpl> browser) {
|
||||
AutoLock lock_scope(this);
|
||||
|
||||
// check that the browser isn't already in the list before adding
|
||||
BrowserList::const_iterator it = browserlist_.begin();
|
||||
browserlist_.push_back(browser);
|
||||
}
|
||||
|
||||
void CefContext::RemoveBrowser(CefRefPtr<CefBrowserHostImpl> browser) {
|
||||
AutoLock lock_scope(this);
|
||||
|
||||
BrowserList::iterator it = browserlist_.begin();
|
||||
for (; it != browserlist_.end(); ++it) {
|
||||
if (it->get() == browser.get()) {
|
||||
found = true;
|
||||
browserlist_.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
browser->SetUniqueId(next_browser_id_++);
|
||||
browserlist_.push_back(browser);
|
||||
}
|
||||
|
||||
return !found;
|
||||
}
|
||||
|
||||
bool CefContext::RemoveBrowser(CefRefPtr<CefBrowserHostImpl> browser) {
|
||||
bool deleted = false;
|
||||
|
||||
{
|
||||
AutoLock lock_scope(this);
|
||||
|
||||
BrowserList::iterator it = browserlist_.begin();
|
||||
for (; it != browserlist_.end(); ++it) {
|
||||
if (it->get() == browser.get()) {
|
||||
browserlist_.erase(it);
|
||||
deleted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (browserlist_.empty())
|
||||
next_browser_id_ = kNextBrowserIdReset;
|
||||
}
|
||||
|
||||
return deleted;
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> CefContext::GetBrowserByID(int id) {
|
||||
@@ -320,7 +297,7 @@ CefRefPtr<CefBrowserHostImpl> CefContext::GetBrowserByID(int id) {
|
||||
|
||||
BrowserList::const_iterator it = browserlist_.begin();
|
||||
for (; it != browserlist_.end(); ++it) {
|
||||
if (it->get()->unique_id() == id)
|
||||
if (it->get()->browser_id() == id)
|
||||
return it->get();
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "include/cef_app.h"
|
||||
#include "include/cef_base.h"
|
||||
|
||||
#include "base/atomic_sequence_num.h"
|
||||
#include "base/file_path.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/scoped_temp_dir.h"
|
||||
@@ -54,8 +55,9 @@ class CefContext : public CefBase {
|
||||
// Returns true if the context is shutting down.
|
||||
bool shutting_down() { return shutting_down_; }
|
||||
|
||||
bool AddBrowser(CefRefPtr<CefBrowserHostImpl> browser);
|
||||
bool RemoveBrowser(CefRefPtr<CefBrowserHostImpl> browser);
|
||||
int GetNextBrowserID();
|
||||
void AddBrowser(CefRefPtr<CefBrowserHostImpl> browser);
|
||||
void RemoveBrowser(CefRefPtr<CefBrowserHostImpl> browser);
|
||||
CefRefPtr<CefBrowserHostImpl> GetBrowserByID(int id);
|
||||
CefRefPtr<CefBrowserHostImpl> GetBrowserByRoutingID(int render_process_id,
|
||||
int render_view_id);
|
||||
@@ -97,7 +99,7 @@ class CefContext : public CefBase {
|
||||
BrowserList browserlist_;
|
||||
|
||||
// Used for assigning unique IDs to browser instances.
|
||||
int next_browser_id_;
|
||||
base::AtomicSequenceNumber next_browser_id_;
|
||||
|
||||
scoped_ptr<CefMainDelegate> main_delegate_;
|
||||
scoped_ptr<content::ContentMainRunner> main_runner_;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include "libcef/browser/origin_whitelist_impl.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "include/cef_origin_whitelist.h"
|
||||
#include "libcef/browser/context.h"
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "googleurl/src/gurl.h"
|
||||
|
||||
@@ -31,25 +32,26 @@ class CefOriginWhitelistManager {
|
||||
const std::string& target_protocol,
|
||||
const std::string& target_domain,
|
||||
bool allow_target_subdomains) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
OriginInfo info;
|
||||
Cef_CrossOriginWhiteListEntry_Params info;
|
||||
info.source_origin = source_origin;
|
||||
info.target_protocol = target_protocol;
|
||||
info.target_domain = target_domain;
|
||||
info.allow_target_subdomains = allow_target_subdomains;
|
||||
|
||||
// Verify that the origin entry doesn't already exist.
|
||||
OriginList::const_iterator it = origin_list_.begin();
|
||||
for (; it != origin_list_.end(); ++it) {
|
||||
if (it->Equals(info))
|
||||
return false;
|
||||
{
|
||||
base::AutoLock lock_scope(lock_);
|
||||
|
||||
// Verify that the origin entry doesn't already exist.
|
||||
OriginList::const_iterator it = origin_list_.begin();
|
||||
for (; it != origin_list_.end(); ++it) {
|
||||
if (IsEqual(*it, info))
|
||||
return false;
|
||||
}
|
||||
|
||||
origin_list_.push_back(info);
|
||||
}
|
||||
|
||||
origin_list_.push_back(info);
|
||||
|
||||
SendModifyCrossOriginWhitelistEntry(true, source_origin, target_protocol,
|
||||
target_domain, allow_target_subdomains);
|
||||
SendModifyCrossOriginWhitelistEntry(true, info);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -57,9 +59,7 @@ class CefOriginWhitelistManager {
|
||||
const std::string& target_protocol,
|
||||
const std::string& target_domain,
|
||||
bool allow_target_subdomains) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
OriginInfo info;
|
||||
Cef_CrossOriginWhiteListEntry_Params info;
|
||||
info.source_origin = source_origin;
|
||||
info.target_protocol = target_protocol;
|
||||
info.target_domain = target_domain;
|
||||
@@ -67,70 +67,63 @@ class CefOriginWhitelistManager {
|
||||
|
||||
bool found = false;
|
||||
|
||||
OriginList::iterator it = origin_list_.begin();
|
||||
for (; it != origin_list_.end(); ++it) {
|
||||
if (it->Equals(info)) {
|
||||
origin_list_.erase(it);
|
||||
found = true;
|
||||
break;
|
||||
{
|
||||
base::AutoLock lock_scope(lock_);
|
||||
|
||||
OriginList::iterator it = origin_list_.begin();
|
||||
for (; it != origin_list_.end(); ++it) {
|
||||
if (IsEqual(*it, info)) {
|
||||
origin_list_.erase(it);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return false;
|
||||
|
||||
SendModifyCrossOriginWhitelistEntry(false, source_origin, target_protocol,
|
||||
target_domain, allow_target_subdomains);
|
||||
SendModifyCrossOriginWhitelistEntry(false, info);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClearOrigins() {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
origin_list_.clear();
|
||||
{
|
||||
base::AutoLock lock_scope(lock_);
|
||||
origin_list_.clear();
|
||||
}
|
||||
|
||||
SendClearCrossOriginWhitelist();
|
||||
}
|
||||
|
||||
// Send all existing cross-origin registrations to the specified host.
|
||||
void RegisterOriginsWithHost(content::RenderProcessHost* host) {
|
||||
CEF_REQUIRE_UIT();
|
||||
void GetCrossOriginWhitelistEntries(
|
||||
std::vector<Cef_CrossOriginWhiteListEntry_Params>* entries) {
|
||||
base::AutoLock lock_scope(lock_);
|
||||
|
||||
if (origin_list_.empty())
|
||||
return;
|
||||
|
||||
OriginList::const_iterator it = origin_list_.begin();
|
||||
for (; it != origin_list_.end(); ++it) {
|
||||
host->Send(
|
||||
new CefProcessMsg_ModifyCrossOriginWhitelistEntry(
|
||||
true, it->source_origin, it->target_protocol, it->target_domain,
|
||||
it->allow_target_subdomains));
|
||||
}
|
||||
entries->insert(entries->end(), origin_list_.begin(), origin_list_.end());
|
||||
}
|
||||
|
||||
private:
|
||||
// Send the modify cross-origin whitelist entry message to all currently
|
||||
// existing hosts.
|
||||
void SendModifyCrossOriginWhitelistEntry(bool add,
|
||||
const std::string& source_origin,
|
||||
const std::string& target_protocol,
|
||||
const std::string& target_domain,
|
||||
bool allow_target_subdomains) {
|
||||
static void SendModifyCrossOriginWhitelistEntry(
|
||||
bool add,
|
||||
Cef_CrossOriginWhiteListEntry_Params& params) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
content::RenderProcessHost::iterator i(
|
||||
content::RenderProcessHost::AllHostsIterator());
|
||||
for (; !i.IsAtEnd(); i.Advance()) {
|
||||
i.GetCurrentValue()->Send(
|
||||
new CefProcessMsg_ModifyCrossOriginWhitelistEntry(
|
||||
add, source_origin, target_protocol, target_domain,
|
||||
allow_target_subdomains));
|
||||
new CefProcessMsg_ModifyCrossOriginWhitelistEntry(add, params));
|
||||
}
|
||||
}
|
||||
|
||||
// Send the clear cross-origin whitelists message to all currently existing
|
||||
// hosts.
|
||||
void SendClearCrossOriginWhitelist() {
|
||||
static void SendClearCrossOriginWhitelist() {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
content::RenderProcessHost::iterator i(
|
||||
@@ -140,22 +133,18 @@ class CefOriginWhitelistManager {
|
||||
}
|
||||
}
|
||||
|
||||
struct OriginInfo {
|
||||
std::string source_origin;
|
||||
std::string target_protocol;
|
||||
std::string target_domain;
|
||||
bool allow_target_subdomains;
|
||||
static bool IsEqual(const Cef_CrossOriginWhiteListEntry_Params& param1,
|
||||
const Cef_CrossOriginWhiteListEntry_Params& param2) {
|
||||
return (param1.source_origin == param2.source_origin &&
|
||||
param1.target_protocol == param2.target_protocol &&
|
||||
param1.target_domain == param2.target_domain &&
|
||||
param1.allow_target_subdomains == param2.allow_target_subdomains);
|
||||
}
|
||||
|
||||
bool Equals(const OriginInfo& info) const {
|
||||
return (source_origin == info.source_origin &&
|
||||
target_protocol == info.target_protocol &&
|
||||
target_domain == info.target_domain &&
|
||||
allow_target_subdomains == info.allow_target_subdomains);
|
||||
}
|
||||
};
|
||||
base::Lock lock_;
|
||||
|
||||
// List of registered origins.
|
||||
typedef std::list<OriginInfo> OriginList;
|
||||
// List of registered origins. Access must be protected by |lock_|.
|
||||
typedef std::vector<Cef_CrossOriginWhiteListEntry_Params> OriginList;
|
||||
OriginList origin_list_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CefOriginWhitelistManager);
|
||||
@@ -247,8 +236,8 @@ bool CefClearCrossOriginWhitelist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RegisterCrossOriginWhitelistEntriesWithHost(
|
||||
content::RenderProcessHost* host) {
|
||||
CEF_REQUIRE_UIT();
|
||||
CefOriginWhitelistManager::GetInstance()->RegisterOriginsWithHost(host);
|
||||
void GetCrossOriginWhitelistEntries(
|
||||
std::vector<Cef_CrossOriginWhiteListEntry_Params>* entries) {
|
||||
CefOriginWhitelistManager::GetInstance()->GetCrossOriginWhitelistEntries(
|
||||
entries);
|
||||
}
|
||||
|
@@ -5,13 +5,17 @@
|
||||
#ifndef CEF_LIBCEF_BROWSER_ORIGIN_WHITELIST_IMPL_H_
|
||||
#define CEF_LIBCEF_BROWSER_ORIGIN_WHITELIST_IMPL_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace content {
|
||||
class RenderProcessHost;
|
||||
}
|
||||
|
||||
// Called when a new RenderProcessHost is created to send existing cross-origin
|
||||
// whitelist entry information.
|
||||
void RegisterCrossOriginWhitelistEntriesWithHost(
|
||||
content::RenderProcessHost* host);
|
||||
struct Cef_CrossOriginWhiteListEntry_Params;
|
||||
|
||||
// Called to retrieve the current list of cross-origin white list entries. This
|
||||
// method is thread safe.
|
||||
void GetCrossOriginWhitelistEntries(
|
||||
std::vector<Cef_CrossOriginWhiteListEntry_Params>* entries);
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_ORIGIN_WHITELIST_IMPL_H_
|
||||
|
Reference in New Issue
Block a user