- Update to Chromium revision 131752.
- Add support for multi_threaded_message_loop run mode on Windows (issue #522). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@586 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
1cd6e3b3e7
commit
9d200c109a
|
@ -37,17 +37,17 @@ CefBrowserMainParts::CefBrowserMainParts(
|
|||
const content::MainFunctionParams& parameters)
|
||||
: BrowserMainParts(),
|
||||
devtools_delegate_(NULL) {
|
||||
CefContentBrowserClient* browser_client =
|
||||
static_cast<CefContentBrowserClient*>(
|
||||
content::GetContentClient()->browser());
|
||||
browser_client->set_browser_main_parts(this);
|
||||
}
|
||||
|
||||
CefBrowserMainParts::~CefBrowserMainParts() {
|
||||
}
|
||||
|
||||
MessageLoop* CefBrowserMainParts::GetMainMessageLoop() {
|
||||
return new CefBrowserMessageLoop();
|
||||
void CefBrowserMainParts::PreMainMessageLoopStart() {
|
||||
if (!MessageLoop::current()) {
|
||||
// Create the browser message loop.
|
||||
message_loop_.reset(new CefBrowserMessageLoop());
|
||||
message_loop_->set_thread_name("CrBrowserMain");
|
||||
}
|
||||
}
|
||||
|
||||
int CefBrowserMainParts::PreCreateThreads() {
|
||||
|
|
|
@ -25,6 +25,7 @@ struct MainFunctionParams;
|
|||
|
||||
class CefBrowserContext;
|
||||
class CefDevToolsDelegate;
|
||||
class MessageLoop;
|
||||
|
||||
class CefBrowserMainParts : public content::BrowserMainParts {
|
||||
public:
|
||||
|
@ -33,8 +34,7 @@ class CefBrowserMainParts : public content::BrowserMainParts {
|
|||
|
||||
virtual void PreEarlyInitialization() OVERRIDE {}
|
||||
virtual void PostEarlyInitialization() OVERRIDE {}
|
||||
virtual void PreMainMessageLoopStart() OVERRIDE {}
|
||||
virtual MessageLoop* GetMainMessageLoop() OVERRIDE;
|
||||
virtual void PreMainMessageLoopStart() OVERRIDE;
|
||||
virtual void PostMainMessageLoopStart() OVERRIDE {}
|
||||
virtual void ToolkitInitialized() OVERRIDE {}
|
||||
virtual int PreCreateThreads() OVERRIDE;
|
||||
|
@ -52,6 +52,7 @@ class CefBrowserMainParts : public content::BrowserMainParts {
|
|||
|
||||
scoped_ptr<CefBrowserContext> browser_context_;
|
||||
|
||||
scoped_ptr<MessageLoop> message_loop_;
|
||||
scoped_ptr<ui::Clipboard> clipboard_;
|
||||
CefDevToolsDelegate* devtools_delegate_;
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "base/string_piece.h"
|
||||
|
||||
void CefBrowserMainParts::PlatformInitialize() {
|
||||
gtk_init(NULL, NULL);
|
||||
}
|
||||
|
||||
void CefBrowserMainParts::PlatformCleanup() {
|
||||
|
|
|
@ -73,7 +73,8 @@ CefContentBrowserClient::~CefContentBrowserClient() {
|
|||
|
||||
content::BrowserMainParts* CefContentBrowserClient::CreateBrowserMainParts(
|
||||
const content::MainFunctionParams& parameters) {
|
||||
return new CefBrowserMainParts(parameters);
|
||||
browser_main_parts_ = new CefBrowserMainParts(parameters);
|
||||
return browser_main_parts_;
|
||||
}
|
||||
|
||||
content::WebContentsView*
|
||||
|
|
|
@ -26,9 +26,6 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
|||
CefContentBrowserClient();
|
||||
virtual ~CefContentBrowserClient();
|
||||
|
||||
void set_browser_main_parts(CefBrowserMainParts* parts) {
|
||||
browser_main_parts_ = parts;
|
||||
}
|
||||
CefBrowserMainParts* browser_main_parts() const {
|
||||
return browser_main_parts_;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "base/bind.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "content/public/app/content_main.h"
|
||||
#include "content/public/app/content_main_runner.h"
|
||||
|
@ -37,23 +36,6 @@ const int kNextBrowserIdReset = 1;
|
|||
// Global CefContext pointer
|
||||
CefRefPtr<CefContext> _Context;
|
||||
|
||||
namespace {
|
||||
|
||||
// Used in multi-threaded message loop mode to observe shutdown of the UI
|
||||
// thread.
|
||||
class DestructionObserver : public MessageLoop::DestructionObserver {
|
||||
public:
|
||||
explicit DestructionObserver(base::WaitableEvent *event) : event_(event) {}
|
||||
virtual void WillDestroyCurrentMessageLoop() {
|
||||
MessageLoop::current()->RemoveDestructionObserver(this);
|
||||
event_->Signal();
|
||||
delete this;
|
||||
}
|
||||
private:
|
||||
base::WaitableEvent *event_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int CefExecuteProcess(const CefMainArgs& args,
|
||||
CefRefPtr<CefApp> application) {
|
||||
|
@ -200,11 +182,12 @@ bool CefContext::Initialize(const CefMainArgs& args,
|
|||
|
||||
cache_path_ = FilePath(CefString(&settings.cache_path));
|
||||
|
||||
#if !defined(OS_WIN)
|
||||
if (settings.multi_threaded_message_loop) {
|
||||
// TODO(cef): Figure out if we can support this.
|
||||
NOTIMPLEMENTED();
|
||||
NOTIMPLEMENTED() << "multi_threaded_message_loop is not supported.";
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
main_delegate_.reset(new CefMainDelegate(application));
|
||||
main_runner_.reset(content::ContentMainRunner::Create());
|
||||
|
@ -246,24 +229,20 @@ void CefContext::Shutdown() {
|
|||
if (settings_.multi_threaded_message_loop) {
|
||||
// Events that will be used to signal when shutdown is complete. Start in
|
||||
// non-signaled mode so that the event will block.
|
||||
base::WaitableEvent browser_shutdown_event(false, false);
|
||||
base::WaitableEvent uithread_shutdown_event(false, false);
|
||||
|
||||
// Finish shutdown on the UI thread.
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::Bind(&CefContext::FinishShutdownOnUIThread, this,
|
||||
&browser_shutdown_event, &uithread_shutdown_event));
|
||||
&uithread_shutdown_event));
|
||||
|
||||
// Block until browser shutdown is complete.
|
||||
browser_shutdown_event.Wait();
|
||||
/// Block until UI thread shutdown is complete.
|
||||
uithread_shutdown_event.Wait();
|
||||
|
||||
FinalizeShutdown();
|
||||
|
||||
// Block until UI thread shutdown is complete.
|
||||
uithread_shutdown_event.Wait();
|
||||
} else {
|
||||
// Finish shutdown on the current thread, which should be the UI thread.
|
||||
FinishShutdownOnUIThread(NULL, NULL);
|
||||
FinishShutdownOnUIThread(NULL);
|
||||
|
||||
FinalizeShutdown();
|
||||
}
|
||||
|
@ -355,7 +334,6 @@ CefBrowserContext* CefContext::browser_context() const {
|
|||
}
|
||||
|
||||
void CefContext::FinishShutdownOnUIThread(
|
||||
base::WaitableEvent* browser_shutdown_event,
|
||||
base::WaitableEvent* uithread_shutdown_event) {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
|
@ -376,19 +354,12 @@ void CefContext::FinishShutdownOnUIThread(
|
|||
(*it)->DestroyBrowser();
|
||||
}
|
||||
|
||||
if (uithread_shutdown_event) {
|
||||
// The destruction observer will signal the UI thread shutdown event when
|
||||
// the UI thread has been destroyed.
|
||||
MessageLoop::current()->AddDestructionObserver(
|
||||
new DestructionObserver(uithread_shutdown_event));
|
||||
|
||||
// Signal the browser shutdown event now.
|
||||
browser_shutdown_event->Signal();
|
||||
}
|
||||
if (uithread_shutdown_event)
|
||||
uithread_shutdown_event->Signal();
|
||||
}
|
||||
|
||||
void CefContext::FinalizeShutdown() {
|
||||
// Shut down the browser runner.
|
||||
// Shut down the browser runner or UI thread.
|
||||
main_delegate_->ShutdownBrowser();
|
||||
|
||||
// Shut down the content runner.
|
||||
|
|
|
@ -70,8 +70,7 @@ class CefContext : public CefBase {
|
|||
private:
|
||||
// Performs shutdown actions that need to occur on the UI thread before any
|
||||
// threads are destroyed.
|
||||
void FinishShutdownOnUIThread(base::WaitableEvent* browser_shutdown_event,
|
||||
base::WaitableEvent* uithread_shutdown_event);
|
||||
void FinishShutdownOnUIThread(base::WaitableEvent* uithread_shutdown_event);
|
||||
|
||||
// Destroys the main runner and related objects.
|
||||
void FinalizeShutdown();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "libcef/common/request_impl.h"
|
||||
|
||||
#include "net/base/net_errors.h"
|
||||
#include "net/url_request/url_request.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -95,6 +96,8 @@ int CefNetworkDelegate::OnBeforeURLRequest(
|
|||
if (handler.get()) {
|
||||
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
|
||||
|
||||
GURL old_url = request->url();
|
||||
|
||||
// Populate the request data.
|
||||
CefRefPtr<CefRequestImpl> requestPtr(new CefRequestImpl());
|
||||
requestPtr->Set(request);
|
||||
|
@ -105,7 +108,10 @@ int CefNetworkDelegate::OnBeforeURLRequest(
|
|||
return net::ERR_ABORTED;
|
||||
}
|
||||
|
||||
*new_url = GURL(std::string(requestPtr->GetURL()));
|
||||
GURL url = GURL(std::string(requestPtr->GetURL()));
|
||||
if (old_url != url)
|
||||
new_url ->Swap(&url);
|
||||
|
||||
requestPtr->Get(request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,27 +51,20 @@ bool CefContentClient::CanHandleWhileSwappedOut(const IPC::Message& msg) {
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string CefContentClient::GetUserAgent(bool* overriding) const {
|
||||
std::string CefContentClient::GetUserAgent() const {
|
||||
std::string product_version;
|
||||
|
||||
static CommandLine& command_line = *CommandLine::ForCurrentProcess();
|
||||
if (command_line.HasSwitch(switches::kUserAgent)) {
|
||||
*overriding = true;
|
||||
return command_line.GetSwitchValueASCII(switches::kUserAgent);
|
||||
if (command_line.HasSwitch(switches::kProductVersion)) {
|
||||
product_version =
|
||||
command_line.GetSwitchValueASCII(switches::kProductVersion);
|
||||
} else {
|
||||
std::string product_version;
|
||||
|
||||
if (command_line.HasSwitch(switches::kProductVersion)) {
|
||||
*overriding = true;
|
||||
product_version =
|
||||
command_line.GetSwitchValueASCII(switches::kProductVersion);
|
||||
} else {
|
||||
*overriding = false;
|
||||
product_version = base::StringPrintf("Chrome/%d.%d.%d.%d",
|
||||
CHROME_VERSION_MAJOR, CHROME_VERSION_MINOR, CHROME_VERSION_BUILD,
|
||||
CHROME_VERSION_PATCH);
|
||||
}
|
||||
|
||||
return webkit_glue::BuildUserAgentFromProduct(product_version);
|
||||
product_version = base::StringPrintf("Chrome/%d.%d.%d.%d",
|
||||
CHROME_VERSION_MAJOR, CHROME_VERSION_MINOR, CHROME_VERSION_BUILD,
|
||||
CHROME_VERSION_PATCH);
|
||||
}
|
||||
|
||||
return webkit_glue::BuildUserAgentFromProduct(product_version);
|
||||
}
|
||||
|
||||
string16 CefContentClient::GetLocalizedString(int message_id) const {
|
||||
|
|
|
@ -30,7 +30,7 @@ class CefContentClient : public content::ContentClient {
|
|||
webkit::npapi::PluginList* plugin_list) OVERRIDE;
|
||||
virtual bool HasWebUIScheme(const GURL& url) const OVERRIDE;
|
||||
virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) OVERRIDE;
|
||||
virtual std::string GetUserAgent(bool* overriding) const OVERRIDE;
|
||||
virtual std::string GetUserAgent() const OVERRIDE;
|
||||
virtual string16 GetLocalizedString(int message_id) const OVERRIDE;
|
||||
virtual base::StringPiece GetDataResource(int resource_id) const OVERRIDE;
|
||||
|
||||
|
|
|
@ -15,19 +15,26 @@
|
|||
#include "base/file_path.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "content/public/browser/browser_main_runner.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/main_function_params.h"
|
||||
#include "ui/base/resource/resource_bundle.h"
|
||||
#include "ui/base/ui_base_paths.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <Objbase.h> // NOLINT(build/include_order)
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "content/public/common/content_paths.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
FilePath GetFrameworksPath() {
|
||||
// Start out with the path to the running executable.
|
||||
FilePath path;
|
||||
|
@ -71,11 +78,53 @@ void OverrideChildProcessPath() {
|
|||
|
||||
PathService::Override(content::CHILD_PROCESS_EXE, helper_path);
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // OS_MACOSX
|
||||
|
||||
namespace {
|
||||
|
||||
// Used to run the UI on a separate thread.
|
||||
class CefUIThread : public base::Thread {
|
||||
public:
|
||||
explicit CefUIThread(const content::MainFunctionParams& main_function_params)
|
||||
: base::Thread("CefUIThread"),
|
||||
main_function_params_(main_function_params) {
|
||||
}
|
||||
|
||||
virtual void Init() OVERRIDE {
|
||||
#if defined(OS_WIN)
|
||||
// Initializes the COM library on the current thread.
|
||||
CoInitialize(NULL);
|
||||
#endif
|
||||
|
||||
// Use our own browser process runner.
|
||||
browser_runner_.reset(content::BrowserMainRunner::Create());
|
||||
|
||||
// Initialize browser process state. Results in a call to
|
||||
// CefBrowserMain::GetMainMessageLoop().
|
||||
int exit_code = browser_runner_->Initialize(main_function_params_);
|
||||
CHECK_EQ(exit_code, -1);
|
||||
}
|
||||
|
||||
virtual void CleanUp() OVERRIDE {
|
||||
browser_runner_->Shutdown();
|
||||
browser_runner_.reset(NULL);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Closes the COM library on the current thread. CoInitialize must
|
||||
// be balanced by a corresponding call to CoUninitialize.
|
||||
CoUninitialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
content::MainFunctionParams main_function_params_;
|
||||
scoped_ptr<content::BrowserMainRunner> browser_runner_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CefMainDelegate::CefMainDelegate(CefRefPtr<CefApp> application)
|
||||
: content_client_(application) {
|
||||
|
@ -88,7 +137,7 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
|
|||
#if defined(OS_MACOSX)
|
||||
OverrideFrameworkBundlePath();
|
||||
#endif
|
||||
|
||||
|
||||
CommandLine* command_line = CommandLine::ForCurrentProcess();
|
||||
std::string process_type =
|
||||
command_line->GetSwitchValueASCII(switches::kProcessType);
|
||||
|
@ -190,14 +239,28 @@ int CefMainDelegate::RunProcess(
|
|||
const std::string& process_type,
|
||||
const content::MainFunctionParams& main_function_params) {
|
||||
if (process_type.empty()) {
|
||||
// Use our own browser process runner.
|
||||
browser_runner_.reset(content::BrowserMainRunner::Create());
|
||||
const CefSettings& settings = _Context->settings();
|
||||
if (!settings.multi_threaded_message_loop) {
|
||||
// Use our own browser process runner.
|
||||
browser_runner_.reset(content::BrowserMainRunner::Create());
|
||||
|
||||
// Initialize browser process state. Results in a call to
|
||||
// CefBrowserMain::GetMainMessageLoop().
|
||||
int exit_code = browser_runner_->Initialize(main_function_params);
|
||||
if (exit_code >= 0)
|
||||
return exit_code;
|
||||
// Initialize browser process state. Results in a call to
|
||||
// CefBrowserMain::GetMainMessageLoop().
|
||||
int exit_code = browser_runner_->Initialize(main_function_params);
|
||||
if (exit_code >= 0)
|
||||
return exit_code;
|
||||
} else {
|
||||
// Run the UI on a separate thread.
|
||||
scoped_ptr<base::Thread> thread;
|
||||
thread.reset(new CefUIThread(main_function_params));
|
||||
base::Thread::Options options;
|
||||
options.message_loop_type = MessageLoop::TYPE_UI;
|
||||
if (!thread->StartWithOptions(options)) {
|
||||
NOTREACHED() << "failed to start UI thread";
|
||||
return 1;
|
||||
}
|
||||
ui_thread_.swap(thread);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -243,6 +306,11 @@ void CefMainDelegate::ShutdownBrowser() {
|
|||
browser_runner_->Shutdown();
|
||||
browser_runner_.reset(NULL);
|
||||
}
|
||||
if (ui_thread_.get()) {
|
||||
// Blocks until the thread has stopped.
|
||||
ui_thread_->Stop();
|
||||
ui_thread_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void CefMainDelegate::InitializeContentClient(
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
#include "base/memory/scoped_ptr.h"
|
||||
#include "content/public/app/content_main_delegate.h"
|
||||
|
||||
namespace base {
|
||||
class Thread;
|
||||
}
|
||||
|
||||
namespace content {
|
||||
class BrowserMainRunner;
|
||||
}
|
||||
|
@ -59,6 +63,8 @@ class CefMainDelegate : public content::ContentMainDelegate {
|
|||
void InitializeResourceBundle();
|
||||
|
||||
scoped_ptr<content::BrowserMainRunner> browser_runner_;
|
||||
scoped_ptr<base::Thread> ui_thread_;
|
||||
|
||||
scoped_ptr<CefContentBrowserClient> browser_client_;
|
||||
scoped_ptr<CefContentRendererClient> renderer_client_;
|
||||
scoped_ptr<CefContentPluginClient> plugin_client_;
|
||||
|
|
|
@ -93,6 +93,13 @@ void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
|
|||
const CefString& errorText,
|
||||
const CefString& failedUrl) {
|
||||
REQUIRE_UI_THREAD();
|
||||
|
||||
// Display a load error message.
|
||||
std::stringstream ss;
|
||||
ss << "<html><body><h2>Failed to load URL " << std::string(failedUrl) <<
|
||||
" with error " << std::string(errorText) << " (" << errorCode <<
|
||||
").</h2></body></html>";
|
||||
frame->LoadString(ss.str(), failedUrl);
|
||||
}
|
||||
|
||||
void ClientHandler::OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
||||
|
|
Loading…
Reference in New Issue