// Copyright (c) 2011 The Chromium OS 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 "metrics/metrics_daemon.h"

#include <fcntl.h>
#include <fstream>
#include <inttypes.h>
#include <math.h>
#include <string.h>
#include <sysexits.h>
#include <time.h>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/hash/hash.h>
#include <base/logging.h>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/system/sys_info.h>
#include <base/threading/thread_task_runner_handle.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/dbus.h>
#include <dbus/message.h>
#include <dbus/object_proxy.h>

#include "metrics/process_meter.h"
#include "power_manager/proto_bindings/suspend.pb.h"
#include "uploader/upload_service.h"

// Returns a pointer for use in PostDelayedTask.  The daemon never exits on its
// own: it can only abort or get killed.  Thus the daemon instance is never
// deleted, and base::Unretained() is appropriate.  This macro exists so we can
// comment this fact in one place.  A function is hard to write because of the
// retturn type.
#define GET_THIS_FOR_POSTTASK() (base::Unretained(this))

using base::FilePath;
using base::StringPrintf;
using base::Time;
using base::TimeDelta;
using base::TimeTicks;
using chromeos_metrics::PersistentInteger;
using std::map;
using std::string;
using std::vector;

namespace chromeos_metrics {
namespace {

const char kCrashReporterInterface[] = "org.chromium.CrashReporter";
const char kCrashReporterUserCrashSignal[] = "UserCrash";
const char kCrashReporterMatchRule[] =
    "type='signal',interface='%s',path='/',member='%s'";

// Build type of an official build.
// See chromite/scripts/cros_set_lsb_release.py.
const char kOfficialBuild[] = "Official Build";

const int kMillisPerSecond = 1000;
const int kSecondsPerMinute = 60;
const int kMinutesPerHour = 60;
const int kHoursPerDay = 24;
const int kMinutesPerDay = kHoursPerDay * kMinutesPerHour;
const int kSecondsPerDay = kSecondsPerMinute * kMinutesPerDay;
const int kDaysPerWeek = 7;
const int kSecondsPerWeek = kSecondsPerDay * kDaysPerWeek;

// Initial interval until the first call to UpdateStats(), The initial update
// happens sooner than subsequent updates to capture short usage times. (e.g.
// situations where a user uses their device for 1-2 minutes only).
const uint32_t kInitialUpdateStatsIntervalMs = 60'000;  // one minute
// Interval between calls to UpdateStats().
const uint32_t kUpdateStatsIntervalMs = 300'000;  // five minutes

// Maximum amount of system memory that will be reported without overflow.
const int kMaximumMemorySizeInKB = 128 * 1024 * 1024;

const char kKernelCrashDetectedFile[] =
    "/run/metrics/external/crash-reporter/kernel-crash-detected";
const char kUncleanShutdownDetectedFile[] =
    "/run/metrics/external/crash-reporter/unclean-shutdown-detected";

// Path of flag created by crouton when it starts.
const char kCroutonStartedFile[] =
    "/run/metrics/external/crouton/crouton-started";

constexpr base::TimeDelta kVmlogInterval = base::TimeDelta::FromSeconds(2);

constexpr char kVmlogDir[] = "/var/log/vmlog";

// Memory use stats collection intervals.  We collect some memory use interval
// at these intervals after boot, and we stop collecting after the last one,
// with the assumption that in most cases the memory use won't change much
// after that.
const int kMemuseIntervals[] = {
    1 * kSecondsPerMinute,    // 1 minute mark
    4 * kSecondsPerMinute,    // 5 minute mark
    25 * kSecondsPerMinute,   // 0.5 hour mark
    120 * kSecondsPerMinute,  // 2.5 hour mark
    600 * kSecondsPerMinute,  // 12.5 hour mark
};

constexpr char kDailyUseTimeName[] = "Platform.DailyUseTime";
constexpr char kCumulativeUseTimeName[] = "Platform.CumulativeUseTime";
constexpr char kCumulativeCpuTimeName[] = "Platform.CumulativeCpuTime";
constexpr char kKernelCrashIntervalName[] = "Platform.KernelCrashInterval";
constexpr char kUncleanShutdownIntervalName[] =
    "Platform.UncleanShutdownInterval";
constexpr char kUserCrashIntervalName[] = "Platform.UserCrashInterval";
constexpr char kAnyCrashesDailyName[] = "Platform.AnyCrashesDaily";
constexpr char kAnyCrashesWeeklyName[] = "Platform.AnyCrashesWeekly";
constexpr char kUserCrashesDailyName[] = "Platform.UserCrashesDaily";
constexpr char kUserCrashesWeeklyName[] = "Platform.UserCrashesWeekly";
constexpr char kKernelCrashesDailyName[] = "Platform.KernelCrashesDaily";
constexpr char kKernelCrashesWeeklyName[] = "Platform.KernelCrashesWeekly";
constexpr char kKernelCrashesSinceUpdateName[] =
    "Platform.KernelCrashesSinceUpdate";
constexpr char kUncleanShutdownsDailyName[] = "Platform.UncleanShutdownsDaily";
constexpr char kUncleanShutdownsWeeklyName[] =
    "Platform.UncleanShutdownsWeekly";

// Max process allocation size in megabytes, used as an upper bound for UMA
// histograms (these are all consumer devices, and 64 GB should be good for a
// few more years).
constexpr int kMaxMemSizeMiB = 64 * (1 << 10);

// Handles the result of an attempt to connect to a D-Bus signal.
void DBusSignalConnected(const std::string& interface,
                         const std::string& signal,
                         bool success) {
  CHECK(success) << "Unable to connect to " << interface << "." << signal;
}

}  // namespace

// disk stats metrics

// The {Read,Write}Sectors numbers are in sectors/second.
// A sector is usually 512 bytes.

const char MetricsDaemon::kMetricReadSectorsLongName[] =
    "Platform.ReadSectorsLong";
const char MetricsDaemon::kMetricWriteSectorsLongName[] =
    "Platform.WriteSectorsLong";
const char MetricsDaemon::kMetricReadSectorsShortName[] =
    "Platform.ReadSectorsShort";
const char MetricsDaemon::kMetricWriteSectorsShortName[] =
    "Platform.WriteSectorsShort";

const int MetricsDaemon::kMetricStatsShortInterval = 1;       // seconds
const int MetricsDaemon::kMetricStatsLongInterval = 30;       // seconds
const int MetricsDaemon::kMetricMeminfoInterval = 30;         // seconds
const int MetricsDaemon::kMetricDetachableBaseInterval = 30;  // seconds
constexpr base::TimeDelta MetricsDaemon::kMetricReportProcessMemoryInterval =
    base::TimeDelta::FromMinutes(10);

// Assume a max rate of 250Mb/s for reads (worse for writes) and 512 byte
// sectors.
const int MetricsDaemon::kMetricSectorsIOMax = 500000;  // sectors/second
const int MetricsDaemon::kMetricSectorsBuckets = 50;    // buckets
// Page size is 4k, sector size is 0.5k.  We're not interested in page fault
// rates that the disk cannot sustain.
const int MetricsDaemon::kMetricPageFaultsMax = kMetricSectorsIOMax / 8;
const int MetricsDaemon::kMetricPageFaultsBuckets = 50;

// Assume a max rate of 54000000 pages/day, based on current 99 percentile
// for Platform.SwapOutLong being about 1500 pages/second. Assume 10 hours
// of use per day.
const int MetricsDaemon::kMetricDailySwapMax = 54000000;
const int MetricsDaemon::kMetricDailySwapBuckets = 50;

// Major page faults, i.e. the ones that require data to be read from disk or
// decompressed from zram.  "Anon" and "File" qualifiers are in grammatically
// incorrect positions for better sorting in UMA.

const char MetricsDaemon::kMetricPageFaultsLongName[] =
    "Platform.PageFaultsLong";
const char MetricsDaemon::kMetricPageFaultsShortName[] =
    "Platform.PageFaultsShort";
const char MetricsDaemon::kMetricFilePageFaultsLongName[] =
    "Platform.PageFaultsFileLong";
const char MetricsDaemon::kMetricFilePageFaultsShortName[] =
    "Platform.PageFaultsFileShort";
const char MetricsDaemon::kMetricAnonPageFaultsLongName[] =
    "Platform.PageFaultsAnonLong";
const char MetricsDaemon::kMetricAnonPageFaultsShortName[] =
    "Platform.PageFaultsAnonShort";

// Swap in and Swap out

const char MetricsDaemon::kMetricSwapInDailyName[] = "Platform.SwapInDaily";
const char MetricsDaemon::kMetricSwapInLongName[] = "Platform.SwapInLong";
const char MetricsDaemon::kMetricSwapInShortName[] = "Platform.SwapInShort";

const char MetricsDaemon::kMetricSwapOutDailyName[] = "Platform.SwapOutDaily";
const char MetricsDaemon::kMetricSwapOutLongName[] = "Platform.SwapOutLong";
const char MetricsDaemon::kMetricSwapOutShortName[] = "Platform.SwapOutShort";

const char MetricsDaemon::kMetricsProcStatFileName[] = "/proc/stat";
const int MetricsDaemon::kMetricsProcStatFirstLineItemsCount = 11;

// Thermal CPU throttling.

const char MetricsDaemon::kMetricScaledCpuFrequencyName[] =
    "Platform.CpuFrequencyThermalScaling";

// Zram sysfs entries.

const char MetricsDaemon::kComprDataSizeName[] = "compr_data_size";
const char MetricsDaemon::kOrigDataSizeName[] = "orig_data_size";
const char MetricsDaemon::kZeroPagesName[] = "zero_pages";
const char MetricsDaemon::kMMStatName[] = "mm_stat";

constexpr char MetricsDaemon::kSysfsThermalZoneFormat[];
constexpr char MetricsDaemon::kSysfsTemperatureValueFile[];
constexpr char MetricsDaemon::kSysfsTemperatureTypeFile[];

constexpr char MetricsDaemon::kMetricTemperatureCpuName[];
constexpr char MetricsDaemon::kMetricTemperatureZeroName[];
constexpr char MetricsDaemon::kMetricTemperatureOneName[];
constexpr char MetricsDaemon::kMetricTemperatureTwoName[];

constexpr int MetricsDaemon::kMetricTemperatureMax;

constexpr base::TimeDelta
    MetricsDaemon::kMinSuspendDurationForAmbientTemperature;

constexpr char MetricsDaemon::kMetricSuspendedTemperatureCpuName[];
constexpr char MetricsDaemon::kMetricSuspendedTemperatureZeroName[];
constexpr char MetricsDaemon::kMetricSuspendedTemperatureOneName[];
constexpr char MetricsDaemon::kMetricSuspendedTemperatureTwoName[];

// Detachable base autosuspend metrics.

const char MetricsDaemon::kMetricDetachableBaseActivePercentName[] =
    "Platform.DetachableBase.ActivePercent";

// Detachable base autosuspend sysfs entries.

const char MetricsDaemon::kHammerSysfsPathPath[] =
    "/run/metrics/external/hammer/hammer_sysfs_path";
const char MetricsDaemon::kDetachableBaseSysfsLevelName[] = "power/level";
const char MetricsDaemon::kDetachableBaseSysfsLevelValue[] = "auto";
const char MetricsDaemon::kDetachableBaseSysfsActiveTimeName[] =
    "power/runtime_active_time";
const char MetricsDaemon::kDetachableBaseSysfsSuspendedTimeName[] =
    "power/runtime_suspended_time";

// crouton metrics

const char MetricsDaemon::kMetricCroutonStarted[] = "Platform.Crouton.Started";

MetricsDaemon::MetricsDaemon()
    : memuse_final_time_(0),
      memuse_interval_index_(0),
      read_sectors_(0),
      write_sectors_(0),
      vmstats_(),
      stats_state_(kStatsShort),
      stats_initial_time_(0),
      ticks_per_second_(0),
      latest_cpu_use_ticks_(0),
      detachable_base_active_time_(0),
      detachable_base_suspended_time_(0),
      thermal_zone_count_(-1) {}

MetricsDaemon::~MetricsDaemon() {}

double MetricsDaemon::GetActiveTime() {
  struct timespec ts;
  int r = clock_gettime(CLOCK_MONOTONIC, &ts);
  if (r < 0) {
    PLOG(WARNING) << "clock_gettime(CLOCK_MONOTONIC) failed";
    return 0;
  } else {
    return ts.tv_sec + static_cast<double>(ts.tv_nsec) / (1000 * 1000 * 1000);
  }
}

int MetricsDaemon::Run() {
  if (CheckSystemCrash(kKernelCrashDetectedFile)) {
    ProcessKernelCrash();
  }

  if (CheckSystemCrash(kUncleanShutdownDetectedFile)) {
    ProcessUncleanShutdown();
  }

  // On OS version change, clear version stats (which are reported daily).
  int32_t version = GetOsVersionHash();
  if (version_cycle_->Get() != version) {
    version_cycle_->Set(version);
    kernel_crashes_version_count_->Set(0);
    version_cumulative_active_use_->Set(0);
    version_cumulative_cpu_use_->Set(0);
  }

  return brillo::DBusDaemon::Run();
}

void MetricsDaemon::RunUploaderTest() {
  upload_service_.reset(new UploadService(
      new SystemProfileCache(true, config_root_), metrics_lib_, server_));
  upload_service_->Init(upload_interval_, metrics_file_,
                        true /* uploads_enabled */);
  upload_service_->UploadEvent();
}

uint32_t MetricsDaemon::GetOsVersionHash() {
  static uint32_t cached_version_hash = 0;
  static bool version_hash_is_cached = false;
  if (version_hash_is_cached)
    return cached_version_hash;
  version_hash_is_cached = true;
  std::string version;
  if (base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_VERSION", &version)) {
    cached_version_hash = base::Hash(version);
  } else if (testing_) {
    cached_version_hash = 42;  // return any plausible value for the hash
  } else {
    LOG(FATAL) << "could not find CHROMEOS_RELEASE_VERSION";
  }
  return cached_version_hash;
}

bool MetricsDaemon::IsOnOfficialBuild() const {
  std::string build_type;
  return (base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BUILD_TYPE",
                                            &build_type) &&
          build_type == kOfficialBuild);
}

