// Copyright 2015 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 "chrome/browser/after_startup_task_utils.h"

#include <memory>
#include <utility>

#include "base/containers/circular_deque.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/process.h"
#include "base/rand_util.h"
#include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h"
#include "base/synchronization/atomic_flag.h"
#include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/page_visibility_state.h"

#if !defined(OS_ANDROID)
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#endif

#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
#include "ui/views/linux_ui/linux_ui.h"
#endif

using content::BrowserThread;
using content::WebContents;
using content::WebContentsObserver;

namespace {

struct AfterStartupTask {
  AfterStartupTask(const base::Location& from_here,
                   const scoped_refptr<base::SequencedTaskRunner>& task_runner,
                   base::OnceClosure task)
      : from_here(from_here), task_runner(task_runner), task(std::move(task)) {}
  ~AfterStartupTask() {}

  const base::Location from_here;
  const scoped_refptr<base::SequencedTaskRunner> task_runner;
  base::OnceClosure task;
};

// The flag may be read on any thread, but must only be set on the UI thread.
base::LazyInstance<base::AtomicFlag>::Leaky g_startup_complete_flag;

// The queue may only be accessed on the UI thread.
base::LazyInstance<base::circular_deque<AfterStartupTask*>>::Leaky
    g_after_startup_tasks;

bool g_schedule_tasks_with_delay = true;

bool IsBrowserStartupComplete() {
  // Be sure to initialize the LazyInstance on the main thread since the flag
  // may only be set on it's initializing thread.
  if (!g_startup_complete_flag.IsCreated())
    return false;
  return g_startup_complete_flag.Get().IsSet();
}

void RunTask(std::unique_ptr<AfterStartupTask> queued_task) {
  // We're careful to delete the caller's |task| on the target runner's thread.
  DCHECK(queued_task->task_runner->RunsTasksInCurrentSequence());
  std::move(queued_task->task).Run();
}

void ScheduleTask(std::unique_ptr<AfterStartupTask> queued_task) {
  // Spread their execution over a brief time.
  constexpr int kMinDelaySec = 0;
  constexpr int kMaxDelaySec = 10;
  scoped_refptr<base::SequencedTaskRunner> target_runner =
      queued_task->task_runner;
  base::Location from_here = queued_task->from_here;
  int delay_in_seconds = g_schedule_tasks_with_delay
                             ? base::RandInt(kMinDelaySec, kMaxDelaySec)
                             : 0;
  target_runner->PostDelayedTask(
      from_here, base::BindOnce(&RunTask, std::move(queued_task)),
      base::TimeDelta::FromSeconds(delay_in_seconds));
}

void QueueTask(std::unique_ptr<AfterStartupTask> queued_task) {
  DCHECK(queued_task);

  // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167
  // for details.
  CHECK(queued_task->task);

  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    // Posted with USER_VISIBLE priority to avoid this becoming an after startup
    // task itself.
    base::PostTask(FROM_HERE,
                   {BrowserThread::UI, base::TaskPriority::USER_VISIBLE},
                   base::BindOnce(QueueTask, std::move(queued_task)));
    return;
  }

  // The flag may have been set while the task to invoke this method
  // on the UI thread was inflight.
  if (IsBrowserStartupComplete()) {
    ScheduleTask(std::move(queued_task));
    return;
  }
  g_after_startup_tasks.Get().push_back(queued_task.release());
}

void SetBrowserStartupIsComplete() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX)
  // Process::Current().CreationTime() is not available on all platforms.
  const base::Time process_creation_time =
      base::Process::Current().CreationTime();
  if (!process_creation_time.is_null()) {
    UMA_HISTOGRAM_LONG_TIMES("Startup.AfterStartupTaskDelayedUntilTime",
                             base::Time::Now() - process_creation_time);
  }
#endif  // defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX)
  UMA_HISTOGRAM_COUNTS_10000("Startup.AfterStartupTaskCount",
                             g_after_startup_tasks.Get().size());
  g_startup_complete_flag.Get().Set();
  for (AfterStartupTask* queued_task : g_after_startup_tasks.Get())
    ScheduleTask(base::WrapUnique(queued_task));
  g_after_startup_tasks.Get().clear();
  g_after_startup_tasks.Get().shrink_to_fit();

