// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/browser_main_runner_impl.h"

#include <memory>

#include "base/allocator/partition_alloc_support.h"
#include "base/base_switches.h"
#include "base/check.h"
#include "base/command_line.h"
#include "base/debug/debugger.h"
#include "base/debug/leak_annotations.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/run_loop.h"
#include "base/synchronization/atomic_flag.h"
#include "base/task/execution_fence.h"
#include "base/time/time.h"
#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/tracing/common/tracing_switches.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/tracing/startup_tracing_controller.h"
#include "content/common/content_switches_internal.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "services/tracing/public/cpp/trace_startup_config.h"
#include "third_party/skia/include/core/SkGraphics.h"
#include "ui/base/ime/init/input_method_initializer.h"
#include "ui/gfx/font_util.h"

#if BUILDFLAG(IS_ANDROID)
#include "content/browser/android/tracing_controller_android.h"
#endif

#if BUILDFLAG(IS_WIN)
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "ui/base/win/scoped_ole_initializer.h"
#endif

namespace content {
namespace {

base::AtomicFlag& GetExitedMainMessageLoopFlag() {
  static base::NoDestructor<base::AtomicFlag> flag;
  return *flag;
}

}  // namespace

// static
std::unique_ptr<BrowserMainRunnerImpl> BrowserMainRunnerImpl::Create() {
  return std::make_unique<BrowserMainRunnerImpl>();
}

BrowserMainRunnerImpl::BrowserMainRunnerImpl()
    : initialization_started_(false),
      is_shutdown_(false),
      scoped_execution_fence_(
          std::make_unique<base::ScopedThreadPoolExecutionFence>()) {}

BrowserMainRunnerImpl::~BrowserMainRunnerImpl() {
  if (initialization_started_ && !is_shutdown_) {
    Shutdown();
  }
}

int BrowserMainRunnerImpl::Initialize(MainFunctionParams parameters) {
  SCOPED_UMA_HISTOGRAM_LONG_TIMER(
      "Startup.BrowserMainRunnerImplInitializeLongTime");
  TRACE_EVENT0("startup", "BrowserMainRunnerImpl::Initialize");

  // On Android we normally initialize the browser in a series of UI thread
  // tasks. While this is happening a second request can come from the OS or
  // another application to start the browser. If this happens then we must
  // not run these parts of initialization twice.
  if (!initialization_started_) {
    initialization_started_ = true;

    SkGraphics::Init();

    if (parameters.command_line->HasSwitch(switches::kWaitForDebugger)) {
      base::debug::WaitForDebugger(60, true);
    }

    if (parameters.command_line->HasSwitch(switches::kBrowserStartupDialog)) {
      WaitForDebugger("Browser");
    }

#if BUILDFLAG(IS_WIN)
    base::win::EnableHighDPISupport();
    // Ole must be initialized before starting message pump, so that TSF
    // (Text Services Framework) module can interact with the message pump
    // on Windows 8 Metro mode.
    ole_initializer_ = std::make_unique<ui::ScopedOleInitializer>();
#endif  // BUILDFLAG(IS_WIN)

    gfx::InitializeFonts();

    auto created_main_parts_closure =
        std::move(parameters.created_main_parts_closure);

    main_loop_ = std::make_unique<BrowserMainLoop>(
        std::move(parameters), std::move(scoped_execution_fence_));

    main_loop_->Init();

    if (created_main_parts_closure) {
      std::move(created_main_parts_closure).Run(main_loop_->parts());
    }

    const int early_init_error_code = main_loop_->EarlyInitialization();
    if (early_init_error_code > 0) {
      main_loop_->CreateMessageLoopForEarlyShutdown();
      return early_init_error_code;
    }

    // Must happen before we try to use a message loop or display any UI.
    if (!main_loop_->InitializeToolkit()) {
      main_loop_->CreateMessageLoopForEarlyShutdown();
      return 1;
    }

    main_loop_->PreCreateMainMessageLoop();
    main_loop_->CreateMainMessageLoop();
    main_loop_->PostCreateMainMessageLoop();

    // WARNING: If we get a WM_ENDSESSION, objects created on the stack here
    // are NOT deleted. If you need something to run during WM_ENDSESSION add it
    // to browser_shutdown::Shutdown or BrowserProcess::EndSession.

    ui::InitializeInputMethod();
  }
  main_loop_->CreateStartupTasks();
  int result_code = main_loop_->GetResultCode();
  if (result_code > 0) {
    return result_code;
  }

  // Return -1 to indicate no early termination.
  return -1;
}

int BrowserMainRunnerImpl::Run() {
  DCHECK(initialization_started_);
  DCHECK(!is_shutdown_);
  main_loop_->RunMainMessageLoop();
  return main_loop_->GetResultCode();
}

void BrowserMainRunnerImpl::Shutdown() {
  DCHECK(initialization_started_);
  DCHECK(!is_shutdown_);

#if BUILDFLAG(IS_CHROMEOS)
  // Reduces shutdown hangs on CrOS.
  // Googlers: see go/cros-no-op-free-2024 for the experiment write-up.
  base::allocator::MakeFreeNoOp();
#endif

  main_loop_->PreShutdown();

  // Finalize the startup tracing session if it is still active.
  StartupTracingController::GetInstance().ShutdownAndWaitForStopIfNeeded();

  {
    // The trace event has to stay between profiler creation and destruction.
    TRACE_EVENT0("shutdown", "BrowserMainRunner");
    GetExitedMainMessageLoopFlag().Set();

    main_loop_->ShutdownThreadsAndCleanUp();

    ui::ShutdownInputMethod();
#if BUILDFLAG(IS_WIN)
    ole_initializer_.reset(NULL);
#endif
    main_loop_.reset(nullptr);

    is_shutdown_ = true;
  }
}

// static
std::unique_ptr<BrowserMainRunner> BrowserMainRunner::Create() {
  return BrowserMainRunnerImpl::Create();
}

// static
bool BrowserMainRunner::ExitedMainMessageLoop() {
  return GetExitedMainMessageLoopFlag().IsSet();
}

}  // namespace content