void MetricsDaemon::Init(bool testing,
                         bool uploader_active,
                         MetricsLibraryInterface* metrics_lib,
                         const string& diskstats_path,
                         const string& vmstats_path,
                         const string& scaling_max_freq_path,
                         const string& cpuinfo_max_freq_path,
                         const base::TimeDelta& upload_interval,
                         const string& server,
                         const string& metrics_file,
                         const string& config_root,
                         const base::FilePath& backing_dir) {
  testing_ = testing;
  uploader_active_ = uploader_active;
  config_root_ = config_root;
  DCHECK(metrics_lib != nullptr);
  metrics_lib_ = metrics_lib;
  backing_dir_ = backing_dir;

  upload_interval_ = upload_interval;
  server_ = server;
  metrics_file_ = metrics_file;

  // Get ticks per second (HZ) on this system.
  // Sysconf cannot fail, so no sanity checks are needed.
  ticks_per_second_ = sysconf(_SC_CLK_TCK);

  daily_active_use_.reset(
      new PersistentInteger(backing_dir_.Append(kDailyUseTimeName)));
  version_cumulative_active_use_.reset(
      new PersistentInteger(backing_dir_.Append(kCumulativeUseTimeName)));
  version_cumulative_cpu_use_.reset(
      new PersistentInteger(backing_dir_.Append(kCumulativeCpuTimeName)));
  kernel_crash_interval_.reset(
      new PersistentInteger(backing_dir_.Append(kKernelCrashIntervalName)));
  unclean_shutdown_interval_.reset(
      new PersistentInteger(backing_dir_.Append(kUncleanShutdownIntervalName)));
  user_crash_interval_.reset(
      new PersistentInteger(backing_dir_.Append(kUserCrashIntervalName)));
  any_crashes_daily_count_.reset(
      new PersistentInteger(backing_dir_.Append(kAnyCrashesDailyName)));
  any_crashes_weekly_count_.reset(
      new PersistentInteger(backing_dir_.Append(kAnyCrashesWeeklyName)));
  user_crashes_daily_count_.reset(
      new PersistentInteger(backing_dir_.Append(kUserCrashesDailyName)));
  user_crashes_weekly_count_.reset(
      new PersistentInteger(backing_dir_.Append(kUserCrashesWeeklyName)));
  kernel_crashes_daily_count_.reset(
      new PersistentInteger(backing_dir_.Append(kKernelCrashesDailyName)));
  kernel_crashes_weekly_count_.reset(
      new PersistentInteger(backing_dir_.Append(kKernelCrashesWeeklyName)));
  kernel_crashes_version_count_.reset(new PersistentInteger(
      backing_dir_.Append(kKernelCrashesSinceUpdateName)));
  unclean_shutdowns_daily_count_.reset(
      new PersistentInteger(backing_dir_.Append(kUncleanShutdownsDailyName)));
  unclean_shutdowns_weekly_count_.reset(
      new PersistentInteger(backing_dir_.Append(kUncleanShutdownsWeeklyName)));

  daily_cycle_.reset(new PersistentInteger(backing_dir_.Append("daily.cycle")));
  weekly_cycle_.reset(
      new PersistentInteger(backing_dir_.Append("weekly.cycle")));
  version_cycle_.reset(
      new PersistentInteger(backing_dir_.Append("version.cycle")));

  diskstats_path_ = diskstats_path;
  vmstats_path_ = vmstats_path;
  scaling_max_freq_path_ = scaling_max_freq_path;
  cpuinfo_max_freq_path_ = cpuinfo_max_freq_path;

  zone_path_base_ = base::FilePath("/sys/class/thermal/");

  vmstats_daily_success = VmStatsReadStats(&vmstats_daily_start);

  // Start the "last update" time at the time of metrics daemon starting.
  // This isn't entirely accurate -- in general, the tick counter will start
  // counting when the kernel starts executing, while metrics_daemon will only
  // start up once boot has mostly completed.
  // However, we need to initialize because:
  // 1. metrics_daemon might crash and restart. In this case, if we did not
  // initialize last_update_stats_time_, the first values we calculate based on
  // it will be based on the overall uptime of the device, rather than the
  // actual interval between updates.
  // 2. TimeTicks doesn't guarantee anything about when the value it returns
  // will be zero -- only that the value is monotonically nondecreasing. In
  // principle, on some platforms, it could start at a large number on boot.
  last_update_stats_time_ = TimeTicks::Now();

  // If testing, initialize Stats Reporter without connecting DBus
  if (testing_)
    StatsReporterInit();
}

