mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-28 09:57:50 +01:00
chrome: cefclient: Add support for --request-context-per-browser
Wait for the OnRequestContextInitialized callback before using a non-global CefRequestContext. Use default handling of --load-extension for Chrome runtime (fixes #3529).
This commit is contained in:
parent
36e4ef1673
commit
b7e35d2878
@ -96,10 +96,21 @@ class RootWindow
|
||||
// of this class will be called on the main thread.
|
||||
class Delegate {
|
||||
public:
|
||||
// Called to retrieve the CefRequestContext for browser. Only called for
|
||||
// non-popup browsers. May return nullptr.
|
||||
virtual CefRefPtr<CefRequestContext> GetRequestContext(
|
||||
RootWindow* root_window) = 0;
|
||||
// Called to synchronously retrieve the CefRequestContext for browser. Only
|
||||
// called for non-popup browsers. Must be called on the main thread. With
|
||||
// the Chrome runtime this method is only safe when using the global request
|
||||
// context.
|
||||
// TODO: Delete this method and use the async version instead.
|
||||
virtual CefRefPtr<CefRequestContext> GetRequestContext() = 0;
|
||||
|
||||
using RequestContextCallback =
|
||||
base::OnceCallback<void(CefRefPtr<CefRequestContext>)>;
|
||||
|
||||
// Called to asynchronously retrieve the CefRequestContext for browser. Only
|
||||
// called for non-popup browsers. Save to call on any thread. |callback|
|
||||
// will be executed on the UI thread after the request context is
|
||||
// initialized.
|
||||
virtual void GetRequestContext(RequestContextCallback callback) = 0;
|
||||
|
||||
// Returns the ImageCache.
|
||||
virtual scoped_refptr<ImageCache> GetImageCache() = 0;
|
||||
|
@ -443,7 +443,7 @@ void RootWindowGtk::CreateRootWindow(const CefBrowserSettings& settings,
|
||||
if (!is_popup_) {
|
||||
// Create the browser window.
|
||||
browser_window_->CreateBrowser(parent, browser_bounds_, settings, nullptr,
|
||||
delegate_->GetRequestContext(this));
|
||||
delegate_->GetRequestContext());
|
||||
} else {
|
||||
// With popups we already have a browser window. Parent the browser window
|
||||
// to the root window and show it in the correct location.
|
||||
|
@ -620,8 +620,7 @@ void RootWindowMacImpl::CreateRootWindow(const CefBrowserSettings& settings,
|
||||
browser_window_->CreateBrowser(
|
||||
CAST_NSVIEW_TO_CEF_WINDOW_HANDLE(contentView),
|
||||
CefRect(0, 0, contentBounds.size.width, contentBounds.size.height),
|
||||
settings, nullptr,
|
||||
root_window_.delegate_->GetRequestContext(&root_window_));
|
||||
settings, nullptr, root_window_.delegate_->GetRequestContext());
|
||||
} else {
|
||||
// With popups we already have a browser window. Parent the browser window
|
||||
// to the root window and show it in the correct location.
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "include/base/cef_callback.h"
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "tests/cefclient/browser/client_handler_std.h"
|
||||
#include "tests/cefclient/browser/main_context.h"
|
||||
@ -24,26 +25,30 @@ namespace {
|
||||
class ClientRequestContextHandler : public CefRequestContextHandler,
|
||||
public CefExtensionHandler {
|
||||
public:
|
||||
ClientRequestContextHandler() = default;
|
||||
using CreateCallback = RootWindow::Delegate::RequestContextCallback;
|
||||
|
||||
explicit ClientRequestContextHandler(CreateCallback callback)
|
||||
: create_callback_(std::move(callback)) {}
|
||||
|
||||
// CefRequestContextHandler methods:
|
||||
void OnRequestContextInitialized(
|
||||
CefRefPtr<CefRequestContext> request_context) override {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
const auto main_context = MainContext::Get();
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
if (command_line->HasSwitch(switches::kLoadExtension)) {
|
||||
if (MainContext::Get()
|
||||
->GetRootWindowManager()
|
||||
->request_context_per_browser()) {
|
||||
|
||||
if (!main_context->UseChromeRuntime() &&
|
||||
command_line->HasSwitch(switches::kLoadExtension)) {
|
||||
// Alloy implementation for loading extensions. Chrome runtime handles
|
||||
// this internally.
|
||||
if (main_context->GetRootWindowManager()->request_context_per_browser()) {
|
||||
// The example extension loading implementation requires all browsers to
|
||||
// share the same request context.
|
||||
LOG(ERROR)
|
||||
<< "Cannot mix --load-extension and --request-context-per-browser";
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Load one or more extension paths specified on the command-line and
|
||||
// delimited with semicolon.
|
||||
const std::string& extension_path =
|
||||
@ -58,6 +63,7 @@ class ClientRequestContextHandler : public CefRequestContextHandler,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the startup URL to create popups that bypass the popup blocker.
|
||||
// For example, via Tests > New Popup from the top menu. This applies for
|
||||
@ -67,6 +73,12 @@ class ClientRequestContextHandler : public CefRequestContextHandler,
|
||||
request_context->SetContentSetting(startup_url, startup_url,
|
||||
CEF_CONTENT_SETTING_TYPE_POPUPS,
|
||||
CEF_CONTENT_SETTING_VALUE_ALLOW);
|
||||
|
||||
if (!create_callback_.is_null()) {
|
||||
// Execute the callback asynchronously.
|
||||
CefPostTask(TID_UI,
|
||||
base::BindOnce(std::move(create_callback_), request_context));
|
||||
}
|
||||
}
|
||||
|
||||
// CefExtensionHandler methods:
|
||||
@ -95,6 +107,8 @@ class ClientRequestContextHandler : public CefRequestContextHandler,
|
||||
}
|
||||
|
||||
private:
|
||||
CreateCallback create_callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(ClientRequestContextHandler);
|
||||
DISALLOW_COPY_AND_ASSIGN(ClientRequestContextHandler);
|
||||
};
|
||||
@ -324,11 +338,33 @@ void RootWindowManager::NotifyExtensionsChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefRequestContext> RootWindowManager::GetRequestContext(
|
||||
RootWindow* root_window) {
|
||||
CefRefPtr<CefRequestContext> RootWindowManager::GetRequestContext() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
return CreateRequestContext(RequestContextCallback());
|
||||
}
|
||||
|
||||
void RootWindowManager::GetRequestContext(RequestContextCallback callback) {
|
||||
DCHECK(!callback.is_null());
|
||||
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute on the main thread.
|
||||
MAIN_POST_CLOSURE(base::BindOnce(
|
||||
base::IgnoreResult(&RootWindowManager::CreateRequestContext),
|
||||
base::Unretained(this), std::move(callback)));
|
||||
} else {
|
||||
CreateRequestContext(std::move(callback));
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefRequestContext> RootWindowManager::CreateRequestContext(
|
||||
RequestContextCallback callback) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (request_context_per_browser_) {
|
||||
// Synchronous use of non-global request contexts is not safe with the
|
||||
// Chrome runtime.
|
||||
CHECK(!callback.is_null() || !MainContext::Get()->UseChromeRuntime());
|
||||
|
||||
// Create a new request context for each browser.
|
||||
CefRequestContextSettings settings;
|
||||
|
||||
@ -350,15 +386,21 @@ CefRefPtr<CefRequestContext> RootWindowManager::GetRequestContext(
|
||||
}
|
||||
}
|
||||
|
||||
return CefRequestContext::CreateContext(settings,
|
||||
new ClientRequestContextHandler);
|
||||
return CefRequestContext::CreateContext(
|
||||
settings, new ClientRequestContextHandler(std::move(callback)));
|
||||
}
|
||||
|
||||
// All browsers will share the global request context.
|
||||
if (!shared_request_context_.get()) {
|
||||
if (!shared_request_context_) {
|
||||
shared_request_context_ = CefRequestContext::CreateContext(
|
||||
CefRequestContext::GetGlobalContext(), new ClientRequestContextHandler);
|
||||
CefRequestContext::GetGlobalContext(),
|
||||
new ClientRequestContextHandler(std::move(callback)));
|
||||
} else if (!callback.is_null()) {
|
||||
// Execute the callback on the UI thread.
|
||||
CefPostTask(TID_UI,
|
||||
base::BindOnce(std::move(callback), shared_request_context_));
|
||||
}
|
||||
|
||||
return shared_request_context_;
|
||||
}
|
||||
|
||||
|
@ -94,8 +94,8 @@ class RootWindowManager : public RootWindow::Delegate {
|
||||
void NotifyExtensionsChanged();
|
||||
|
||||
// RootWindow::Delegate methods.
|
||||
CefRefPtr<CefRequestContext> GetRequestContext(
|
||||
RootWindow* root_window) override;
|
||||
CefRefPtr<CefRequestContext> GetRequestContext() override;
|
||||
void GetRequestContext(RequestContextCallback callback) override;
|
||||
scoped_refptr<ImageCache> GetImageCache() override;
|
||||
void OnTest(RootWindow* root_window, int test_id) override;
|
||||
void OnExit(RootWindow* root_window) override;
|
||||
@ -109,6 +109,10 @@ class RootWindowManager : public RootWindow::Delegate {
|
||||
base::OnceClosure close_callback,
|
||||
bool with_osr) override;
|
||||
|
||||
// |callback| may be nullptr. Must be called on the main thread.
|
||||
CefRefPtr<CefRequestContext> CreateRequestContext(
|
||||
RequestContextCallback callback);
|
||||
|
||||
void CleanupOnUIThread();
|
||||
|
||||
const bool terminate_when_all_windows_closed_;
|
||||
|
@ -58,20 +58,14 @@ void RootWindowViews::Init(RootWindow::Delegate* delegate,
|
||||
CreateClientHandler(config_->url);
|
||||
initialized_ = true;
|
||||
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute GetRequestContext() on the main thread.
|
||||
MAIN_POST_CLOSURE(base::BindOnce(
|
||||
delegate_->GetRequestContext(base::BindOnce(
|
||||
[](scoped_refptr<RootWindowViews> self,
|
||||
const CefBrowserSettings& settings) {
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefRequestContext> request_context) {
|
||||
// Continue initialization on the UI thread.
|
||||
self->InitOnUIThread(settings,
|
||||
self->delegate_->GetRequestContext(self.get()));
|
||||
self->InitOnUIThread(settings, request_context);
|
||||
},
|
||||
scoped_refptr<RootWindowViews>(this), settings));
|
||||
} else {
|
||||
// Continue initialization on the UI thread.
|
||||
InitOnUIThread(settings, delegate_->GetRequestContext(this));
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowViews::InitAsPopup(RootWindow::Delegate* delegate,
|
||||
|
@ -1015,7 +1015,7 @@ void RootWindowWin::OnCreate(LPCREATESTRUCT lpCreateStruct) {
|
||||
CefRect cef_rect(rect.left, rect.top, rect.right - rect.left,
|
||||
rect.bottom - rect.top);
|
||||
browser_window_->CreateBrowser(hwnd_, cef_rect, browser_settings_, nullptr,
|
||||
delegate_->GetRequestContext(this));
|
||||
delegate_->GetRequestContext());
|
||||
} else {
|
||||
// With popups we already have a browser window. Parent the browser window
|
||||
// to the root window and show it in the correct location.
|
||||
|
Loading…
x
Reference in New Issue
Block a user