#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
  // Make sure we complete the startup notification sequence, or launchers will
  // get confused by not receiving the expected message from the main process.
  views::LinuxUI* linux_ui = views::LinuxUI::instance();
  if (linux_ui)
    linux_ui->NotifyWindowManagerStartupComplete();
#endif
}

// Observes the first visible page load and sets the startup complete
// flag accordingly.
class StartupObserver : public WebContentsObserver {
 public:
  StartupObserver() {}
  ~StartupObserver() override {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    DCHECK(IsBrowserStartupComplete());
  }

  void Start();

 private:
  void OnStartupComplete() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    SetBrowserStartupIsComplete();
    delete this;
  }

  void OnFailsafeTimeout() { OnStartupComplete(); }

  // WebContentsObserver overrides
  void DidFinishLoad(content::RenderFrameHost* render_frame_host,
                     const GURL& validated_url) override {
    if (!render_frame_host->GetParent())
      OnStartupComplete();
  }

  void DidFailLoad(content::RenderFrameHost* render_frame_host,
                   const GURL& validated_url,
                   int error_code) override {
    if (!render_frame_host->GetParent())
      OnStartupComplete();
  }

  // Starting the browser with a file download url will not result in
  // DidFinishLoad firing, so watch for this case too. crbug.com/1006954
  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override {
    if (navigation_handle->IsInMainFrame() && navigation_handle->IsDownload())
      OnStartupComplete();
  }

  void WebContentsDestroyed() override { OnStartupComplete(); }

  SEQUENCE_CHECKER(sequence_checker_);

  base::WeakPtrFactory<StartupObserver> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(StartupObserver);
};

void StartupObserver::Start() {
  // Signal completion quickly when there is no first page to load.
  const int kShortDelaySecs = 3;
  base::TimeDelta delay = base::TimeDelta::FromSeconds(kShortDelaySecs);

#if !defined(OS_ANDROID)
  WebContents* contents = nullptr;
  for (auto* browser : *BrowserList::GetInstance()) {
    contents = browser->tab_strip_model()->GetActiveWebContents();
    if (contents && contents->GetMainFrame() &&
        contents->GetMainFrame()->GetVisibilityState() ==
            content::PageVisibilityState::kVisible) {
      break;
    }
  }

  if (contents) {
    // Give the page time to finish loading.
    const int kLongerDelayMins = 3;
    Observe(contents);
    delay = base::TimeDelta::FromMinutes(kLongerDelayMins);
  }
#else
  // Startup completion is signaled via AfterStartupTaskUtils.java,
  // this is just a failsafe timeout.
  const int kLongerDelayMins = 3;
  delay = base::TimeDelta::FromMinutes(kLongerDelayMins);
#endif  // !defined(OS_ANDROID)

  base::PostDelayedTask(FROM_HERE, {BrowserThread::UI},
                        base::BindOnce(&StartupObserver::OnFailsafeTimeout,
                                       weak_factory_.GetWeakPtr()),
                        delay);
}

}  // namespace

void AfterStartupTaskUtils::StartMonitoringStartup() {
  // The observer is self-deleting.
  (new StartupObserver)->Start();
}

void AfterStartupTaskUtils::PostTask(
    const base::Location& from_here,
    const scoped_refptr<base::SequencedTaskRunner>& destination_runner,
    base::OnceClosure task) {
  if (IsBrowserStartupComplete()) {
    destination_runner->PostTask(from_here, std::move(task));
    return;
  }

  std::unique_ptr<AfterStartupTask> queued_task(
      new AfterStartupTask(from_here, destination_runner, std::move(task)));
  QueueTask(std::move(queued_task));
}

void AfterStartupTaskUtils::SetBrowserStartupIsCompleteForTesting() {
  ::SetBrowserStartupIsComplete();
}

void AfterStartupTaskUtils::SetBrowserStartupIsComplete() {
  ::SetBrowserStartupIsComplete();
}

bool AfterStartupTaskUtils::IsBrowserStartupComplete() {
  return ::IsBrowserStartupComplete();
}

void AfterStartupTaskUtils::UnsafeResetForTesting() {
  DCHECK(g_after_startup_tasks.Get().empty());
  if (!IsBrowserStartupComplete())
    return;
  g_startup_complete_flag.Get().UnsafeResetForTesting();
  DCHECK(!IsBrowserStartupComplete());
}

// static
void AfterStartupTaskUtils::DisableScheduleTaskDelayForTesting() {
  g_schedule_tasks_with_delay = false;
}