int MetricsDaemon::OnInit() {
  int return_code = brillo::DBusDaemon::OnInit();
  if (return_code != EX_OK)
    return return_code;

  StatsReporterInit();

  // Start collecting meminfo stats.
  ScheduleMeminfoCallback(kMetricMeminfoInterval);
  memuse_final_time_ = GetActiveTime() + kMemuseIntervals[0];
  ScheduleMemuseCallback(kMemuseIntervals[0]);

  // Start collecting process memory stats.
  ScheduleReportProcessMemory(kMetricReportProcessMemoryInterval);

  // Start collecting detachable base stats.
  ScheduleDetachableBaseCallback(kMetricDetachableBaseInterval);

  if (testing_)
    return EX_OK;

  vmlog_writer_.reset(new chromeos_metrics::VmlogWriter(
      base::FilePath(kVmlogDir), kVmlogInterval));
  bus_->AssertOnDBusThread();
  CHECK(bus_->SetUpAsyncOperations());

  if (bus_->IsConnected()) {
    const std::string match_rule =
        base::StringPrintf(kCrashReporterMatchRule, kCrashReporterInterface,
                           kCrashReporterUserCrashSignal);

    // A filter function is used here because there is no permanent object
    // proxy exported by crash_reporter as it is a short-lived program.
    //
    // It might be theoretically possible to convert it to use
    // ObjectProxy::ConnectToSignal, but it's probably not worth the effort,
    // especially since ConnectToSignal uses FilterFunctions under the hood
    // anyways.
    bus_->AddFilterFunction(&MetricsDaemon::MessageFilter, this);

    DBusError error;
    dbus_error_init(&error);
    bus_->AddMatch(match_rule, &error);

    if (dbus_error_is_set(&error)) {
      LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got "
                 << error.name << ": " << error.message;
      return EX_SOFTWARE;
    }

    dbus::ObjectProxy* powerd_proxy = bus_->GetObjectProxy(
        power_manager::kPowerManagerServiceName,
        dbus::ObjectPath(power_manager::kPowerManagerServicePath));

    powerd_proxy->ConnectToSignal(
        power_manager::kPowerManagerInterface,
        power_manager::kSuspendDoneSignal,
        base::Bind(&MetricsDaemon::HandleSuspendDone, GET_THIS_FOR_POSTTASK()),
        base::Bind(&DBusSignalConnected));

  } else {
    LOG(ERROR) << "DBus isn't connected.";
    return EX_UNAVAILABLE;
  }

  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MetricsDaemon::HandleUpdateStatsTimeout,
                 GET_THIS_FOR_POSTTASK()),
      base::TimeDelta::FromMilliseconds(kInitialUpdateStatsIntervalMs));

  // Emit a "0" value on start, to provide a baseline for this metric.
  SendLinearSample(kMetricCroutonStarted, 0, 2, 3);
  SendCroutonStats();

  if (uploader_active_) {
    bool is_official = IsOnOfficialBuild();
    LOG(INFO) << "uploader enabled"
              << (is_official ? "" : " (dummy mode for unofficial build)");
    upload_service_.reset(
        new UploadService(new SystemProfileCache(), metrics_lib_, server_));
    upload_service_->Init(upload_interval_, metrics_file_,
                          is_official /* uploads_enabled */);
  }

  return EX_OK;
}

void MetricsDaemon::OnShutdown(int* return_code) {
  if (!testing_ && bus_->IsConnected()) {
    const std::string match_rule =
        base::StringPrintf(kCrashReporterMatchRule, kCrashReporterInterface,
                           kCrashReporterUserCrashSignal);

    bus_->RemoveFilterFunction(&MetricsDaemon::MessageFilter, this);

    DBusError error;
    dbus_error_init(&error);
    bus_->RemoveMatch(match_rule, &error);

    if (dbus_error_is_set(&error)) {
      LOG(ERROR) << "Failed to remove match rule \"" << match_rule << "\". Got "
                 << error.name << ": " << error.message;
    }
  }
  brillo::DBusDaemon::OnShutdown(return_code);
}

// static
DBusHandlerResult MetricsDaemon::MessageFilter(DBusConnection* connection,
                                               DBusMessage* message,
                                               void* user_data) {
  int message_type = dbus_message_get_type(message);
  if (message_type != DBUS_MESSAGE_TYPE_SIGNAL) {
    DLOG(WARNING) << "unexpected message type " << message_type;
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }

  // Signal messages always have interfaces.
  const std::string interface(dbus_message_get_interface(message));
  const std::string member(dbus_message_get_member(message));

  MetricsDaemon* daemon = static_cast<MetricsDaemon*>(user_data);

  DBusMessageIter iter;
  dbus_message_iter_init(message, &iter);
  if (interface == kCrashReporterInterface) {
    CHECK_EQ(member, kCrashReporterUserCrashSignal);
    daemon->ProcessUserCrash();
  } else {
    // Ignore messages from the bus itself.
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }

  return DBUS_HANDLER_RESULT_HANDLED;
}

// One might argue that parts of this should go into
// chromium/src/base/sys_info_chromeos.c instead, but put it here for now.

