blob: 35910d7ddce8a42c1e4ebdc7a937fcdf893b54fe [file] [log] [blame]
Bertrand SIMONNET52e5b992015-08-10 15:18:00 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070016
Bertrand SIMONNET4b915ae2015-07-28 15:38:14 -070017#include "uploader/system_profile_cache.h"
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070018
Bertrand SIMONNETbd3505e2015-08-04 14:04:51 -070019#include <base/files/file_util.h>
20#include <base/guid.h>
21#include <base/logging.h>
22#include <base/strings/string_number_conversions.h>
23#include <base/strings/string_util.h>
24#include <base/sys_info.h>
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070025#include <string>
26#include <vector>
27
Bertrand SIMONNETbd3505e2015-08-04 14:04:51 -070028#include "constants.h"
Bertrand SIMONNET4b915ae2015-07-28 15:38:14 -070029#include "persistent_integer.h"
30#include "uploader/metrics_log_base.h"
31#include "uploader/proto/chrome_user_metrics_extension.pb.h"
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070032
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070033namespace {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070034
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070035const char kPersistentSessionIdFilename[] = "Sysinfo.SessionId";
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070036
37} // namespace
38
Bertrand SIMONNETa8bcc182014-12-19 09:35:15 -080039std::string ChannelToString(
40 const metrics::SystemProfileProto_Channel& channel) {
41 switch (channel) {
42 case metrics::SystemProfileProto::CHANNEL_STABLE:
43 return "STABLE";
44 case metrics::SystemProfileProto::CHANNEL_DEV:
45 return "DEV";
46 case metrics::SystemProfileProto::CHANNEL_BETA:
47 return "BETA";
48 case metrics::SystemProfileProto::CHANNEL_CANARY:
49 return "CANARY";
50 default:
51 return "UNKNOWN";
52 }
53}
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070054
55SystemProfileCache::SystemProfileCache()
56 : initialized_(false),
57 testing_(false),
58 config_root_("/"),
59 session_id_(new chromeos_metrics::PersistentInteger(
60 kPersistentSessionIdFilename)) {
61}
62
63SystemProfileCache::SystemProfileCache(bool testing,
64 const std::string& config_root)
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070065 : initialized_(false),
Bertrand SIMONNETeb815be2014-09-11 07:38:17 -070066 testing_(testing),
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -070067 config_root_(config_root),
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070068 session_id_(new chromeos_metrics::PersistentInteger(
69 kPersistentSessionIdFilename)) {
70}
71
72bool SystemProfileCache::Initialize() {
73 CHECK(!initialized_)
74 << "this should be called only once in the metrics_daemon lifetime.";
75
Bertrand SIMONNETbae5dcc2015-08-04 14:12:10 -070076 if (!base::SysInfo::GetLsbReleaseValue("BRILLO_BUILD_TARGET_ID",
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -070077 &profile_.build_target_id)) {
78 LOG(ERROR) << "Could not initialize system profile.";
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070079 return false;
80 }
81
Bertrand SIMONNETbae5dcc2015-08-04 14:12:10 -070082 std::string channel;
83 if (!base::SysInfo::GetLsbReleaseValue("BRILLO_CHANNEL", &channel) ||
84 !base::SysInfo::GetLsbReleaseValue("BRILLO_VERSION", &profile_.version)) {
85 // If the channel or version is missing, the image is not official.
86 // In this case, set the channel to unknown and the version to 0.0.0.0 to
87 // avoid polluting the production data.
88 channel = "";
89 profile_.version = metrics::kDefaultVersion;
90
91 }
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070092 profile_.client_id =
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -070093 testing_ ? "client_id_test" :
94 GetPersistentGUID(metrics::kMetricsGUIDFilePath);
95 profile_.hardware_class = "unknown";
96 profile_.channel = ProtoChannelFromString(channel);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070097
98 // Increment the session_id everytime we initialize this. If metrics_daemon
99 // does not crash, this should correspond to the number of reboots of the
100 // system.
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700101 session_id_->Add(1);
Ben Chanf05ab402014-08-07 00:54:59 -0700102 profile_.session_id = static_cast<int32_t>(session_id_->Get());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700103
104 initialized_ = true;
105 return initialized_;
106}
107
108bool SystemProfileCache::InitializeOrCheck() {
109 return initialized_ || Initialize();
110}
111
112void SystemProfileCache::Populate(
113 metrics::ChromeUserMetricsExtension* metrics_proto) {
114 CHECK(metrics_proto);
115 CHECK(InitializeOrCheck())
116 << "failed to initialize system information.";
117
118 // The client id is hashed before being sent.
119 metrics_proto->set_client_id(
120 metrics::MetricsLogBase::Hash(profile_.client_id));
121 metrics_proto->set_session_id(profile_.session_id);
122
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -0700123 // Sets the product id.
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700124 metrics_proto->set_product(9);
Bertrand SIMONNET71a62ef2014-10-07 11:26:25 -0700125
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700126 metrics::SystemProfileProto* profile_proto =
127 metrics_proto->mutable_system_profile();
128 profile_proto->mutable_hardware()->set_hardware_class(
129 profile_.hardware_class);
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700130 profile_proto->set_app_version(profile_.version);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700131 profile_proto->set_channel(profile_.channel);
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700132 metrics::SystemProfileProto_BrilloDeviceData* device_data =
133 profile_proto->mutable_brillo();
134 device_data->set_build_target_id(profile_.build_target_id);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700135}
136
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700137std::string SystemProfileCache::GetPersistentGUID(
138 const std::string& filename) {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700139 std::string guid;
140 base::FilePath filepath(filename);
141 if (!base::ReadFileToString(filepath, &guid)) {
142 guid = base::GenerateGUID();
143 // If we can't read or write the file, the guid will not be preserved during
144 // the next reboot. Crash.
145 CHECK(base::WriteFile(filepath, guid.c_str(), guid.size()));
146 }
147 return guid;
148}
149
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700150metrics::SystemProfileProto_Channel SystemProfileCache::ProtoChannelFromString(
151 const std::string& channel) {
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700152 if (channel == "stable") {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700153 return metrics::SystemProfileProto::CHANNEL_STABLE;
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700154 } else if (channel == "dev") {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700155 return metrics::SystemProfileProto::CHANNEL_DEV;
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700156 } else if (channel == "beta") {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700157 return metrics::SystemProfileProto::CHANNEL_BETA;
Bertrand SIMONNET52e1d552015-08-04 15:06:21 -0700158 } else if (channel == "canary") {
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700159 return metrics::SystemProfileProto::CHANNEL_CANARY;
160 }
161
162 DLOG(INFO) << "unknown channel: " << channel;
163 return metrics::SystemProfileProto::CHANNEL_UNKNOWN;
164}