blob: 82401c648fac3b8f059d97fcec58e80a272bdb06 [file] [log] [blame]
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -07001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Bertrand SIMONNET4b915ae2015-07-28 15:38:14 -07005#include "uploader/system_profile_cache.h"
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -07006
Bertrand SIMONNETbd3505e2015-08-04 14:04:51 -07007#include <base/files/file_util.h>
8#include <base/guid.h>
9#include <base/logging.h>
10#include <base/strings/string_number_conversions.h>
11#include <base/strings/string_util.h>
12#include <base/sys_info.h>
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070013#include <string>
14#include <vector>
15
Bertrand SIMONNETbd3505e2015-08-04 14:04:51 -070016#include "constants.h"
Bertrand SIMONNET4b915ae2015-07-28 15:38:14 -070017#include "persistent_integer.h"
18#include "uploader/metrics_log_base.h"
19#include "uploader/proto/chrome_user_metrics_extension.pb.h"
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070020
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070021namespace {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070022
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070023const char kPersistentSessionIdFilename[] = "Sysinfo.SessionId";
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070024
25} // namespace
26
Bertrand SIMONNETa8bcc182014-12-19 09:35:15 -080027std::string ChannelToString(
28 const metrics::SystemProfileProto_Channel& channel) {
29 switch (channel) {
30 case metrics::SystemProfileProto::CHANNEL_STABLE:
31 return "STABLE";
32 case metrics::SystemProfileProto::CHANNEL_DEV:
33 return "DEV";
34 case metrics::SystemProfileProto::CHANNEL_BETA:
35 return "BETA";
36 case metrics::SystemProfileProto::CHANNEL_CANARY:
37 return "CANARY";
38 default:
39 return "UNKNOWN";
40 }
41}
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070042
43SystemProfileCache::SystemProfileCache()
44 : initialized_(false),
45 testing_(false),
46 config_root_("/"),
47 session_id_(new chromeos_metrics::PersistentInteger(
48 kPersistentSessionIdFilename)) {
49}
50
51SystemProfileCache::SystemProfileCache(bool testing,
52 const std::string& config_root)
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070053 : initialized_(false),
Bertrand SIMONNETeb815be2014-09-11 07:38:17 -070054 testing_(testing),
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070055 config_root_(config_root),
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070056 session_id_(new chromeos_metrics::PersistentInteger(
57 kPersistentSessionIdFilename)) {
58}
59
60bool SystemProfileCache::Initialize() {
61 CHECK(!initialized_)
62 << "this should be called only once in the metrics_daemon lifetime.";
63
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -070064 std::string channel;
65 if (!base::SysInfo::GetLsbReleaseValue("BRILLO_CHANNEL", &channel) ||
66 !base::SysInfo::GetLsbReleaseValue("BRILLO_VERSION", &profile_.version) ||
67 !base::SysInfo::GetLsbReleaseValue("BRILLO_BUILD_TARGET_ID",
68 &profile_.build_target_id)) {
69 LOG(ERROR) << "Could not initialize system profile.";
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070070 return false;
71 }
72
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070073 profile_.client_id =
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -070074 testing_ ? "client_id_test" :
75 GetPersistentGUID(metrics::kMetricsGUIDFilePath);
76 profile_.hardware_class = "unknown";
77 profile_.channel = ProtoChannelFromString(channel);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070078
79 // Increment the session_id everytime we initialize this. If metrics_daemon
80 // does not crash, this should correspond to the number of reboots of the
81 // system.
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070082 session_id_->Add(1);
Ben Chanf05ab402014-08-07 00:54:59 -070083 profile_.session_id = static_cast<int32_t>(session_id_->Get());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070084
85 initialized_ = true;
86 return initialized_;
87}
88
89bool SystemProfileCache::InitializeOrCheck() {
90 return initialized_ || Initialize();
91}
92
93void SystemProfileCache::Populate(
94 metrics::ChromeUserMetricsExtension* metrics_proto) {
95 CHECK(metrics_proto);
96 CHECK(InitializeOrCheck())
97 << "failed to initialize system information.";
98
99 // The client id is hashed before being sent.
100 metrics_proto->set_client_id(
101 metrics::MetricsLogBase::Hash(profile_.client_id));
102 metrics_proto->set_session_id(profile_.session_id);
103
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -0700104 // Sets the product id.
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700105 metrics_proto->set_product(9);
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -0700106
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700107 metrics::SystemProfileProto* profile_proto =
108 metrics_proto->mutable_system_profile();
109 profile_proto->mutable_hardware()->set_hardware_class(
110 profile_.hardware_class);
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700111 profile_proto->set_app_version(profile_.version);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700112 profile_proto->set_channel(profile_.channel);
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700113 metrics::SystemProfileProto_BrilloDeviceData* device_data =
114 profile_proto->mutable_brillo();
115 device_data->set_build_target_id(profile_.build_target_id);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700116}
117
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700118std::string SystemProfileCache::GetPersistentGUID(
119 const std::string& filename) {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700120 std::string guid;
121 base::FilePath filepath(filename);
122 if (!base::ReadFileToString(filepath, &guid)) {
123 guid = base::GenerateGUID();
124 // If we can't read or write the file, the guid will not be preserved during
125 // the next reboot. Crash.
126 CHECK(base::WriteFile(filepath, guid.c_str(), guid.size()));
127 }
128 return guid;
129}
130
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700131metrics::SystemProfileProto_Channel SystemProfileCache::ProtoChannelFromString(
132 const std::string& channel) {
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700133 if (channel == "stable") {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700134 return metrics::SystemProfileProto::CHANNEL_STABLE;
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700135 } else if (channel == "dev") {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700136 return metrics::SystemProfileProto::CHANNEL_DEV;
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700137 } else if (channel == "beta") {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700138 return metrics::SystemProfileProto::CHANNEL_BETA;
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700139 } else if (channel == "canary") {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700140 return metrics::SystemProfileProto::CHANNEL_CANARY;
141 }
142
143 DLOG(INFO) << "unknown channel: " << channel;
144 return metrics::SystemProfileProto::CHANNEL_UNKNOWN;
145}