TimeDelta MetricsDaemon::GetIncrementalCpuUse() {
  FilePath proc_stat_path = FilePath(kMetricsProcStatFileName);
  std::string proc_stat_string;
  if (!base::ReadFileToString(proc_stat_path, &proc_stat_string)) {
    LOG(WARNING) << "cannot open " << kMetricsProcStatFileName;
    return TimeDelta();
  }

  std::vector<std::string> proc_stat_lines = base::SplitString(
      proc_stat_string, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
  if (proc_stat_lines.empty()) {
    LOG(WARNING) << "cannot parse " << kMetricsProcStatFileName << ": "
                 << proc_stat_string;
    return TimeDelta();
  }
  std::vector<std::string> proc_stat_totals =
      base::SplitString(proc_stat_lines[0], base::kWhitespaceASCII,
                        base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  uint64_t user_ticks, user_nice_ticks, system_ticks;
  if (proc_stat_totals.size() != kMetricsProcStatFirstLineItemsCount ||
      proc_stat_totals[0] != "cpu" ||
      !base::StringToUint64(proc_stat_totals[1], &user_ticks) ||
      !base::StringToUint64(proc_stat_totals[2], &user_nice_ticks) ||
      !base::StringToUint64(proc_stat_totals[3], &system_ticks)) {
    LOG(WARNING) << "cannot parse first line: " << proc_stat_lines[0];
    return TimeDelta(base::TimeDelta::FromSeconds(0));
  }

  uint64_t total_cpu_use_ticks = user_ticks + user_nice_ticks + system_ticks;

  // Sanity check.
  if (total_cpu_use_ticks < latest_cpu_use_ticks_) {
    LOG(WARNING) << "CPU time decreasing from " << latest_cpu_use_ticks_
                 << " to " << total_cpu_use_ticks;
    return TimeDelta();
  }

  uint64_t diff = total_cpu_use_ticks - latest_cpu_use_ticks_;
  latest_cpu_use_ticks_ = total_cpu_use_ticks;
  // Use microseconds to avoid significant truncations.
  return base::TimeDelta::FromMicroseconds(diff * 1000 * 1000 /
                                           ticks_per_second_);
}

void MetricsDaemon::ProcessUserCrash() {
  // Counts the active time up to now.
  UpdateStats(TimeTicks::Now(), Time::Now());

  // Reports the active use time since the last crash and resets it.
  SendAndResetCrashIntervalSample(user_crash_interval_, kUserCrashIntervalName);

  any_crashes_daily_count_->Add(1);
  any_crashes_weekly_count_->Add(1);
  user_crashes_daily_count_->Add(1);
  user_crashes_weekly_count_->Add(1);
}

void MetricsDaemon::ProcessKernelCrash() {
  // Counts the active time up to now.
  UpdateStats(TimeTicks::Now(), Time::Now());

  // Reports the active use time since the last crash and resets it.
  SendAndResetCrashIntervalSample(kernel_crash_interval_,
                                  kKernelCrashIntervalName);

  any_crashes_daily_count_->Add(1);
  any_crashes_weekly_count_->Add(1);
  kernel_crashes_daily_count_->Add(1);
  kernel_crashes_weekly_count_->Add(1);

  kernel_crashes_version_count_->Add(1);
}

void MetricsDaemon::ProcessUncleanShutdown() {
  // Counts the active time up to now.
  UpdateStats(TimeTicks::Now(), Time::Now());

  // Reports the active use time since the last crash and resets it.
  SendAndResetCrashIntervalSample(unclean_shutdown_interval_,
                                  kUncleanShutdownIntervalName);

  unclean_shutdowns_daily_count_->Add(1);
  LOG(INFO) << "metrics_daemon processing unclean shutdown; new value: "
            << unclean_shutdowns_daily_count_->Get();
  unclean_shutdowns_weekly_count_->Add(1);
  any_crashes_daily_count_->Add(1);
  any_crashes_weekly_count_->Add(1);
}

bool MetricsDaemon::CheckSystemCrash(const string& crash_file) {
  FilePath crash_detected(crash_file);
  if (!base::PathExists(crash_detected))
    return false;

  // Deletes the crash-detected file so that the daemon doesn't report
  // another kernel crash in case it's restarted.
  base::DeleteFile(crash_detected);  // not recursive
  return true;
}

void MetricsDaemon::StatsReporterInit() {
  DiskStatsReadStats(&read_sectors_, &write_sectors_);
  VmStatsReadStats(&vmstats_);
  // The first time around just run the long stat, so we don't delay boot.
  stats_state_ = kStatsLong;
  stats_initial_time_ = GetActiveTime();
  if (stats_initial_time_ < 0) {
    LOG(WARNING) << "not collecting disk stats";
  } else {
    ScheduleStatsCallback(kMetricStatsLongInterval);
  }
}

void MetricsDaemon::ScheduleStatsCallback(int wait) {
  if (testing_) {
    return;
  }
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MetricsDaemon::StatsCallback, GET_THIS_FOR_POSTTASK()),
      base::TimeDelta::FromSeconds(wait));
}

bool MetricsDaemon::DiskStatsReadStats(uint64_t* read_sectors,
                                       uint64_t* write_sectors) {
  int nchars;
  int nitems;
  bool success = false;
  char line[200];
  if (diskstats_path_.empty()) {
    return false;
  }
  int file = HANDLE_EINTR(open(diskstats_path_.c_str(), O_RDONLY));
  if (file < 0) {
    PLOG(WARNING) << "cannot open " << diskstats_path_;
    return false;
  }
  nchars = HANDLE_EINTR(read(file, line, sizeof(line)));
  if (nchars < 0) {
    PLOG(WARNING) << "cannot read from " << diskstats_path_;
    return false;
  } else {
    LOG_IF(WARNING, nchars == sizeof(line))
        << "line too long in " << diskstats_path_;
    line[nchars] = '\0';
    nitems = sscanf(line, "%*d %*d %" PRIu64 " %*d %*d %*d %" PRIu64,
                    read_sectors, write_sectors);
    if (nitems == 2) {
      success = true;
    } else {
      LOG(WARNING) << "found " << nitems << " items in " << diskstats_path_
                   << ", expected 2";
    }
  }
  IGNORE_EINTR(close(file));
  return success;
}

bool MetricsDaemon::VmStatsReadStats(struct VmstatRecord* stats) {
  std::ifstream vmstat_stream(vmstats_path_, std::ifstream::in);
  if (vmstat_stream.fail()) {
    LOG(WARNING) << "Couldn't open " << vmstats_path_;
    return false;
  }
  return VmStatsParseStats(&vmstat_stream, stats);
}

void MetricsDaemon::SetThermalZonePathBaseForTest(const base::FilePath& path) {
  zone_path_base_ = path;
}

std::map<std::string, uint64_t> MetricsDaemon::ReadSensorTemperatures() {
  // -1 value means we haven't yet determined how many zones there are
  // this run, we'll iterate until we get an error reading a file.
  bool update_zone_count = thermal_zone_count_ == -1;
  if (update_zone_count)
    thermal_zone_read_failure_notified_.clear();

  std::map<std::string, uint64_t> readings;
  for (int zone = 0; zone < thermal_zone_count_ || update_zone_count; zone++) {
    std::string thermal_zone =
        base::StringPrintf(MetricsDaemon::kSysfsThermalZoneFormat, zone);
    FilePath zone_path = zone_path_base_.Append(thermal_zone);
    std::string type;
    bool type_read_success = base::ReadFileToString(
        zone_path.Append(kSysfsTemperatureTypeFile), &type);

    if (!type_read_success) {
      if (update_zone_count) {
        // We failed to read from a zone. Since this is the first time during
        // this loop, the last valid zone must have been (|zone| - 1), meaning
        // the number of thermal zones must equal |zone|.
        thermal_zone_count_ = zone;
        break;
      }
      LOG(WARNING) << "Failed to read type file for zone " << zone_path.value();
      // This read failed so we'll skip reading the value, but there are more
      // zones to read from so remain in the loop.
      continue;
    }

    if (update_zone_count) {
      thermal_zone_read_failure_notified_.push_back(false);
    }
    bool warn_on_read_failure = !thermal_zone_read_failure_notified_.at(zone);
    uint64_t temperature = 0;
    if (ReadFileToUint64(zone_path.Append(kSysfsTemperatureValueFile),
                         &temperature, warn_on_read_failure)) {
      base::TrimWhitespaceASCII(type, base::TRIM_TRAILING, &type);
      readings.emplace(type, temperature);
      thermal_zone_read_failure_notified_.at(zone) = false;
    } else {
      thermal_zone_read_failure_notified_.at(zone) = true;
    }
  }
  return readings;
}

void MetricsDaemon::SendTemperatureSamples() {
  for (const auto& entry : ReadSensorTemperatures()) {
    std::string metric_name;
    // Name for CPU sensor is platform dependent.
    if (entry.first == "TCPU" || entry.first == "B0D4" ||
        entry.first == "acpitz") {
      metric_name = kMetricTemperatureCpuName;
    } else if (entry.first == "TSR0") {
      metric_name = kMetricTemperatureZeroName;
    } else if (entry.first == "TSR1") {
      metric_name = kMetricTemperatureOneName;
    } else if (entry.first == "TSR2") {
      metric_name = kMetricTemperatureTwoName;
    } else {
      continue;
    }
    // Readings are millidegrees Celsius, convert to degrees.
    int sample = static_cast<int>(round(entry.second / 1000.0));
    SendLinearSample(metric_name, sample, kMetricTemperatureMax,
                     kMetricTemperatureMax + 1);
  }
}

void MetricsDaemon::HandleSuspendDone(dbus::Signal* signal) {
  power_manager::SuspendDone info;
  dbus::MessageReader reader(signal);
  CHECK(reader.PopArrayOfBytesAsProto(&info));
  const base::TimeDelta duration =
      base::TimeDelta::FromInternalValue(info.suspend_duration());
  if (duration >= kMinSuspendDurationForAmbientTemperature) {
    for (const auto& entry : ReadSensorTemperatures()) {
      std::string metric_name;
      // Name for CPU sensor is platform dependent.
      if (entry.first == "TCPU" || entry.first == "B0D4" ||
          entry.first == "acpitz") {
        metric_name = kMetricSuspendedTemperatureCpuName;
      } else if (entry.first == "TSR0") {
        metric_name = kMetricSuspendedTemperatureZeroName;
      } else if (entry.first == "TSR1") {
        metric_name = kMetricSuspendedTemperatureOneName;
      } else if (entry.first == "TSR2") {
        metric_name = kMetricSuspendedTemperatureTwoName;
      } else {
        continue;
      }
      // Readings are millidegrees Celsius, convert to degrees.
      int sample = static_cast<int>(round(entry.second / 1000.0));
      SendLinearSample(metric_name, sample, kMetricTemperatureMax,
                       kMetricTemperatureMax + 1);
    }
  }
}

