// Copyright 2018 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/scheduler/browser_task_executor.h"

#include <atomic>

#include "base/functional/bind.h"
#include "base/message_loop/message_pump_type.h"
#include "base/run_loop.h"
#include "base/task/deferred_sequenced_task_runner.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/threading_features.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "content/browser/browser_process_io_thread.h"
#include "content/browser/browser_thread_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/common/content_features.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/task_scheduler/post_task_android.h"
#include "base/android/task_scheduler/task_runner_android.h"
#include "base/android/task_scheduler/task_traits_android.h"
#endif

using QueueType = content::BrowserTaskQueues::QueueType;

namespace content {
namespace features {
// When the "BrowserPrioritizeInputQueue" feature is enabled, the browser will
// schedule tasks related to input in kHigh priority queue. This puts it under
// bootstrap, but above regular tasks.
//
// The goal is to reduce jank by ensuring chromium is handling input events as
// soon as possible.
//
// TODO(nuskos): Remove this feature flag after we've done our retroactive study
// of all chrometto performance improvements.
BASE_FEATURE(kBrowserPrioritizeInputQueue,
             "BrowserPrioritizeInputQueue",
             base::FEATURE_ENABLED_BY_DEFAULT);

}  // namespace features

namespace {

// |g_browser_task_executor| is intentionally leaked on shutdown.
BrowserTaskExecutor* g_browser_task_executor = nullptr;

#if BUILDFLAG(IS_ANDROID)
scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunnerForAndroidMainThread(
    ::TaskTraits android_traits) {
  BrowserTaskTraits traits;
  switch (android_traits) {
    case ::TaskTraits::UI_BEST_EFFORT:
      traits = {base::TaskPriority::BEST_EFFORT};
      break;
    case ::TaskTraits::UI_USER_VISIBLE:
      traits = {base::TaskPriority::USER_VISIBLE};
      break;
    case ::TaskTraits::UI_USER_BLOCKING:
      traits = {base::TaskPriority::USER_BLOCKING};
      break;
    default:
      NOTREACHED();
  }
  return g_browser_task_executor->GetUIThreadTaskRunner(traits);
}
#endif

}  // namespace

BaseBrowserTaskExecutor::BaseBrowserTaskExecutor() = default;

BaseBrowserTaskExecutor::~BaseBrowserTaskExecutor() = default;

scoped_refptr<base::SingleThreadTaskRunner>
BaseBrowserTaskExecutor::GetTaskRunner(BrowserThread::ID identifier,
                                       const BrowserTaskTraits& traits) const {
  const QueueType queue_type = GetQueueType(traits);

  switch (identifier) {
    case BrowserThread::UI: {
      return browser_ui_thread_handle_->GetBrowserTaskRunner(queue_type);
    }
    case BrowserThread::IO:
      return browser_io_thread_handle_->GetBrowserTaskRunner(queue_type);
    case BrowserThread::ID_COUNT:
      NOTREACHED();
  }
  return nullptr;
}

// static
QueueType BaseBrowserTaskExecutor::GetQueueType(
    const BrowserTaskTraits& traits) {
  switch (traits.task_type()) {
    case BrowserTaskType::kUserInput:
      if (base::FeatureList::IsEnabled(
              features::kBrowserPrioritizeInputQueue)) {
        return QueueType::kUserInput;
      }
      // Defer to traits.priority() below.
      break;

    case BrowserTaskType::kNavigationNetworkResponse:
      if (base::FeatureList::IsEnabled(
              ::features::kNavigationNetworkResponseQueue)) {
        return QueueType::kNavigationNetworkResponse;
      }
      // Defer to traits.priority() below.
      break;

    case BrowserTaskType::kServiceWorkerStorageControlResponse:
      return QueueType::kServiceWorkerStorageControlResponse;

    case BrowserTaskType::kDefault:
      // Defer to traits.priority() below.
      break;
  }

  switch (traits.priority()) {
    case base::TaskPriority::BEST_EFFORT:
      return QueueType::kBestEffort;

    case base::TaskPriority::USER_VISIBLE:
      return QueueType::kUserVisible;

    case base::TaskPriority::USER_BLOCKING:
      return QueueType::kUserBlocking;
  }
}

BrowserTaskExecutor::BrowserTaskExecutor(
    std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler,
    std::unique_ptr<BrowserIOThreadDelegate> browser_io_thread_delegate)
    : ui_thread_executor_(std::make_unique<UIThreadExecutor>(
          std::move(browser_ui_thread_scheduler))),
      io_thread_executor_(std::make_unique<IOThreadExecutor>(
          std::move(browser_io_thread_delegate))) {
  browser_ui_thread_handle_ = ui_thread_executor_->GetUIThreadHandle();
  browser_io_thread_handle_ = io_thread_executor_->GetIOThreadHandle();
  ui_thread_executor_->SetIOThreadHandle(browser_io_thread_handle_);
  io_thread_executor_->SetUIThreadHandle(browser_ui_thread_handle_);
}

BrowserTaskExecutor::~BrowserTaskExecutor() = default;

// static
void BrowserTaskExecutor::Create() {
  DCHECK(!base::SingleThreadTaskRunner::HasCurrentDefault());
  CreateInternal(std::make_unique<BrowserUIThreadScheduler>(),
                 std::make_unique<BrowserIOThreadDelegate>());
}

// static
void BrowserTaskExecutor::CreateForTesting(
    std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler,
    std::unique_ptr<BrowserIOThreadDelegate> browser_io_thread_delegate) {
  CreateInternal(std::move(browser_ui_thread_scheduler),
                 std::move(browser_io_thread_delegate));
}

// static
void BrowserTaskExecutor::CreateInternal(
    std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler,
    std::unique_ptr<BrowserIOThreadDelegate> browser_io_thread_delegate) {
  DCHECK(!g_browser_task_executor);
  g_browser_task_executor =
      new BrowserTaskExecutor(std::move(browser_ui_thread_scheduler),
                              std::move(browser_io_thread_delegate));

  g_browser_task_executor->browser_ui_thread_handle_
      ->EnableAllExceptBestEffortQueues();

#if BUILDFLAG(IS_ANDROID)
  // In Android Java, UI thread is a base/ concept, but needs to know how that
  // maps onto the BrowserThread::UI in C++.
  base::TaskRunnerAndroid::SetUiThreadTaskRunnerCallback(
      base::BindRepeating(&GetTaskRunnerForAndroidMainThread));
  base::PostTaskAndroid::SignalNativeSchedulerReady();
#endif
}

// static
BrowserTaskExecutor* BrowserTaskExecutor::Get() {
  DCHECK(g_browser_task_executor)
      << "No browser task executor created.\nHint: if this is in a unit test, "
         "you're likely missing a content::BrowserTaskEnvironment member in "
         "your fixture.";
  return g_browser_task_executor;
}

// static
void BrowserTaskExecutor::ResetForTesting() {
  if (g_browser_task_executor) {
    RunAllPendingTasksOnThreadForTesting(BrowserThread::UI);
    RunAllPendingTasksOnThreadForTesting(BrowserThread::IO);
    delete g_browser_task_executor;
    g_browser_task_executor = nullptr;
  }
}

// static
void BrowserTaskExecutor::PostFeatureListSetup() {
  DCHECK(Get()->ui_thread_executor_);
  Get()->ui_thread_executor_->PostFeatureListSetup();
}

// static
absl::optional<BrowserUIThreadScheduler::UserInputActiveHandle>
BrowserTaskExecutor::OnUserInputStart() {
  DCHECK(Get()->ui_thread_executor_);
  return absl::optional<BrowserUIThreadScheduler::UserInputActiveHandle>(
      Get()->ui_thread_executor_->OnUserInputStart());
}

// static
void BrowserTaskExecutor::Shutdown() {
  if (!g_browser_task_executor)
    return;

  DCHECK(Get()->ui_thread_executor_);
  DCHECK(Get()->io_thread_executor_);
  // We don't delete |g_browser_task_executor| because other threads may
  // PostTask or call BrowserTaskExecutor::GetTaskRunner while we're tearing
  // things down. We don't want to add locks so we just leak instead of dealing
  // with that. For similar reasons we don't need to call
  // PostTaskAndroid::SignalNativeSchedulerShutdown on Android. In tests however
  // we need to clean up, so BrowserTaskExecutor::ResetForTesting should be
  // called.
  Get()->ui_thread_executor_.reset();
  Get()->io_thread_executor_.reset();
}

// static
void BrowserTaskExecutor::RunAllPendingTasksOnThreadForTesting(
    BrowserThread::ID identifier) {
  DCHECK(Get());

  base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);

