2012-04-03 03:34:16 +02:00
|
|
|
// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
|
|
|
|
// reserved. Use of this source code is governed by a BSD-style license that can
|
|
|
|
// be found in the LICENSE file.
|
|
|
|
|
2024-04-30 17:45:07 +02:00
|
|
|
#include "cef/libcef/browser/browser_message_loop.h"
|
2016-05-04 20:00:03 +02:00
|
|
|
|
2016-05-25 01:35:43 +02:00
|
|
|
#include "base/memory/ptr_util.h"
|
2019-07-16 19:59:21 +02:00
|
|
|
#include "base/message_loop/message_pump.h"
|
2019-03-13 22:27:37 +01:00
|
|
|
#include "base/message_loop/message_pump_for_ui.h"
|
2024-04-30 17:45:07 +02:00
|
|
|
#include "cef/libcef/common/app_manager.h"
|
2012-04-03 03:34:16 +02:00
|
|
|
|
2022-01-24 18:58:02 +01:00
|
|
|
#if BUILDFLAG(IS_MAC)
|
2023-09-15 21:51:43 +02:00
|
|
|
#include "base/apple/scoped_nsautorelease_pool.h"
|
|
|
|
#include "base/message_loop/message_pump_apple.h"
|
2016-05-04 20:00:03 +02:00
|
|
|
#endif
|
|
|
|
|
2019-03-13 22:27:37 +01:00
|
|
|
#include "content/public/browser/browser_thread.h"
|
|
|
|
|
2016-05-04 20:00:03 +02:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
// MessagePump implementation that delegates to OnScheduleMessagePumpWork() for
|
|
|
|
// scheduling.
|
2019-01-11 15:40:47 +01:00
|
|
|
class MessagePumpExternal : public base::MessagePumpForUI {
|
2016-05-04 20:00:03 +02:00
|
|
|
public:
|
|
|
|
MessagePumpExternal(float max_time_slice,
|
|
|
|
CefRefPtr<CefBrowserProcessHandler> handler)
|
2017-05-17 11:29:28 +02:00
|
|
|
: max_time_slice_(max_time_slice), handler_(handler) {}
|
2016-05-04 20:00:03 +02:00
|
|
|
|
|
|
|
void Run(Delegate* delegate) override {
|
|
|
|
base::TimeTicks start = base::TimeTicks::Now();
|
|
|
|
while (true) {
|
2022-01-24 18:58:02 +01:00
|
|
|
#if BUILDFLAG(IS_MAC)
|
2023-09-15 21:51:43 +02:00
|
|
|
base::apple::ScopedNSAutoreleasePool autorelease_pool;
|
2016-05-04 20:00:03 +02:00
|
|
|
#endif
|
|
|
|
|
2020-04-14 21:31:00 +02:00
|
|
|
base::TimeTicks next_run_time; // is_null()
|
2024-06-14 19:01:45 +02:00
|
|
|
DirectRunWork(delegate, &next_run_time);
|
2016-05-04 20:00:03 +02:00
|
|
|
|
2020-04-14 21:31:00 +02:00
|
|
|
if (next_run_time.is_null()) {
|
|
|
|
// We have more work that should run immediately.
|
|
|
|
next_run_time = base::TimeTicks::Now();
|
|
|
|
}
|
|
|
|
|
|
|
|
const base::TimeDelta& delta = next_run_time - start;
|
2023-01-02 23:59:03 +01:00
|
|
|
if (delta.InSecondsF() > max_time_slice_) {
|
2016-05-04 20:00:03 +02:00
|
|
|
break;
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
2016-05-04 20:00:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-17 11:29:28 +02:00
|
|
|
void Quit() override {}
|
2016-05-04 20:00:03 +02:00
|
|
|
|
2017-05-17 11:29:28 +02:00
|
|
|
void ScheduleWork() override { handler_->OnScheduleMessagePumpWork(0); }
|
2016-05-04 20:00:03 +02:00
|
|
|
|
2022-03-26 02:12:30 +01:00
|
|
|
void ScheduleDelayedWork(
|
|
|
|
const Delegate::NextWorkInfo& next_work_info) override {
|
|
|
|
const base::TimeDelta& delta =
|
|
|
|
next_work_info.delayed_run_time - next_work_info.recent_now;
|
2016-05-04 20:00:03 +02:00
|
|
|
handler_->OnScheduleMessagePumpWork(delta.InMilliseconds());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2024-06-14 19:01:45 +02:00
|
|
|
static void DirectRunWork(Delegate* delegate,
|
2020-04-14 21:31:00 +02:00
|
|
|
base::TimeTicks* next_run_time) {
|
|
|
|
bool more_immediate_work = false;
|
|
|
|
bool more_delayed_work = false;
|
|
|
|
|
|
|
|
Delegate::NextWorkInfo next_work_info = delegate->DoWork();
|
|
|
|
|
|
|
|
// is_immediate() returns true if the next task is ready right away.
|
|
|
|
more_immediate_work = next_work_info.is_immediate();
|
|
|
|
if (!more_immediate_work) {
|
|
|
|
// Check the next PendingTask's |delayed_run_time|.
|
|
|
|
// is_max() returns true if there are no more immediate nor delayed tasks.
|
|
|
|
more_delayed_work = !next_work_info.delayed_run_time.is_max();
|
2020-07-21 18:26:41 +02:00
|
|
|
if (more_delayed_work) {
|
2020-04-14 21:31:00 +02:00
|
|
|
// The only remaining work that we know about is the PendingTask.
|
|
|
|
// Consider the run time for that task in the time slice calculation.
|
|
|
|
*next_run_time = next_work_info.delayed_run_time;
|
|
|
|
}
|
2016-05-04 20:00:03 +02:00
|
|
|
}
|
|
|
|
|
2020-07-21 18:26:41 +02:00
|
|
|
if (!more_immediate_work && !more_delayed_work) {
|
2024-06-14 19:01:45 +02:00
|
|
|
delegate->DoIdleWork();
|
2020-07-21 18:26:41 +02:00
|
|
|
}
|
2016-05-04 20:00:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const float max_time_slice_;
|
|
|
|
CefRefPtr<CefBrowserProcessHandler> handler_;
|
|
|
|
};
|
|
|
|
|
|
|
|
CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() {
|
2020-06-28 23:05:36 +02:00
|
|
|
CefRefPtr<CefApp> app = CefAppManager::Get()->GetApplication();
|
2023-01-02 23:59:03 +01:00
|
|
|
if (app) {
|
2016-05-04 20:00:03 +02:00
|
|
|
return app->GetBrowserProcessHandler();
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
2016-05-04 20:00:03 +02:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2019-03-13 22:27:37 +01:00
|
|
|
std::unique_ptr<base::MessagePump> MessagePumpFactoryForUI() {
|
|
|
|
if (!content::BrowserThread::IsThreadInitialized(
|
|
|
|
content::BrowserThread::UI) ||
|
|
|
|
content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
|
2016-05-04 20:00:03 +02:00
|
|
|
CefRefPtr<CefBrowserProcessHandler> handler = GetBrowserProcessHandler();
|
2023-01-02 23:59:03 +01:00
|
|
|
if (handler) {
|
2019-03-13 22:27:37 +01:00
|
|
|
return std::make_unique<MessagePumpExternal>(0.01f, handler);
|
2023-01-02 23:59:03 +01:00
|
|
|
}
|
2016-05-04 20:00:03 +02:00
|
|
|
}
|
|
|
|
|
2022-01-24 18:58:02 +01:00
|
|
|
#if BUILDFLAG(IS_MAC)
|
2023-09-15 21:51:43 +02:00
|
|
|
return base::message_pump_apple::Create();
|
2019-03-13 22:27:37 +01:00
|
|
|
#else
|
|
|
|
return std::make_unique<base::MessagePumpForUI>();
|
|
|
|
#endif
|
2016-05-04 20:00:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2020-06-24 22:26:12 +02:00
|
|
|
void InitExternalMessagePumpFactoryForUI() {
|
|
|
|
base::MessagePump::OverrideMessagePumpForUIFactory(MessagePumpFactoryForUI);
|
2012-04-03 03:34:16 +02:00
|
|
|
}
|