bool MetricsDaemon::ReadFreqToInt(const string& sysfs_file_name, int* value) {
  const FilePath sysfs_path(sysfs_file_name);
  string value_string;
  if (!base::ReadFileToString(sysfs_path, &value_string)) {
    LOG(WARNING) << "cannot read " << sysfs_path.value().c_str();
    return false;
  }
  if (!base::RemoveChars(value_string, "\n", &value_string)) {
    LOG(WARNING) << "no newline in " << value_string;
    // Continue even though the lack of newline is suspicious.
  }
  if (!base::StringToInt(value_string, value)) {
    LOG(WARNING) << "cannot convert " << value_string << " to int";
    return false;
  }
  return true;
}

void MetricsDaemon::SendCpuThrottleMetrics() {
  // |max_freq| is 0 only the first time through.
  static int max_freq = 0;
  if (max_freq == -1)
    // Give up, as sysfs did not report max_freq correctly.
    return;
  if (max_freq == 0 || testing_) {
    // One-time initialization of max_freq.  (Every time when testing.)
    if (!ReadFreqToInt(cpuinfo_max_freq_path_, &max_freq)) {
      max_freq = -1;
      return;
    }
    if (max_freq == 0) {
      LOG(WARNING) << "sysfs reports 0 max CPU frequency\n";
      max_freq = -1;
      return;
    }
    if (max_freq % 10000 == 1000) {
      // Special case: system has turbo mode, and max non-turbo frequency is
      // max_freq - 1000.  This relies on "normal" (non-turbo) frequencies
      // being multiples of (at least) 10 MHz.  Although there is no guarantee
      // of this, it seems a fairly reasonable assumption.  Otherwise we should
      // read scaling_available_frequencies, sort the frequencies, compare the
      // two highest ones, and check if they differ by 1000 (kHz) (and that's a
      // hack too, no telling when it will change).
      max_freq -= 1000;
    }
  }
  int scaled_freq = 0;
  if (!ReadFreqToInt(scaling_max_freq_path_, &scaled_freq))
    return;
  // Frequencies are in kHz.  If scaled_freq > max_freq, turbo is on, but
  // scaled_freq is not the actual turbo frequency.  We indicate this situation
  // with a 101% value.
  int percent = scaled_freq > max_freq ? 101 : scaled_freq / (max_freq / 100);
  SendLinearSample(kMetricScaledCpuFrequencyName, percent, 101, 102);
}

// Collects disk and vm stats alternating over a short and a long interval.

void MetricsDaemon::StatsCallback() {
  uint64_t read_sectors_now, write_sectors_now;
  struct VmstatRecord vmstats_now;
  double time_now = GetActiveTime();
  double delta_time = time_now - stats_initial_time_;
  if (testing_) {
    // Fake the time when testing.
    delta_time = stats_state_ == kStatsShort ? kMetricStatsShortInterval
                                             : kMetricStatsLongInterval;
  }
  bool diskstats_success =
      DiskStatsReadStats(&read_sectors_now, &write_sectors_now);
  int delta_read = read_sectors_now - read_sectors_;
  int delta_write = write_sectors_now - write_sectors_;
  int read_sectors_per_second = delta_read / delta_time;
  int write_sectors_per_second = delta_write / delta_time;
  bool vmstats_success = VmStatsReadStats(&vmstats_now);
  uint64_t delta_faults = vmstats_now.page_faults_ - vmstats_.page_faults_;
  uint64_t delta_file_faults =
      vmstats_now.file_page_faults_ - vmstats_.file_page_faults_;
  uint64_t delta_anon_faults =
      vmstats_now.anon_page_faults_ - vmstats_.anon_page_faults_;
  uint64_t delta_swap_in = vmstats_now.swap_in_ - vmstats_.swap_in_;
  uint64_t delta_swap_out = vmstats_now.swap_out_ - vmstats_.swap_out_;
  uint64_t page_faults_per_second = delta_faults / delta_time;
  uint64_t file_page_faults_per_second = delta_file_faults / delta_time;
  uint64_t anon_page_faults_per_second = delta_anon_faults / delta_time;
  uint64_t swap_in_per_second = delta_swap_in / delta_time;
  uint64_t swap_out_per_second = delta_swap_out / delta_time;

  switch (stats_state_) {
    case kStatsShort:
      if (diskstats_success) {
        SendSample(kMetricReadSectorsShortName, read_sectors_per_second, 1,
                   kMetricSectorsIOMax, kMetricSectorsBuckets);
        SendSample(kMetricWriteSectorsShortName, write_sectors_per_second, 1,
                   kMetricSectorsIOMax, kMetricSectorsBuckets);
      }
      if (vmstats_success) {
        SendSample(kMetricPageFaultsShortName, page_faults_per_second, 1,
                   kMetricPageFaultsMax, kMetricPageFaultsBuckets);
        SendSample(kMetricFilePageFaultsShortName, file_page_faults_per_second,
                   1, kMetricPageFaultsMax, kMetricPageFaultsBuckets);
        SendSample(kMetricAnonPageFaultsShortName, anon_page_faults_per_second,
                   1, kMetricPageFaultsMax, kMetricPageFaultsBuckets);
        SendSample(kMetricSwapInShortName, swap_in_per_second, 1,
                   kMetricPageFaultsMax, kMetricPageFaultsBuckets);
        SendSample(kMetricSwapOutShortName, swap_out_per_second, 1,
                   kMetricPageFaultsMax, kMetricPageFaultsBuckets);
      }
      // Schedule long callback.
      stats_state_ = kStatsLong;
      ScheduleStatsCallback(kMetricStatsLongInterval -
                            kMetricStatsShortInterval);
      break;
    case kStatsLong:
      if (diskstats_success) {
        SendSample(kMetricReadSectorsLongName, read_sectors_per_second, 1,
                   kMetricSectorsIOMax, kMetricSectorsBuckets);
        SendSample(kMetricWriteSectorsLongName, write_sectors_per_second, 1,
                   kMetricSectorsIOMax, kMetricSectorsBuckets);
        // Reset sector counters.
        read_sectors_ = read_sectors_now;
        write_sectors_ = write_sectors_now;
      }
      if (vmstats_success) {
        SendSample(kMetricPageFaultsLongName, page_faults_per_second, 1,
                   kMetricPageFaultsMax, kMetricPageFaultsBuckets);
        SendSample(kMetricFilePageFaultsLongName, file_page_faults_per_second,
                   1, kMetricPageFaultsMax, kMetricPageFaultsBuckets);
        SendSample(kMetricAnonPageFaultsLongName, anon_page_faults_per_second,
                   1, kMetricPageFaultsMax, kMetricPageFaultsBuckets);
        SendSample(kMetricSwapInLongName, swap_in_per_second, 1,
                   kMetricPageFaultsMax, kMetricPageFaultsBuckets);
        SendSample(kMetricSwapOutLongName, swap_out_per_second, 1,
                   kMetricPageFaultsMax, kMetricPageFaultsBuckets);

        vmstats_ = vmstats_now;
      }
      SendCpuThrottleMetrics();
      SendTemperatureSamples();
      // Set start time for new cycle.
      stats_initial_time_ = time_now;
      // Schedule short callback.
      stats_state_ = kStatsShort;
      ScheduleStatsCallback(kMetricStatsShortInterval);
      break;
    default:
      LOG(FATAL) << "Invalid stats state";
  }
}

void MetricsDaemon::ScheduleMeminfoCallback(int wait) {
  if (testing_)
    return;
  base::TimeDelta wait_delta = base::TimeDelta::FromSeconds(wait);
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MetricsDaemon::MeminfoCallback, GET_THIS_FOR_POSTTASK(),
                 wait_delta),
      wait_delta);
}

void MetricsDaemon::MeminfoCallback(base::TimeDelta wait) {
  string meminfo_raw;
  const FilePath meminfo_path("/proc/meminfo");
  if (!base::ReadFileToString(meminfo_path, &meminfo_raw)) {
    LOG(WARNING) << "cannot read " << meminfo_path.value().c_str();
    return;
  }
  // Make both calls even if the first one fails.  Only stop rescheduling if
  // both calls fail, since some platforms do not support zram.
  bool success = ProcessMeminfo(meminfo_raw);
  success = ReportZram(base::FilePath("/sys/block/zram0")) || success;
  if (success) {
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&MetricsDaemon::MeminfoCallback, GET_THIS_FOR_POSTTASK(),
                   wait),
        wait);
  }
}

void MetricsDaemon::ScheduleReportProcessMemory(base::TimeDelta interval) {
  if (testing_)
    return;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MetricsDaemon::ReportProcessMemoryCallback,
                 GET_THIS_FOR_POSTTASK(), interval),
      interval);
}

