1 // Copyright 2014 The Chromium 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 
5 #include "chrome/browser/metrics/google_update_metrics_provider_win.h"
6 
7 #include "base/location.h"
8 #include "base/metrics/histogram_functions.h"
9 #include "base/metrics/metrics_hashes.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/task/post_task.h"
13 #include "base/task/thread_pool.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "build/branding_buildflags.h"
16 #include "chrome/install_static/install_details.h"
17 #include "third_party/metrics_proto/system_profile.pb.h"
18 
19 typedef metrics::SystemProfileProto::GoogleUpdate::ProductInfo ProductInfo;
20 
21 namespace {
22 
23 // Helper function for checking if this is an official build. Used instead of
24 // the macro to allow checking for successful code compilation on non-official
25 // builds.
IsGoogleChromeBuild()26 bool IsGoogleChromeBuild() {
27 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
28   return true;
29 #else
30   return false;
31 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
32 }
33 
ProductDataToProto(const GoogleUpdateSettings::ProductData & product_data,ProductInfo * product_info)34 void ProductDataToProto(const GoogleUpdateSettings::ProductData& product_data,
35                         ProductInfo* product_info) {
36   product_info->set_version(product_data.version);
37   product_info->set_last_update_success_timestamp(
38       product_data.last_success.ToTimeT());
39   product_info->set_last_error(product_data.last_error_code);
40   product_info->set_last_extra_error(product_data.last_extra_code);
41   if (ProductInfo::InstallResult_IsValid(product_data.last_result)) {
42     product_info->set_last_result(
43         static_cast<ProductInfo::InstallResult>(product_data.last_result));
44   }
45 }
46 
47 }  // namespace
48 
GoogleUpdateMetricsProviderWin()49 GoogleUpdateMetricsProviderWin::GoogleUpdateMetricsProviderWin() {}
50 
~GoogleUpdateMetricsProviderWin()51 GoogleUpdateMetricsProviderWin::~GoogleUpdateMetricsProviderWin() {
52 }
53 
AsyncInit(base::OnceClosure done_callback)54 void GoogleUpdateMetricsProviderWin::AsyncInit(
55     base::OnceClosure done_callback) {
56   if (!IsGoogleChromeBuild()) {
57     base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
58                                                   std::move(done_callback));
59     return;
60   }
61 
62   // Schedules a task on a blocking pool thread to gather Google Update
63   // statistics (requires Registry reads).
64   base::ThreadPool::PostTaskAndReplyWithResult(
65       FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
66       base::BindOnce(
67           &GoogleUpdateMetricsProviderWin::GetGoogleUpdateDataBlocking),
68       base::BindOnce(&GoogleUpdateMetricsProviderWin::ReceiveGoogleUpdateData,
69                      weak_ptr_factory_.GetWeakPtr(), std::move(done_callback)));
70 }
71 
ProvideSystemProfileMetrics(metrics::SystemProfileProto * system_profile_proto)72 void GoogleUpdateMetricsProviderWin::ProvideSystemProfileMetrics(
73     metrics::SystemProfileProto* system_profile_proto) {
74   // Do nothing for chromium builds.
75   if (!IsGoogleChromeBuild())
76     return;
77   // Convert wstring to string.
78   std::string update_cohort_name = base::WideToUTF8(
79       install_static::InstallDetails::Get().update_cohort_name());
80   // TODO(nikunjb): Once update_cohort_name is added to system profile
81   // update the code here.
82   base::UmaHistogramSparse("GoogleUpdate.InstallDetails.UpdateCohort",
83                            base::HashMetricName(update_cohort_name));
84   metrics::SystemProfileProto::GoogleUpdate* google_update =
85       system_profile_proto->mutable_google_update();
86 
87   google_update->set_is_system_install(
88       google_update_metrics_.is_system_install);
89 
90   if (!google_update_metrics_.last_started_automatic_update_check.is_null()) {
91     google_update->set_last_automatic_start_timestamp(
92         google_update_metrics_.last_started_automatic_update_check.ToTimeT());
93   }
94 
95   if (!google_update_metrics_.last_checked.is_null()) {
96     google_update->set_last_update_check_timestamp(
97         google_update_metrics_.last_checked.ToTimeT());
98   }
99 
100   if (!google_update_metrics_.google_update_data.version.empty()) {
101     ProductDataToProto(google_update_metrics_.google_update_data,
102                        google_update->mutable_google_update_status());
103   }
104 
105   if (!google_update_metrics_.product_data.version.empty()) {
106     ProductDataToProto(google_update_metrics_.product_data,
107                        google_update->mutable_client_status());
108   }
109 }
110 
GoogleUpdateMetrics()111 GoogleUpdateMetricsProviderWin::GoogleUpdateMetrics::GoogleUpdateMetrics()
112     : is_system_install(false) {
113 }
114 
~GoogleUpdateMetrics()115 GoogleUpdateMetricsProviderWin::GoogleUpdateMetrics::~GoogleUpdateMetrics() {
116 }
117 
118 // static
119 GoogleUpdateMetricsProviderWin::GoogleUpdateMetrics
GetGoogleUpdateDataBlocking()120 GoogleUpdateMetricsProviderWin::GetGoogleUpdateDataBlocking() {
121   GoogleUpdateMetrics google_update_metrics;
122 
123   if (!IsGoogleChromeBuild())
124     return google_update_metrics;
125 
126   const bool is_system_install = GoogleUpdateSettings::IsSystemInstall();
127   google_update_metrics.is_system_install = is_system_install;
128   google_update_metrics.last_started_automatic_update_check =
129       GoogleUpdateSettings::GetGoogleUpdateLastStartedAU(is_system_install);
130   google_update_metrics.last_checked =
131       GoogleUpdateSettings::GetGoogleUpdateLastChecked(is_system_install);
132   GoogleUpdateSettings::GetUpdateDetailForGoogleUpdate(
133       &google_update_metrics.google_update_data);
134   GoogleUpdateSettings::GetUpdateDetail(&google_update_metrics.product_data);
135   return google_update_metrics;
136 }
137 
ReceiveGoogleUpdateData(base::OnceClosure done_callback,const GoogleUpdateMetrics & google_update_metrics)138 void GoogleUpdateMetricsProviderWin::ReceiveGoogleUpdateData(
139     base::OnceClosure done_callback,
140     const GoogleUpdateMetrics& google_update_metrics) {
141   google_update_metrics_ = google_update_metrics;
142   std::move(done_callback).Run();
143 }
144