// Copyright 2014 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 "content/browser/power_usage_monitor_impl.h"

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/power_usage_monitor.h"
#include "content/public/browser/render_process_host.h"

namespace content {

namespace {

// Wait this long after power on before enabling power usage monitoring.
const int kMinUptimeMinutes = 30;

// Minimum discharge time after which we collect the discharge rate.
const int kMinDischargeMinutes = 30;

class PowerUsageMonitorSystemInterface
    : public PowerUsageMonitor::SystemInterface {
 public:
  explicit PowerUsageMonitorSystemInterface(PowerUsageMonitor* owner)
      : power_usage_monitor_(owner),
        weak_ptr_factory_(this) {}
  ~PowerUsageMonitorSystemInterface() override {}

  void ScheduleHistogramReport(base::TimeDelta delay) override {
    BrowserThread::PostDelayedTask(
        BrowserThread::UI,
        FROM_HERE,
        base::Bind(
            &PowerUsageMonitorSystemInterface::ReportBatteryLevelHistogram,
            weak_ptr_factory_.GetWeakPtr(),
            Now(),
            delay),
        delay);
  }

  void CancelPendingHistogramReports() override {
    weak_ptr_factory_.InvalidateWeakPtrs();
  }

  void RecordDischargePercentPerHour(int percent_per_hour) override {
    UMA_HISTOGRAM_PERCENTAGE("Power.BatteryDischargePercentPerHour",
                             percent_per_hour);
  }

  base::Time Now() override { return base::Time::Now(); }

 protected:
  void ReportBatteryLevelHistogram(base::Time start_time,
                                   base::TimeDelta discharge_time) {
    // It's conceivable that the code to cancel pending histogram reports on
    // system suspend, will only get called after the system has woken up.
    // To mitigage this, check whether more time has passed than expected and
    // abort histogram recording in this case.

    // Delayed tasks are subject to timer coalescing and can fire anywhere from
    // delay -> delay * 1.5) . In most cases, the OS should fire the task
    // at the next wakeup and not as late as it can.
    // A threshold of 2 minutes is used, since that should be large enough to
    // take the slop factor due to coalescing into account.
    base::TimeDelta threshold = discharge_time +
        base::TimeDelta::FromMinutes(2);
    if ((Now() - start_time) > threshold) {
      return;
    }

    const std::string histogram_name = base::StringPrintf(
        "Power.BatteryDischarge_%d", discharge_time.InMinutes());
    base::HistogramBase* histogram =
        base::Histogram::FactoryGet(histogram_name,
                                    1,
                                    100,
                                    101,
                                    base::Histogram::kUmaTargetedHistogramFlag);
    double discharge_amount = power_usage_monitor_->discharge_amount();
    histogram->Add(discharge_amount * 100);
  }

 private:
  PowerUsageMonitor* power_usage_monitor_;  // Not owned.

  // Used to cancel in progress delayed tasks.
  base::WeakPtrFactory<PowerUsageMonitorSystemInterface> weak_ptr_factory_;
};

}  // namespace

void StartPowerUsageMonitor() {
  static base::LazyInstance<PowerUsageMonitor>::Leaky monitor =
     LAZY_INSTANCE_INITIALIZER;
  monitor.Get().Start();
}

PowerUsageMonitor::PowerUsageMonitor()
    : callback_(base::Bind(&PowerUsageMonitor::OnBatteryStatusUpdate,
          base::Unretained(this))),
      system_interface_(new PowerUsageMonitorSystemInterface(this)),
      started_(false),
      tracking_discharge_(false),
      on_battery_power_(false),
      initial_battery_level_(0),
      current_battery_level_(0) {
}

PowerUsageMonitor::~PowerUsageMonitor() {
  if (started_)
    base::PowerMonitor::Get()->RemoveObserver(this);
}

void PowerUsageMonitor::Start() {
  // Power monitoring may be delayed based on uptime, but renderer process
  // lifetime tracking needs to start immediately so processes created before
  // then are accounted for.
  registrar_.Add(this,
                 NOTIFICATION_RENDERER_PROCESS_CREATED,
                 NotificationService::AllBrowserContextsAndSources());
  registrar_.Add(this,
                 NOTIFICATION_RENDERER_PROCESS_CLOSED,
                 NotificationService::AllBrowserContextsAndSources());
  subscription_ =
      device::BatteryStatusService::GetInstance()->AddCallback(callback_);

  // Delay initialization until the system has been up for a while.
  // This is to mitigate the effect of increased power draw during system start.
  base::TimeDelta uptime =
      base::TimeDelta::FromMilliseconds(base::SysInfo::Uptime());
  base::TimeDelta min_uptime = base::TimeDelta::FromMinutes(kMinUptimeMinutes);
  if (uptime < min_uptime) {
    base::TimeDelta delay = min_uptime - uptime;
    BrowserThread::PostDelayedTask(
        BrowserThread::UI,
        FROM_HERE,
        base::Bind(&PowerUsageMonitor::StartInternal, base::Unretained(this)),
        delay);
  } else {
    StartInternal();
  }
}

void PowerUsageMonitor::StartInternal() {
  DCHECK(!started_);
  started_ = true;

  // PowerMonitor is used to get suspend/resume notifications.
  base::PowerMonitor::Get()->AddObserver(this);
}

void PowerUsageMonitor::DischargeStarted(double battery_level) {
  on_battery_power_ = true;

  // If all browser windows are closed, don't report power metrics since
  // Chrome's power draw is likely not significant.
  if (live_renderer_ids_.empty())
    return;

  // Cancel any in-progress ReportBatteryLevelHistogram() calls.
  system_interface_->CancelPendingHistogramReports();

  tracking_discharge_ = true;
  start_discharge_time_ = system_interface_->Now();

  initial_battery_level_ = battery_level;
  current_battery_level_ = battery_level;

  const int kBatteryReportingIntervalMinutes[] = {5, 15, 30};
  for (auto reporting_interval : kBatteryReportingIntervalMinutes) {
    base::TimeDelta delay = base::TimeDelta::FromMinutes(reporting_interval);
    system_interface_->ScheduleHistogramReport(delay);
  }
}

void PowerUsageMonitor::WallPowerConnected(double battery_level) {
  on_battery_power_ = false;

  if (tracking_discharge_) {
    DCHECK(!start_discharge_time_.is_null());
    base::TimeDelta discharge_time =
        system_interface_->Now() - start_discharge_time_;

    if (discharge_time.InMinutes() > kMinDischargeMinutes) {
      // Record the rate at which the battery discharged over the entire period
      // the system was on battery power.
      double discharge_hours = discharge_time.InSecondsF() / 3600.0;
      int percent_per_hour =
          floor(((discharge_amount() / discharge_hours) * 100.0) + 0.5);
      system_interface_->RecordDischargePercentPerHour(percent_per_hour);
    }
  }

  // Cancel any in-progress ReportBatteryLevelHistogram() calls.
  system_interface_->CancelPendingHistogramReports();

  initial_battery_level_ = 0;
  current_battery_level_ = 0;
  start_discharge_time_ = base::Time();
  tracking_discharge_ = false;
}

void PowerUsageMonitor::OnBatteryStatusUpdate(
    const device::BatteryStatus& status) {
  bool now_on_battery_power = (status.charging == 0);
  bool was_on_battery_power = on_battery_power_;
  double battery_level = status.level;

  if (now_on_battery_power == was_on_battery_power) {
    if (now_on_battery_power)
      current_battery_level_ = battery_level;
    return;
  } else if (now_on_battery_power) {  // Wall power disconnected.
    DischargeStarted(battery_level);
  } else {  // Wall power connected.
    WallPowerConnected(battery_level);
  }
}

void PowerUsageMonitor::OnRenderProcessNotification(int type, int rph_id) {
  size_t previous_num_live_renderers = live_renderer_ids_.size();

  if (type == NOTIFICATION_RENDERER_PROCESS_CREATED) {
    live_renderer_ids_.insert(rph_id);
  } else if (type == NOTIFICATION_RENDERER_PROCESS_CLOSED) {
    live_renderer_ids_.erase(rph_id);
  } else {
    NOTREACHED()  << "Unexpected notification type: " << type;
  }

  if (live_renderer_ids_.empty() && previous_num_live_renderers != 0) {
    // All render processes have died.
    CancelPendingHistogramReporting();
    tracking_discharge_ = false;
  }

}

void PowerUsageMonitor::SetSystemInterfaceForTest(
    scoped_ptr<SystemInterface> interface) {
  system_interface_ = interface.Pass();
}

void PowerUsageMonitor::OnPowerStateChange(bool on_battery_power) {
}

void PowerUsageMonitor::OnResume() {
}

void PowerUsageMonitor::OnSuspend() {
  CancelPendingHistogramReporting();
}

void PowerUsageMonitor::Observe(int type,
                                const NotificationSource& source,
                                const NotificationDetails& details) {
  RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
  OnRenderProcessNotification(type, rph->GetID());
}

void PowerUsageMonitor::CancelPendingHistogramReporting() {
  // Cancel any in-progress histogram reports and reporting of discharge UMA.
  system_interface_->CancelPendingHistogramReports();
}

}  // namespace content