void MetricsDaemon::ReportProcessMemoryCallback(base::TimeDelta wait) {
  ReportProcessMemory();
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MetricsDaemon::ReportProcessMemoryCallback,
                 GET_THIS_FOR_POSTTASK(), wait),
      wait);
}

void MetricsDaemon::ReportProcessMemory() {
  base::FilePath procfs_path("/proc");
  base::FilePath run_path("/run");
  ProcessInfo info(procfs_path, run_path);
  info.Collect();
  info.Classify();
  for (int i = 0; i < PG_KINDS_COUNT; i++) {
    ProcessGroupKind kind = static_cast<ProcessGroupKind>(i);
    ProcessMemoryStats stats;
    // base::size is not compile time value, thus not usable by static_assert.
    // use sizeof instead, sizeof(kProcessMemoryUMANames[i]) should return
    // (number of elements * size of pointers), so is sizeof(stats.rss_sizes)
    // since both kProcessMemoryUMANames[i] and rss_sizes are arrays with fixed
    // size defined.
    static_assert(sizeof(kProcessMemoryUMANames[i]) /
                          sizeof(*kProcessMemoryUMANames[i]) ==
                      sizeof(stats.rss_sizes) / sizeof(*stats.rss_sizes),
                  "RSS array size mismatch");
    AccumulateProcessGroupStats(procfs_path, info.GetGroup(kind), &stats);
    ReportProcessGroupStats(kProcessMemoryUMANames[i], stats);
  }
}

void MetricsDaemon::ReportProcessGroupStats(
    const char* const uma_names[MEM_KINDS_COUNT],
    const ProcessMemoryStats& stats) {
  const uint64_t MiB = 1 << 20;
  for (int i = 0; i < base::size(stats.rss_sizes); i++) {
    SendSample(uma_names[i], stats.rss_sizes[i] / MiB, 1, kMaxMemSizeMiB, 50);
  }
}

void MetricsDaemon::ScheduleDetachableBaseCallback(int wait) {
  if (testing_)
    return;

  base::TimeDelta wait_delta = base::TimeDelta::FromSeconds(wait);
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MetricsDaemon::DetachableBaseCallback,
                 GET_THIS_FOR_POSTTASK(), base::FilePath{kHammerSysfsPathPath},
                 wait_delta),
      wait_delta);
}

void MetricsDaemon::DetachableBaseCallback(const base::FilePath sysfs_path_path,
                                           base::TimeDelta wait) {
  uint64_t active_time, suspended_time;

  if (GetDetachableBaseTimes(sysfs_path_path, &active_time, &suspended_time)) {
    // Edge case: disconnected and reconnected since the last callback.
    if (active_time < detachable_base_active_time_ ||
        suspended_time < detachable_base_suspended_time_) {
      DLOG(INFO) << "Detachable base removed (or time counter overflow)";
      detachable_base_active_time_ = active_time;
      detachable_base_suspended_time_ = suspended_time;
    }

    if (detachable_base_active_time_ == 0 &&
        detachable_base_suspended_time_ == 0)
      DLOG(INFO) << "Detachable base detected, start reporting activity";

    uint64_t delta_active = active_time - detachable_base_active_time_;
    uint64_t delta_suspended = suspended_time - detachable_base_suspended_time_;

    if ((delta_active + delta_suspended) > 0) {
      double active_ratio =
          static_cast<double>(delta_active) / (delta_active + delta_suspended);

      DLOG(INFO) << "Detachable base active_ratio: "
                 << base::StringPrintf("%.8f", active_ratio);

      // Linear scale, min=0, max=100, buckets=101.
      SendLinearSample(kMetricDetachableBaseActivePercentName,
                       active_ratio * 100, 100, 101);
    }
  } else {
    if (detachable_base_active_time_ != 0 &&
        detachable_base_suspended_time_ != 0)
      DLOG(INFO) << "Detachable base removed";
    active_time = 0;
    suspended_time = 0;
  }

  detachable_base_active_time_ = active_time;
  detachable_base_suspended_time_ = suspended_time;

  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MetricsDaemon::DetachableBaseCallback,
                 GET_THIS_FOR_POSTTASK(), sysfs_path_path, wait),
      wait);
}

bool MetricsDaemon::GetDetachableBaseTimes(const base::FilePath sysfs_path_path,
                                           uint64_t* active_time,
                                           uint64_t* suspended_time) {
  base::FilePath sysfs_path;
  std::string content;

  if (!base::ReadFileToString(sysfs_path_path, &content))
    return false;
  base::TrimWhitespaceASCII(content, base::TRIM_TRAILING, &content);

  sysfs_path = base::FilePath(content);
  if (!base::ReadFileToString(sysfs_path.Append(kDetachableBaseSysfsLevelName),
                              &content))
    return false;
  base::TrimWhitespaceASCII(content, base::TRIM_TRAILING, &content);

  if (content != "auto")
    return false;

  bool r1 =
      ReadFileToUint64(sysfs_path.Append(kDetachableBaseSysfsActiveTimeName),
                       active_time, false);
  bool r2 =
      ReadFileToUint64(sysfs_path.Append(kDetachableBaseSysfsSuspendedTimeName),
                       suspended_time, false);
  if (!r1 || !r2)
    return false;

  return true;
}

// static
bool MetricsDaemon::ReadFileToUint64(const base::FilePath& path,
                                     uint64_t* value,
                                     bool warn_on_read_failure) {
  std::string content;
  if (!base::ReadFileToString(path, &content)) {
    if (warn_on_read_failure)
      PLOG(WARNING) << "cannot read " << path.MaybeAsASCII();
    return false;
  }
  // Remove final newline.
  base::TrimWhitespaceASCII(content, base::TRIM_TRAILING, &content);
  if (!base::StringToUint64(content, value)) {
    LOG(WARNING) << "invalid integer " << content << " in file "
                 << path.value();
    return false;
  }
  return true;
}

// static
bool MetricsDaemon::ReadZramStat(const base::FilePath& zram_dir,
                                 uint64_t* compr_data_size_out,
                                 uint64_t* orig_data_size_out,
                                 uint64_t* zero_pages_out,
                                 uint64_t* incompr_pages_out) {
  const base::FilePath mm_stat_path = zram_dir.Append(kMMStatName);
  std::string content;

  if (!base::ReadFileToString(mm_stat_path, &content)) {
    // If mm_stat is not present, try to read zram stat from the old stat files.
    if (!ReadFileToUint64(zram_dir.Append(kComprDataSizeName),
                          compr_data_size_out) ||
        !ReadFileToUint64(zram_dir.Append(kOrigDataSizeName),
                          orig_data_size_out) ||
        !ReadFileToUint64(zram_dir.Append(kZeroPagesName), zero_pages_out)) {
      LOG(WARNING) << "Cannot open zram stat files";
      return false;
    }
    *incompr_pages_out = 0;
    return true;
  }

  int num_items =
      sscanf(content.c_str(),
             "%" PRIu64 " %" PRIu64 " %*d %*d %*d %" PRIu64 " %*d %" PRIu64,
             orig_data_size_out, compr_data_size_out, zero_pages_out,
             incompr_pages_out);
  // incompr_pages is only expected in kernel >= 4.19
  if (num_items == 3) {
    *incompr_pages_out = 0;
  }
  if (num_items < 3) {
    LOG(WARNING) << "Found " << num_items << " item(s) in "
                 << mm_stat_path.value() << ", expected at least 3";
    return false;
  }

  return true;
}

