summaryrefslogtreecommitdiff
path: root/libcef/common/chrome/chrome_main_runner_delegate.cc
blob: 57a92d931e8fe00c84717a1e5d9d3ec4bb456551 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright 2020 The Chromium Embedded Framework Authors.
// Portions copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "libcef/common/chrome/chrome_main_runner_delegate.h"

#include "libcef/common/app_manager.h"
#include "libcef/common/chrome/chrome_main_delegate_cef.h"

#include "base/command_line.h"
#include "base/run_loop.h"
#include "chrome/browser/browser_process_impl.h"
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/common/profiler/main_thread_stack_sampling_profiler.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"

ChromeMainRunnerDelegate::ChromeMainRunnerDelegate(
    CefMainRunnerHandler* runner,
    CefSettings* settings,
    CefRefPtr<CefApp> application)
    : runner_(runner), settings_(settings), application_(application) {}

ChromeMainRunnerDelegate::~ChromeMainRunnerDelegate() = default;

content::ContentMainDelegate*
ChromeMainRunnerDelegate::GetContentMainDelegate() {
  if (!main_delegate_) {
    main_delegate_ = std::make_unique<ChromeMainDelegateCef>(runner_, settings_,
                                                             application_);
  }
  return main_delegate_.get();
}

void ChromeMainRunnerDelegate::BeforeMainThreadInitialize(
    const CefMainArgs& args) {
#if BUILDFLAG(IS_WIN)
  base::CommandLine::Init(0, nullptr);
#else
  base::CommandLine::Init(args.argc, args.argv);
#endif
}

void ChromeMainRunnerDelegate::BeforeMainMessageLoopRun(
    base::RunLoop* run_loop) {
  // The ScopedKeepAlive instance triggers shutdown logic when released on the
  // UI thread before terminating the message loop (e.g. from CefQuitMessageLoop
  // or FinishShutdownOnUIThread when running with multi-threaded message loop).
  keep_alive_ = std::make_unique<ScopedKeepAlive>(
      KeepAliveOrigin::APP_CONTROLLER, KeepAliveRestartOption::DISABLED);

  // The idle callback will be executed from BrowserProcessImpl::Unpin() via
  // KeepAliveRegistry when the last ScopedKeepAlive is released.
  // ScopedKeepAlives are also held by Browser objects.
  DCHECK(g_browser_process);
  static_cast<BrowserProcessImpl*>(g_browser_process)
      ->SetQuitClosure(run_loop->QuitWhenIdleClosure());
}

bool ChromeMainRunnerDelegate::HandleMainMessageLoopQuit() {
  // May be called multiple times. See comments in RunMainMessageLoopBefore.
  keep_alive_.reset();

  // Cancel direct execution of the QuitWhenIdleClosure() in
  // CefMainRunner::QuitMessageLoop. We instead wait for all Chrome browser
  // windows to exit.
  return true;
}

void ChromeMainRunnerDelegate::BeforeUIThreadInitialize() {
  sampling_profiler_ = std::make_unique<MainThreadStackSamplingProfiler>();
}

void ChromeMainRunnerDelegate::AfterUIThreadShutdown() {
  static_cast<ChromeContentBrowserClient*>(
      CefAppManager::Get()->GetContentClient()->browser())
      ->CleanupOnUIThread();
  main_delegate_->CleanupOnUIThread();

  sampling_profiler_.reset();
}

void ChromeMainRunnerDelegate::BeforeExecuteProcess(const CefMainArgs& args) {
  BeforeMainThreadInitialize(args);
}

void ChromeMainRunnerDelegate::AfterExecuteProcess() {
  AfterMainThreadShutdown();
}