  switch (identifier) {
    case BrowserThread::UI:
      Get()->browser_ui_thread_handle_->ScheduleRunAllPendingTasksForTesting(
          run_loop.QuitClosure());
      break;
    case BrowserThread::IO: {
      Get()->browser_io_thread_handle_->ScheduleRunAllPendingTasksForTesting(
          run_loop.QuitClosure());
      break;
    }
    case BrowserThread::ID_COUNT:
      NOTREACHED();
  }

  run_loop.Run();
}

// static
void BrowserTaskExecutor::OnStartupComplete() {
  Get()->browser_ui_thread_handle_->OnStartupComplete();
  Get()->browser_io_thread_handle_->OnStartupComplete();
}

// static
scoped_refptr<base::SingleThreadTaskRunner>
BrowserTaskExecutor::GetUIThreadTaskRunner(const BrowserTaskTraits& traits) {
  return Get()->GetTaskRunner(BrowserThread::UI, traits);
}

// static
scoped_refptr<base::SingleThreadTaskRunner>
BrowserTaskExecutor::GetIOThreadTaskRunner(const BrowserTaskTraits& traits) {
  return Get()->GetTaskRunner(BrowserThread::IO, traits);
}

// static
void BrowserTaskExecutor::InitializeIOThread() {
  Get()->browser_io_thread_handle_->EnableAllExceptBestEffortQueues();
}