bool MetricsDaemon::ReportZram(const base::FilePath& zram_dir) {
  if (!base::DirectoryExists(zram_dir)) {
    return false;
  }

  // Data sizes are in bytes.  |zero_pages| and |incompr_pages| are in number of
  // pages.
  uint64_t compr_data_size, orig_data_size, zero_pages, incompr_pages;
  const size_t page_size = 4096;

  if (!ReadZramStat(zram_dir, &compr_data_size, &orig_data_size, &zero_pages,
                    &incompr_pages)) {
    return false;
  }

  // |orig_data_size| does not include zero-filled pages.
  orig_data_size += zero_pages * page_size;

  if (incompr_pages > 0) {
    // incompr_pages is the number of incompressible 4k pages.
    const int incompr_pages_size = incompr_pages * page_size;
    // The values of interest for incompr_pages size is between 1MB and 1GB.
    // The units are number of 4k pages.
    SendSample("Platform.ZramIncompressiblePages", incompr_pages, 256,
               256 * 1024, 50);
    SendLinearSample("Platform.ZramIncompressibleRatioPercent.PreCompression",
                     incompr_pages_size * 100 / orig_data_size, 100, 101);
    SendLinearSample("Platform.ZramIncompressibleRatioPercent.PostCompression",
                     incompr_pages_size * 100 / compr_data_size, 100, 101);
  }

  const int compr_data_size_mb = compr_data_size >> 20;
  const int savings_mb = (orig_data_size - compr_data_size) >> 20;

  // Report compressed size in megabytes.  100 MB or less has little impact.
  SendSample("Platform.ZramCompressedSize", compr_data_size_mb, 100, 4000, 50);
  SendSample("Platform.ZramSavings", savings_mb, 100, 4000, 50);
  // The compression ratio is multiplied by 100 for better resolution.  The
  // ratios of interest are between 1 and 6 (100% and 600% as reported).  We
  // don't want samples when very little memory is being compressed.
  //
  // A race in older versions of zram can make orig_data_size underflow and
  // be reported as a large positive number, so we also need to ensure that
  // orig_data_size multiplied by 100 isn't going to overflow.
  if (compr_data_size_mb >= 1 &&
      orig_data_size < (1ull << (sizeof(orig_data_size) * 8 - 1)) / 100) {
    SendSample("Platform.ZramCompressionRatioPercent",
               orig_data_size * 100 / compr_data_size, 100, 600, 50);
  }
  // The values of interest for zero_pages are between 1MB and 1GB.  The units
  // are number of pages.
  SendSample("Platform.ZramZeroPages", zero_pages, 256, 256 * 1024, 50);
  // Send ratio sample only when the ratio exists.
  if (orig_data_size > 0) {
    const int zero_percent = zero_pages * page_size * 100 / orig_data_size;
    SendSample("Platform.ZramZeroRatioPercent", zero_percent, 1, 50, 50);
  }

  return true;
}

bool MetricsDaemon::ProcessMeminfo(const string& meminfo_raw) {
  static const MeminfoRecord fields_array[] = {
      {"MemTotal", "MemTotal"},  // SPECIAL CASE: total system memory
      {"MemFree", "MemFree"},
      {"Buffers", "Buffers"},
      {"Cached", "Cached"},
      // { "SwapCached", "SwapCached" },
      {"Active", "Active"},
      {"Inactive", "Inactive"},
      {"ActiveAnon", "Active(anon)", kMeminfoOp_Anon},
      {"InactiveAnon", "Inactive(anon)", kMeminfoOp_Anon},
      {"ActiveFile", "Active(file)", kMeminfoOp_File},
      {"InactiveFile", "Inactive(file)", kMeminfoOp_File},
      {"Unevictable", "Unevictable", kMeminfoOp_HistLog},
      // { "Mlocked", "Mlocked" },
      {"SwapTotal", "SwapTotal", kMeminfoOp_SwapTotal},
      {"SwapFree", "SwapFree", kMeminfoOp_SwapFree},
      // { "Dirty", "Dirty" },
      // { "Writeback", "Writeback" },
      {"AnonPages", "AnonPages"},
      {"Mapped", "Mapped"},
      {"Shmem", "Shmem", kMeminfoOp_HistLog},
      {"Slab", "Slab", kMeminfoOp_HistLog},
      // { "SReclaimable", "SReclaimable" },
      // { "SUnreclaim", "SUnreclaim" },
  };
  vector<MeminfoRecord> fields(fields_array,
                               fields_array + base::size(fields_array));
  if (!FillMeminfo(meminfo_raw, &fields)) {
    return false;
  }
  int total_memory = fields[0].value;
  if (total_memory == 0) {
    // this "cannot happen"
    LOG(WARNING) << "borked meminfo parser";
    return false;
  }
  int swap_total = 0;
  int swap_free = 0;
  int mem_free_derived = 0;    // free + cached + buffers
  int mem_used_derived = 0;    // total - free_derived
  int process_data_total = 0;  // anon (active and inactive) + swap
  int file_total = 0;          // file active and inactive
  // Send all fields retrieved, except total memory.
  for (unsigned int i = 1; i < fields.size(); i++) {
    string metrics_name =
        base::StringPrintf("Platform.Meminfo%s", fields[i].name);
    int percent;
    switch (fields[i].op) {
      case kMeminfoOp_HistPercent:
        // report value as percent of total memory
        percent = fields[i].value * 100 / total_memory;
        SendLinearSample(metrics_name, percent, 100, 101);
        break;
      case kMeminfoOp_HistLog:
        // report value in kbytes, log scale, 256GiB max
        SendSample(metrics_name, fields[i].value, 1, 256 * 1024 * 1024, 100);
        break;
      case kMeminfoOp_SwapTotal:
        swap_total = fields[i].value;
        break;
      case kMeminfoOp_SwapFree:
        swap_free = fields[i].value;
        break;
      case kMeminfoOp_Anon:
        process_data_total += fields[i].value;
        break;
      case kMeminfoOp_File:
        file_total += fields[i].value;
        break;
    }
    if (strcmp(fields[i].match, "MemFree") == 0 ||
        strcmp(fields[i].match, "Buffers") == 0 ||
        strcmp(fields[i].match, "Cached") == 0) {
      mem_free_derived += fields[i].value;
    }
  }
  int swap_used = swap_total - swap_free;
  if (swap_total > 0) {
    int swap_used_percent = swap_used * 100 / swap_total;
    SendSample("Platform.MeminfoSwapUsed", swap_used, 1, 256 * 1024 * 1024,
               100);
    SendLinearSample("Platform.MeminfoSwapUsedPercent", swap_used_percent, 100,
                     101);
  }
  process_data_total += swap_used;
  mem_used_derived = total_memory - mem_free_derived;
  SendSample("Platform.MeminfoMemFreeDerived", mem_free_derived, 1,
             kMaximumMemorySizeInKB, 100);
  SendSample("Platform.MeminfoMemUsedDerived", mem_used_derived, 1,
             kMaximumMemorySizeInKB, 100);
  SendSample("Platform.MeminfoMemTotal", total_memory, 1,
             kMaximumMemorySizeInKB, 100);
  SendSample("Platform.MeminfoProcessDataTotal", process_data_total, 1,
             kMaximumMemorySizeInKB, 100);
  SendSample("Platform.MeminfoFileTotal", file_total, 1, kMaximumMemorySizeInKB,
             100);
  return true;
}

bool MetricsDaemon::FillMeminfo(const string& meminfo_raw,
                                vector<MeminfoRecord>* fields) {
  vector<string> lines = base::SplitString(
      meminfo_raw, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  // Scan meminfo output and collect field values.  Each field name has to
  // match a meminfo entry (case insensitive) after removing non-alpha
  // characters from the entry.
  size_t ifield = 0;
  for (size_t iline = 0; iline < lines.size() && ifield < fields->size();
       iline++) {
    vector<string> tokens = base::SplitString(
        lines[iline], ": ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    if (strcmp((*fields)[ifield].match, tokens[0].c_str()) == 0) {
      // Name matches. Parse value and save.
      char* rest;
      (*fields)[ifield].value =
          static_cast<int>(strtol(tokens[1].c_str(), &rest, 10));
      if (*rest != '\0') {
        LOG(WARNING) << "missing meminfo value";
        return false;
      }
      ifield++;
    }
  }
  if (ifield < fields->size()) {
    // End of input reached while scanning.
    LOG(WARNING) << "cannot find field " << (*fields)[ifield].match
                 << " and following";
    return false;
  }
  return true;
}

void MetricsDaemon::ScheduleMemuseCallback(double interval) {
  if (testing_) {
    return;
  }
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MetricsDaemon::MemuseCallback, GET_THIS_FOR_POSTTASK()),
      base::TimeDelta::FromSeconds(interval));
}

void MetricsDaemon::MemuseCallback() {
  // Since we only care about active time (i.e. uptime minus sleep time) but
  // the callbacks are driven by real time (uptime), we check if we should
  // reschedule this callback due to intervening sleep periods.
  double now = GetActiveTime();
  // Avoid intervals of less than one second.
  double remaining_time = ceil(memuse_final_time_ - now);
  if (remaining_time > 0) {
    ScheduleMemuseCallback(remaining_time);
  } else {
    // Report stats and advance the measurement interval unless there are
    // errors or we've completed the last interval.
    if (MemuseCallbackWork() &&
        memuse_interval_index_ < base::size(kMemuseIntervals)) {
      double interval = kMemuseIntervals[memuse_interval_index_++];
      memuse_final_time_ = now + interval;
      ScheduleMemuseCallback(interval);
    }
  }
}

bool MetricsDaemon::MemuseCallbackWork() {
  string meminfo_raw;
  const FilePath meminfo_path("/proc/meminfo");
  if (!base::ReadFileToString(meminfo_path, &meminfo_raw)) {
    LOG(WARNING) << "cannot read " << meminfo_path.value().c_str();
    return false;
  }
  return ProcessMemuse(meminfo_raw);
}

