// Copyright 2017 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 "media/audio/alive_checker.h"

#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/threading/thread_task_runner_handle.h"

namespace media {

AliveChecker::AliveChecker(base::RepeatingClosure dead_callback,
                           base::TimeDelta check_interval,
                           base::TimeDelta timeout,
                           bool stop_at_first_alive_notification,
                           bool pause_check_during_suspend)
    : AliveChecker(std::move(dead_callback),
                   check_interval,
                   timeout,
                   stop_at_first_alive_notification,
                   pause_check_during_suspend,
                   PowerObserverHelperFactoryCallback()) {}

AliveChecker::AliveChecker(
    base::RepeatingClosure dead_callback,
    base::TimeDelta check_interval,
    base::TimeDelta timeout,
    bool stop_at_first_alive_notification,
    PowerObserverHelperFactoryCallback power_observer_helper_factory_callback)
    : AliveChecker(std::move(dead_callback),
                   check_interval,
                   timeout,
                   stop_at_first_alive_notification,
                   true,
                   std::move(power_observer_helper_factory_callback)) {}

// The private constructor called by the above public constructors.
AliveChecker::AliveChecker(
    base::RepeatingClosure dead_callback,
    base::TimeDelta check_interval,
    base::TimeDelta timeout,
    bool stop_at_first_alive_notification,
    bool pause_check_during_suspend,
    PowerObserverHelperFactoryCallback power_observer_helper_factory_callback)
    : check_interval_(check_interval),
      timeout_(timeout),
      task_runner_(base::ThreadTaskRunnerHandle::Get()),
      dead_callback_(std::move(dead_callback)),
      stop_at_first_alive_notification_(stop_at_first_alive_notification),
      weak_factory_(this) {
  DCHECK(!dead_callback_.is_null());
  DCHECK_GT(check_interval_, base::TimeDelta());
  DCHECK_GT(timeout_, check_interval_);

  if (pause_check_during_suspend) {
    // When suspending, we don't need to take any action. When resuming, we
    // reset |last_alive_notification_time_| to avoid false alarms.
    // Unretained is safe since the PowerObserverHelper runs the callback on
    // the task runner the AliveChecker (and consequently the
    // PowerObserverHelper) is destroyed on.
    if (power_observer_helper_factory_callback.is_null()) {
      power_observer_ = std::make_unique<PowerObserverHelper>(
          task_runner_, base::DoNothing(),
          base::Bind(
              &AliveChecker::SetLastAliveNotificationTimeToNowOnTaskRunner,
              base::Unretained(this)));
    } else {
      power_observer_ =
          std::move(power_observer_helper_factory_callback)
              .Run(task_runner_, base::DoNothing(),
                   base::Bind(&AliveChecker::
                                  SetLastAliveNotificationTimeToNowOnTaskRunner,
                              base::Unretained(this)));
    }
  } else {
    // If |pause_check_during_suspend| is false, we expect an empty factory
    // callback.
    DCHECK(power_observer_helper_factory_callback.is_null());
  }
}

AliveChecker::~AliveChecker() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
}

void AliveChecker::Start() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());

  SetLastAliveNotificationTimeToNowOnTaskRunner();
  detected_dead_ = false;

  DCHECK(!check_alive_timer_);
  check_alive_timer_ = std::make_unique<base::RepeatingTimer>();
  check_alive_timer_->Start(FROM_HERE, check_interval_, this,
                            &AliveChecker::CheckIfAlive);
  DCHECK(check_alive_timer_->IsRunning());
}

void AliveChecker::Stop() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  check_alive_timer_.reset();
}

bool AliveChecker::DetectedDead() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  return detected_dead_;
}

void AliveChecker::NotifyAlive() {
  if (!task_runner_->RunsTasksInCurrentSequence()) {
    // We don't need high precision for setting |last_alive_notification_time_|
    // so we don't have to care about the delay added with posting the task.
    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&AliveChecker::NotifyAlive, weak_factory_.GetWeakPtr()));
    return;
  }

  SetLastAliveNotificationTimeToNowOnTaskRunner();
  if (stop_at_first_alive_notification_)
    Stop();
}

void AliveChecker::CheckIfAlive() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());

  // The reason we check a flag instead of stopping the timer that runs this
  // function at suspend is that it would require knowing what state we're in
  // when resuming and maybe start the timer. Also, we would still need this
  // flag anyway to maybe start the timer at stream creation.
  // TODO(grunell): Suspend/resume notifications are not supported on Linux. We
  // could possibly use wall clock time as a complement to be able to detect
  // time jumps that probably are caused by suspend/resume.
  if (power_observer_ && power_observer_->IsSuspending())
    return;

  if (base::TimeTicks::Now() - last_alive_notification_time_ > timeout_) {
    Stop();
    detected_dead_ = true;
    dead_callback_.Run();
  }
}

void AliveChecker::SetLastAliveNotificationTimeToNowOnTaskRunner() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  last_alive_notification_time_ = base::TimeTicks::Now();
}

}  // namespace media