std::unique_ptr<BrowserProcessIOThread> BrowserTaskExecutor::CreateIOThread() {
  DCHECK(Get()->io_thread_executor_);

  std::unique_ptr<BrowserIOThreadDelegate> browser_io_thread_delegate =
      Get()->io_thread_executor_->TakeDelegate();

  DCHECK(browser_io_thread_delegate);
  TRACE_EVENT0("startup", "BrowserTaskExecutor::CreateIOThread");

  auto io_thread = std::make_unique<BrowserProcessIOThread>();

  if (browser_io_thread_delegate->allow_blocking_for_testing()) {
    io_thread->AllowBlockingForTesting();
  }

  base::Thread::Options options;
  options.message_pump_type = base::MessagePumpType::IO;
  options.delegate = std::move(browser_io_thread_delegate);
// TODO(1329208): Align Win ThreadType with other platforms. The platform
// discrepancy stems from organic evolution of the thread priorities on each
// platform and while it might make sense not to bump the priority of the IO
// thread per Windows' priority boosts capabilities on MessagePumpForIO, this
// should at least be aligned with what platform_thread_win.cc does for
// ThreadType::kDisplayCritical (IO pumps in other processes) and it currently
// does not.
#if BUILDFLAG(IS_WIN)
  if (base::FeatureList::IsEnabled(base::kAboveNormalCompositingBrowserWin)) {
    options.thread_type = base::ThreadType::kCompositing;
  }
#else
  // Up the priority of the |io_thread_| as some of its IPCs relate to
  // display tasks.
  options.thread_type = base::ThreadType::kCompositing;
#endif
  if (!io_thread->StartWithOptions(std::move(options)))
    LOG(FATAL) << "Failed to start BrowserThread:IO";
  return io_thread;
}

BrowserTaskExecutor::UIThreadExecutor::UIThreadExecutor(
    std::unique_ptr<BrowserUIThreadScheduler> browser_ui_thread_scheduler)
    : browser_ui_thread_scheduler_(std::move(browser_ui_thread_scheduler)) {
  browser_ui_thread_handle_ = browser_ui_thread_scheduler_->GetHandle();
}

BrowserTaskExecutor::UIThreadExecutor::~UIThreadExecutor() = default;

absl::optional<BrowserUIThreadScheduler::UserInputActiveHandle>
BrowserTaskExecutor::UIThreadExecutor::OnUserInputStart() {
  DCHECK(browser_ui_thread_scheduler_);
  return browser_ui_thread_scheduler_->OnUserInputStart();
}

void BrowserTaskExecutor::UIThreadExecutor::PostFeatureListSetup() {
  DCHECK(browser_ui_thread_scheduler_);
  browser_ui_thread_scheduler_->PostFeatureListSetup();
}

scoped_refptr<BrowserUIThreadScheduler::Handle>
BrowserTaskExecutor::UIThreadExecutor::GetUIThreadHandle() {
  return browser_ui_thread_handle_;
}

void BrowserTaskExecutor::UIThreadExecutor::SetIOThreadHandle(
    scoped_refptr<BrowserUIThreadScheduler::Handle> io_thread_handle) {
  browser_io_thread_handle_ = std::move(io_thread_handle);
}

BrowserTaskExecutor::IOThreadExecutor::IOThreadExecutor(
    std::unique_ptr<BrowserIOThreadDelegate> browser_io_thread_delegate)
    : browser_io_thread_delegate_(std::move(browser_io_thread_delegate)) {
  // |browser_io_thread_delegate_| can be null in tests.
  if (!browser_io_thread_delegate_)
    return;
  browser_io_thread_handle_ = browser_io_thread_delegate_->GetHandle();
}

BrowserTaskExecutor::IOThreadExecutor::~IOThreadExecutor() = default;

scoped_refptr<BrowserUIThreadScheduler::Handle>
BrowserTaskExecutor::IOThreadExecutor::GetIOThreadHandle() {
  return browser_io_thread_handle_;
}

void BrowserTaskExecutor::IOThreadExecutor::SetUIThreadHandle(
    scoped_refptr<BrowserUIThreadScheduler::Handle> ui_thread_handle) {
  browser_ui_thread_handle_ = std::move(ui_thread_handle);
}

}  // namespace content
