metrics: generate app_version from standard lsb-release fields
app_version used to be set to CHROMEOS_RELEASE_DESCRIPTION which has no
structure and should never be used for parsing.
Now that various version numbers have been added to lsb-release, use those
fields to generate the version string.
The version string format is "A.B.C.D (Official Build) $CHANNEL $BOARD" with:
* A = chrome milestone
* B = build number
* C = branch number
* D = patch number
* CHANNEL is one of STABLE, DEV, BETA, CANARY
* BOARD is the board name
BUG=chromium:426889
TEST=trybot run on gizmo-paladin
TEST=`test_that -b gizmo gizmo platform_MetricsUploader`
TEST=`FEATURES=test emerge-gizmo metrics`
Change-Id: I624df14bd859e0c0279dd3de621e651150d30add
Reviewed-on: https://chromium-review.googlesource.com/236949
Tested-by: Bertrand Simonnet <bsimonnet@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Bertrand Simonnet <bsimonnet@chromium.org>
Trybot-Ready: Bertrand Simonnet <bsimonnet@chromium.org>
diff --git a/metrics/uploader/system_profile_cache.cc b/metrics/uploader/system_profile_cache.cc
index 54c2693..28e0f09 100644
--- a/metrics/uploader/system_profile_cache.cc
+++ b/metrics/uploader/system_profile_cache.cc
@@ -12,6 +12,7 @@
#include "base/guid.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
#include "base/sys_info.h"
#include "components/metrics/proto/chrome_user_metrics_extension.pb.h"
#include "metrics/persistent_integer.h"
@@ -26,6 +27,21 @@
} // namespace
+std::string ChannelToString(
+ const metrics::SystemProfileProto_Channel& channel) {
+ switch (channel) {
+ case metrics::SystemProfileProto::CHANNEL_STABLE:
+ return "STABLE";
+ case metrics::SystemProfileProto::CHANNEL_DEV:
+ return "DEV";
+ case metrics::SystemProfileProto::CHANNEL_BETA:
+ return "BETA";
+ case metrics::SystemProfileProto::CHANNEL_CANARY:
+ return "CANARY";
+ default:
+ return "UNKNOWN";
+ }
+}
SystemProfileCache::SystemProfileCache()
: initialized_(false),
@@ -48,12 +64,17 @@
CHECK(!initialized_)
<< "this should be called only once in the metrics_daemon lifetime.";
+ std::string chromeos_version;
+ std::string board;
+ std::string build_type;
if (!base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_NAME",
&profile_.os_name) ||
!base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_VERSION",
&profile_.os_version) ||
- !base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_DESCRIPTION",
- &profile_.app_version) ||
+ !base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BOARD", &board) ||
+ !base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BUILD_TYPE",
+ &build_type) ||
+ !GetChromeOSVersion(&chromeos_version) ||
!GetHardwareId(&profile_.hardware_class)) {
DLOG(ERROR) << "failing to initialize profile cache";
return false;
@@ -63,6 +84,9 @@
base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_TRACK", &channel_string);
profile_.channel = ProtoChannelFromString(channel_string);
+ profile_.app_version = chromeos_version + " (" + build_type + ")" +
+ ChannelToString(profile_.channel) + " " + board;
+
// If the product id is not defined, use the default one from the protobuf.
profile_.product_id = metrics::ChromeUserMetricsExtension::CHROME;
if (GetProductId(&profile_.product_id)) {
@@ -126,6 +150,39 @@
return guid;
}
+bool SystemProfileCache::GetChromeOSVersion(std::string* version) {
+ if (testing_) {
+ *version = "0.0.0.0";
+ return true;
+ }
+
+ std::string milestone, build, branch, patch;
+ unsigned tmp;
+ if (base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_CHROME_MILESTONE",
+ &milestone) &&
+ base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BUILD_NUMBER",
+ &build) &&
+ base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_BRANCH_NUMBER",
+ &branch) &&
+ base::SysInfo::GetLsbReleaseValue("CHROMEOS_RELEASE_PATCH_NUMBER",
+ &patch)) {
+ // Convert to uint to ensure those fields are positive numbers.
+ if (base::StringToUint(milestone, &tmp) &&
+ base::StringToUint(build, &tmp) &&
+ base::StringToUint(branch, &tmp) &&
+ base::StringToUint(patch, &tmp)) {
+ std::vector<std::string> parts = {milestone, build, branch, patch};
+ *version = JoinString(parts, '.');
+ return true;
+ }
+ DLOG(INFO) << "The milestone, build, branch or patch is not a positive "
+ << "number.";
+ return false;
+ }
+ DLOG(INFO) << "Field missing from /etc/lsb-release";
+ return false;
+}
+
bool SystemProfileCache::GetHardwareId(std::string* hwid) {
CHECK(hwid);
diff --git a/metrics/uploader/system_profile_cache.h b/metrics/uploader/system_profile_cache.h
index 95f554f..bbfc90d 100644
--- a/metrics/uploader/system_profile_cache.h
+++ b/metrics/uploader/system_profile_cache.h
@@ -72,6 +72,15 @@
// Gets the product ID from the GOOGLE_METRICS_PRODUCT_ID field.
bool GetProductId(int* product_id) const;
+ // Generate the formatted chromeos version from the fields in
+ // /etc/lsb-release. The format is A.B.C.D where A, B, C and D are positive
+ // integer representing:
+ // * the chrome milestone
+ // * the build number
+ // * the branch number
+ // * the patch number
+ bool GetChromeOSVersion(std::string* version);
+
bool initialized_;
bool testing_;
std::string config_root_;
diff --git a/metrics/uploader/upload_service_test.cc b/metrics/uploader/upload_service_test.cc
index ff96f85..363c8c1 100644
--- a/metrics/uploader/upload_service_test.cc
+++ b/metrics/uploader/upload_service_test.cc
@@ -189,7 +189,9 @@
"CHROMEOS_RELEASE_NAME=" + name +
"\nCHROMEOS_RELEASE_VERSION=version\n"
"CHROMEOS_RELEASE_DESCRIPTION=description beta-channel test\n"
- "CHROMEOS_RELEASE_TRACK=beta-channel");
+ "CHROMEOS_RELEASE_TRACK=beta-channel\n"
+ "CHROMEOS_RELEASE_BUILD_TYPE=developer build\n"
+ "CHROMEOS_RELEASE_BOARD=myboard");
base::SysInfo::SetChromeOSVersionInfoForTest(content, base::Time());
scoped_ptr<metrics::MetricSample> histogram =