bool MetricsDaemon::ProcessMemuse(const string& meminfo_raw) {
  static const MeminfoRecord fields_array[] = {
      {"MemTotal", "MemTotal"},  // SPECIAL CASE: total system memory
      {"ActiveAnon", "Active(anon)"},
      {"InactiveAnon", "Inactive(anon)"},
  };
  vector<MeminfoRecord> fields(fields_array,
                               fields_array + base::size(fields_array));
  if (!FillMeminfo(meminfo_raw, &fields)) {
    return false;
  }
  int total = fields[0].value;
  int active_anon = fields[1].value;
  int inactive_anon = fields[2].value;
  if (total == 0) {
    // this "cannot happen"
    LOG(WARNING) << "borked meminfo parser";
    return false;
  }
  string metrics_name =
      base::StringPrintf("Platform.MemuseAnon%d", memuse_interval_index_);
  SendLinearSample(metrics_name, (active_anon + inactive_anon) * 100 / total,
                   100, 101);
  return true;
}

void MetricsDaemon::SendSample(
    const string& name, int sample, int min, int max, int nbuckets) {
  metrics_lib_->SendToUMA(name, sample, min, max, nbuckets);
}

void MetricsDaemon::SendKernelCrashesCumulativeCountStats() {
  // Report the number of crashes for this OS version, but don't clear the
  // counter.  It is cleared elsewhere on version change.
  int64_t crashes_count = kernel_crashes_version_count_->Get();
  SendSample(kKernelCrashesSinceUpdateName, crashes_count,
             1,     // value of first bucket
             500,   // value of last bucket
             100);  // number of buckets

  int64_t cpu_use_ms = version_cumulative_cpu_use_->Get();
  SendSample(kCumulativeCpuTimeName,
             cpu_use_ms / 1000,  // stat is in seconds
             1,                  // device may be used very little...
             8 * 1000 * 1000,    // ... or a lot (a little over 90 days)
             100);

  // On the first run after an autoupdate, cpu_use_ms and active_use_seconds
  // can be zero.  Avoid division by zero.
  if (cpu_use_ms > 0) {
    // Send the crash frequency since update in number of crashes per CPU year.
    SendSample("Platform.KernelCrashesPerCpuYear",
               crashes_count * kSecondsPerDay * 365 * 1000 / cpu_use_ms, 1,
               1000 * 1000,  // about one crash every 30s of CPU time
               100);
  }

  int64_t active_use_seconds = version_cumulative_active_use_->Get();
  if (active_use_seconds > 0) {
    SendSample(kCumulativeUseTimeName, active_use_seconds,
               1,                // device may be used very little...
               8 * 1000 * 1000,  // ... or a lot (about 90 days)
               100);
    // Same as above, but per year of active time.
    SendSample("Platform.KernelCrashesPerActiveYear",
               crashes_count * kSecondsPerDay * 365 / active_use_seconds, 1,
               1000 * 1000,  // about one crash every 30s of active time
               100);
  }
}

void MetricsDaemon::SendAndResetDailyUseSample() {
  // Since metrics_daemon only updates statistics every kUpdateStatsIntervalMs,
  // we will often report devices that are active for exactly 24 hours as being
  // active for slightly more than 24 hours. Round down in such cases to exactly
  // 24 hours, since we cannot be active for more than 24 hours in a day.  Do
  // *not* round down times more than that, because they could be due to
  // unrelated bugs that we don't want to mask.
  int64_t dau_seconds = daily_active_use_->GetAndClear();
  if (dau_seconds > kSecondsPerDay &&
      dau_seconds <=
          kSecondsPerDay + (kUpdateStatsIntervalMs / kMillisPerSecond)) {
    // Shift the extra over to the current day.
    daily_active_use_->Add(dau_seconds - kSecondsPerDay);

    // Then record only the maximum daily amount today.
    dau_seconds = kSecondsPerDay;
  }
  SendSample(kDailyUseTimeName, dau_seconds,
             1,               // value of first bucket
             kSecondsPerDay,  // value of last bucket
             50);             // number of buckets
}

void MetricsDaemon::SendAndResetCrashIntervalSample(
    const std::unique_ptr<PersistentInteger>& interval,
    const std::string& name) {
  SendSample(name, interval->GetAndClear(),
             1,                    // value of first bucket
             4 * kSecondsPerWeek,  // value of last bucket
             50);                  // number of buckets
}

void MetricsDaemon::SendAndResetCrashFrequencySample(
    const std::unique_ptr<PersistentInteger>& frequency,
    const std::string& name) {
  SendSample(name, frequency->GetAndClear(),
             1,    // value of first bucket
             100,  // value of last bucket
             50);  // number of buckets
}

void MetricsDaemon::SendAndResetDailyVmstats() {
  struct VmstatRecord vmstats_now;
  bool vmstats_success = VmStatsReadStats(&vmstats_now);
  if (vmstats_success && vmstats_daily_success) {
    uint64_t delta_swap_in =
        vmstats_now.swap_in_ - vmstats_daily_start.swap_in_;
    uint64_t delta_swap_out =
        vmstats_now.swap_out_ - vmstats_daily_start.swap_out_;
    SendSample(kMetricSwapInDailyName, delta_swap_in, 1, kMetricDailySwapMax,
               kMetricDailySwapBuckets);
    SendSample(kMetricSwapOutDailyName, delta_swap_out, 1, kMetricDailySwapMax,
               kMetricDailySwapBuckets);
  }
  vmstats_daily_start = vmstats_now;
  vmstats_daily_success = vmstats_success;
}

void MetricsDaemon::SendLinearSample(const string& name,
                                     int sample,
                                     int max,
                                     int nbuckets) {
  // TODO(semenzato): add a proper linear histogram to the Chrome external
  // metrics API.
  LOG_IF(FATAL, nbuckets != max + 1) << "unsupported histogram scale";
  metrics_lib_->SendEnumToUMA(name, sample, max);
}

void MetricsDaemon::SendCroutonStats() {
  // Report the presence of kCroutonStartedFile. We only report each state
  // exactly once per boot. "0" state reported on init.
  if (PathExists(FilePath(kCroutonStartedFile))) {
    SendLinearSample(kMetricCroutonStarted, 1, 2, 3);
  } else {
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&MetricsDaemon::SendCroutonStats, GET_THIS_FOR_POSTTASK()),
        base::TimeDelta::FromMilliseconds(kUpdateStatsIntervalMs));
  }
}

void MetricsDaemon::UpdateStats(TimeTicks now_ticks, Time now_wall_time) {
  const int elapsed_seconds = (now_ticks - last_update_stats_time_).InSeconds();
  daily_active_use_->Add(elapsed_seconds);
  version_cumulative_active_use_->Add(elapsed_seconds);
  user_crash_interval_->Add(elapsed_seconds);
  kernel_crash_interval_->Add(elapsed_seconds);
  version_cumulative_cpu_use_->Add(GetIncrementalCpuUse().InMilliseconds());
  last_update_stats_time_ = now_ticks;

  const TimeDelta since_epoch = now_wall_time - Time::UnixEpoch();
  const int day = since_epoch.InDays();
  const int week = day / 7;

  if (daily_cycle_->Get() != day) {
    daily_cycle_->Set(day);
    SendAndResetDailyUseSample();
    SendAndResetCrashFrequencySample(any_crashes_daily_count_,
                                     kAnyCrashesDailyName);
    SendAndResetCrashFrequencySample(user_crashes_daily_count_,
                                     kUserCrashesDailyName);
    SendAndResetCrashFrequencySample(kernel_crashes_daily_count_,
                                     kKernelCrashesDailyName);
    SendAndResetCrashFrequencySample(unclean_shutdowns_daily_count_,
                                     kUncleanShutdownsDailyName);
    SendKernelCrashesCumulativeCountStats();
    SendAndResetDailyVmstats();
  }

  if (weekly_cycle_->Get() != week) {
    weekly_cycle_->Set(week);
    SendAndResetCrashFrequencySample(any_crashes_weekly_count_,
                                     kAnyCrashesWeeklyName);
    SendAndResetCrashFrequencySample(user_crashes_weekly_count_,
                                     kUserCrashesWeeklyName);
    SendAndResetCrashFrequencySample(kernel_crashes_weekly_count_,
                                     kKernelCrashesWeeklyName);
    SendAndResetCrashFrequencySample(unclean_shutdowns_weekly_count_,
                                     kUncleanShutdownsWeeklyName);
  }
}

void MetricsDaemon::HandleUpdateStatsTimeout() {
  UpdateStats(TimeTicks::Now(), Time::Now());
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&MetricsDaemon::HandleUpdateStatsTimeout,
                 GET_THIS_FOR_POSTTASK()),
      base::TimeDelta::FromMilliseconds(kUpdateStatsIntervalMs));
}

}  // namespace chromeos_metrics
