OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 "components/metrics/data_use_tracker.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/strings/string_number_conversions.h" | |
10 #include "base/strings/stringprintf.h" | |
11 #include "components/metrics/metrics_pref_names.h" | |
12 #include "components/prefs/scoped_user_pref_update.h" | |
13 #include "components/variations/variations_associated_data.h" | |
14 | |
15 namespace metrics { | |
16 | |
17 namespace { | |
18 | |
19 // This function is for forwarding metrics usage pref changes to the appropriate | |
20 // callback on the appropriate thread. | |
21 void UpdateMetricsUsagePrefs( | |
22 const UpdateUsagePrefCallbackType& update_on_ui_callback, | |
23 scoped_refptr<base::SequencedTaskRunner> ui_task_runner, | |
24 const std::string& service_name, | |
25 int message_size) { | |
26 ui_task_runner->PostTask( | |
27 FROM_HERE, base::Bind(update_on_ui_callback, service_name, message_size)); | |
28 } | |
29 | |
30 } // namespace | |
31 | |
32 DataUseTracker::DataUseTracker(PrefService* local_state) | |
33 : local_state_(local_state), | |
34 weak_ptr_factory_(this) {} | |
35 | |
36 DataUseTracker::~DataUseTracker() {} | |
37 | |
38 // static | |
39 void DataUseTracker::RegisterPrefs(PrefRegistrySimple* registry) { | |
40 registry->RegisterDictionaryPref(metrics::prefs::kUserCellDataUse); | |
41 registry->RegisterDictionaryPref(metrics::prefs::kUmaCellDataUse); | |
42 } | |
43 | |
44 UpdateUsagePrefCallbackType DataUseTracker::GetDataUseForwardingCallback( | |
45 scoped_refptr<base::SequencedTaskRunner> ui_task_runner) { | |
46 DCHECK(ui_task_runner->RunsTasksOnCurrentThread()); | |
47 | |
48 return base::Bind( | |
49 &UpdateMetricsUsagePrefs, | |
50 base::Bind(&DataUseTracker::UpdateMetricsUsagePrefsOnUIThread, | |
51 weak_ptr_factory_.GetWeakPtr()), | |
52 ui_task_runner); | |
53 } | |
54 | |
55 bool DataUseTracker::ShouldUploadLogOnCellular(int log_bytes) { | |
56 DCHECK(thread_checker_.CalledOnValidThread()); | |
57 | |
58 RemoveExpiredEntries(); | |
59 | |
60 int uma_weekly_quota_bytes; | |
61 if (!GetUmaWeeaklyQuota(&uma_weekly_quota_bytes)) | |
62 return true; | |
63 | |
64 int uma_total_data_use = ComputeTotalDataUse(prefs::kUmaCellDataUse); | |
65 int new_uma_total_data_use = log_bytes + uma_total_data_use; | |
66 // If the new log doesn't increase the total UMA traffic to be above the | |
67 // allowed quota then the log should be uploaded. | |
68 if (new_uma_total_data_use <= uma_weekly_quota_bytes) | |
69 return true; | |
70 | |
71 double uma_ratio; | |
72 if (!GetUmaRatio(&uma_ratio)) | |
73 return true; | |
74 | |
75 int user_total_data_use = ComputeTotalDataUse(prefs::kUserCellDataUse); | |
76 // If after adding the new log the uma ratio is still under the allowed ratio | |
77 // then the log should be uploaded and vice versa. | |
78 return new_uma_total_data_use / | |
79 static_cast<double>(log_bytes + user_total_data_use) <= | |
80 uma_ratio; | |
81 } | |
82 | |
83 void DataUseTracker::UpdateMetricsUsagePrefsOnUIThread( | |
84 const std::string& service_name, | |
85 int message_size) { | |
86 DCHECK(thread_checker_.CalledOnValidThread()); | |
87 | |
88 UpdateUsagePref(prefs::kUserCellDataUse, message_size); | |
89 if (service_name == "UMA") | |
90 UpdateUsagePref(prefs::kUmaCellDataUse, message_size); | |
mmenke
2016/04/04 17:26:23
Recording UMA and non-UMA data use through a metho
gayane -on leave until 09-2017
2016/04/05 14:26:46
For now we would like to manage to get to M51 whic
mmenke
2016/04/05 20:18:32
Not going to block on this, but my general feeling
| |
91 } | |
92 | |
93 void DataUseTracker::UpdateUsagePref(const std::string& pref_name, | |
94 int message_size) { | |
mmenke
2016/04/04 17:26:23
All this does is write to a pref from another thre
gayane -on leave until 09-2017
2016/04/05 14:26:46
For using PrefMember we can have pass PrefMember o
mmenke
2016/04/05 20:18:32
Could DataUseTracker::GetDataUseForwardingCallback
| |
95 DCHECK(thread_checker_.CalledOnValidThread()); | |
96 | |
97 DictionaryPrefUpdate pref_updater(local_state_, pref_name); | |
98 int todays_traffic = 0; | |
99 std::string todays_key = GetCurrentMeasurementDateAsString(); | |
100 | |
101 const base::DictionaryValue* user_pref_dict = | |
102 local_state_->GetDictionary(pref_name); | |
103 user_pref_dict->GetInteger(todays_key, &todays_traffic); | |
104 pref_updater->SetInteger(todays_key, todays_traffic + message_size); | |
105 } | |
106 | |
107 void DataUseTracker::RemoveExpiredEntries() { | |
108 DCHECK(thread_checker_.CalledOnValidThread()); | |
109 RemoveExpiredEntriesForPref(prefs::kUmaCellDataUse); | |
110 RemoveExpiredEntriesForPref(prefs::kUserCellDataUse); | |
111 } | |
112 | |
113 void DataUseTracker::RemoveExpiredEntriesForPref(const std::string& pref_name) { | |
114 DCHECK(thread_checker_.CalledOnValidThread()); | |
115 | |
116 const base::DictionaryValue* user_pref_dict = | |
117 local_state_->GetDictionary(pref_name); | |
118 const base::Time current_date = GetCurrentMeasurementDate(); | |
119 const base::Time week_ago = current_date - base::TimeDelta::FromDays(7); | |
120 | |
121 base::DictionaryValue user_pref_new_dict; | |
122 for (base::DictionaryValue::Iterator it(*user_pref_dict); !it.IsAtEnd(); | |
123 it.Advance()) { | |
124 base::Time key_date; | |
125 base::Time::FromUTCString(it.key().c_str(), &key_date); | |
126 if (key_date > week_ago) | |
127 user_pref_new_dict.Set(it.key(), it.value().CreateDeepCopy()); | |
128 } | |
129 local_state_->Set(pref_name, user_pref_new_dict); | |
mmenke
2016/04/04 17:26:23
DataReductionProxyCompressionStats has its own mag
gayane -on leave until 09-2017
2016/04/05 14:26:46
I had a quick look but It didn't seem to me simila
mmenke
2016/04/05 20:18:32
Right...which means things would have to move arou
| |
130 } | |
131 | |
132 int DataUseTracker::ComputeTotalDataUse(std::string pref_name) { | |
133 DCHECK(thread_checker_.CalledOnValidThread()); | |
134 | |
135 int total_data_use = 0; | |
136 const base::DictionaryValue* pref_dict = | |
137 local_state_->GetDictionary(pref_name); | |
138 for (base::DictionaryValue::Iterator it(*pref_dict); !it.IsAtEnd(); | |
139 it.Advance()) { | |
140 int value = 0; | |
141 it.value().GetAsInteger(&value); | |
142 total_data_use += value; | |
143 } | |
144 return total_data_use; | |
145 } | |
146 | |
147 bool DataUseTracker::GetUmaWeeaklyQuota(int* uma_weekly_quota_bytes) { | |
mmenke
2016/04/04 17:26:23
Weeakly -> Weekly
gayane -on leave until 09-2017
2016/04/05 14:26:46
Done.
| |
148 DCHECK(thread_checker_.CalledOnValidThread()); | |
149 | |
150 std::string param_value_str = variations::GetVariationParamValue( | |
151 "UMA_EnableCellularLogUpload", "Uma_Quota"); | |
152 if (param_value_str.empty()) | |
153 return false; | |
154 | |
155 base::StringToInt(param_value_str, uma_weekly_quota_bytes); | |
156 return true; | |
157 } | |
158 | |
159 bool DataUseTracker::GetUmaRatio(double* ratio) { | |
160 DCHECK(thread_checker_.CalledOnValidThread()); | |
161 | |
162 std::string param_value_str = variations::GetVariationParamValue( | |
163 "UMA_EnableCellularLogUpload", "Uma_Ratio"); | |
164 if (param_value_str.empty()) | |
165 return false; | |
166 base::StringToDouble(param_value_str, ratio); | |
167 return true; | |
168 } | |
169 | |
170 base::Time DataUseTracker::GetCurrentMeasurementDate() { | |
171 return base::Time::Now().LocalMidnight(); | |
172 } | |
173 | |
174 std::string DataUseTracker::GetCurrentMeasurementDateAsString() { | |
175 DCHECK(thread_checker_.CalledOnValidThread()); | |
176 | |
177 base::Time::Exploded today_exploded; | |
178 GetCurrentMeasurementDate().LocalExplode(&today_exploded); | |
179 return base::StringPrintf("%04d-%02d-%02d", today_exploded.year, | |
180 today_exploded.month, today_exploded.day_of_month); | |
181 } | |
182 | |
183 } // namespace metrics | |
OLD | NEW |