Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
|
Alexei Svitkine (slow)
2016/03/29 16:29:10
2016
gayane -on leave until 09-2017
2016/03/31 01:38:24
Done.
| |
| 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 #include "content/public/browser/browser_thread.h" | |
| 15 | |
| 16 namespace metrics { | |
| 17 | |
| 18 namespace { | |
| 19 static scoped_ptr<metrics::DataUseTracker> instance_; | |
|
Alexei Svitkine (slow)
2016/03/29 16:29:10
This is not needed anymore, right?
gayane -on leave until 09-2017
2016/03/31 01:38:24
Done.
| |
| 20 } | |
| 21 | |
| 22 // static | |
| 23 void DataUseTracker::GetForwardingCallback( | |
| 24 base::WeakPtr<DataUseTracker> data_use_tracker, | |
| 25 base::Callback<void(base::Callback<void(const std::string&, int)>)> | |
| 26 reply_callback) { | |
| 27 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 28 content::BrowserThread::PostTaskAndReplyWithResult( | |
| 29 content::BrowserThread::UI, FROM_HERE, | |
| 30 base::Bind(&DataUseTracker::GetForwardingCallbackOnUIThread, | |
| 31 data_use_tracker), | |
| 32 reply_callback); | |
| 33 } | |
| 34 | |
| 35 // static | |
| 36 base::Callback<void(const std::string&, int)> | |
| 37 DataUseTracker::GetForwardingCallbackOnUIThread( | |
| 38 base::WeakPtr<DataUseTracker> data_use_tracker) { | |
| 39 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 40 return base::Bind(&DataUseTracker::UpdateMetricsUsagePrefsOnUIThread, | |
| 41 data_use_tracker); | |
| 42 } | |
| 43 | |
| 44 void DataUseTracker::RunOnUI( | |
| 45 base::Callback<void(const std::string&, int)> callback, | |
| 46 const std::string& service_name, | |
| 47 int message_size) { | |
| 48 content::BrowserThread::PostTask( | |
| 49 content::BrowserThread::UI, FROM_HERE, | |
| 50 base::Bind(callback, service_name, message_size)); | |
| 51 } | |
| 52 | |
| 53 // static | |
| 54 void DataUseTracker::RegisterPrefs(PrefRegistrySimple* registry) { | |
| 55 registry->RegisterDictionaryPref(metrics::prefs::kUserCellDataUse); | |
| 56 registry->RegisterDictionaryPref(metrics::prefs::kUmaCellDataUse); | |
| 57 } | |
| 58 | |
| 59 DataUseTracker::DataUseTracker(PrefService* local_state) | |
| 60 : local_state_(local_state), | |
| 61 uma_qouta_for_testing_(0), | |
| 62 uma_ratio_for_testing_(0), | |
| 63 weak_ptr_factory_(this) {} | |
| 64 | |
| 65 DataUseTracker::~DataUseTracker() {} | |
| 66 | |
| 67 std::string DataUseTracker::GetCurrentMeasurementDate() { | |
| 68 if (!date_for_testing_.empty()) | |
| 69 return date_for_testing_; | |
| 70 | |
| 71 base::Time::Exploded today_exploded; | |
| 72 base::Time::Now().LocalMidnight().LocalExplode(&today_exploded); | |
| 73 return base::StringPrintf("%04d-%02d-%02d", today_exploded.year, | |
| 74 today_exploded.month, today_exploded.day_of_month); | |
| 75 } | |
| 76 | |
| 77 void DataUseTracker::UpdateMetricsUsagePrefsOnUIThread( | |
| 78 const std::string& service_name, | |
| 79 int message_size) { | |
| 80 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 81 UpdateUsagePref(prefs::kUserCellDataUse, message_size); | |
| 82 if (service_name == "UMA") | |
| 83 UpdateUsagePref(prefs::kUmaCellDataUse, message_size); | |
| 84 } | |
| 85 | |
| 86 void DataUseTracker::RemoveExpiredEntries() { | |
| 87 RemoveExpiredEntriesForPref(prefs::kUmaCellDataUse); | |
| 88 RemoveExpiredEntriesForPref(prefs::kUserCellDataUse); | |
| 89 } | |
| 90 | |
| 91 void DataUseTracker::RemoveExpiredEntriesForPref(const std::string& pref_name) { | |
| 92 const base::DictionaryValue* user_pref_dict = | |
| 93 local_state_->GetDictionary(pref_name); | |
| 94 if (!user_pref_dict) | |
| 95 return; | |
| 96 base::DictionaryValue user_pref_new_dict; | |
| 97 for (base::DictionaryValue::Iterator it(*user_pref_dict); !it.IsAtEnd(); | |
| 98 it.Advance()) { | |
| 99 base::Time start_of_week = | |
| 100 base::Time::Now().LocalMidnight() - base::TimeDelta::FromDays(7); | |
| 101 base::Time key_date; | |
| 102 base::Time::FromString(it.key().c_str(), &key_date); | |
| 103 if (key_date >= start_of_week) { | |
| 104 user_pref_new_dict.Set(it.key(), it.value().CreateDeepCopy()); | |
| 105 } | |
| 106 } | |
| 107 local_state_->Set(pref_name, user_pref_new_dict); | |
| 108 } | |
| 109 | |
| 110 void DataUseTracker::UpdateUsagePref(const std::string& pref_name, | |
| 111 int message_size) { | |
| 112 DictionaryPrefUpdate pref_updater(local_state_, pref_name); | |
| 113 int todays_traffic = 0; | |
| 114 std::string todays_key = GetCurrentMeasurementDate(); | |
| 115 local_state_->GetDictionary(pref_name)->GetInteger(todays_key, | |
| 116 &todays_traffic); | |
| 117 pref_updater->SetInteger(todays_key, todays_traffic + message_size); | |
| 118 } | |
| 119 | |
| 120 bool DataUseTracker::CanUploadUMALog(int log_bytes) { | |
| 121 RemoveExpiredEntries(); | |
| 122 int uma_total_data_use = ComputeTotalDataUse(prefs::kUmaCellDataUse); | |
| 123 int uma_qouta; | |
| 124 bool is_qouta_specified = GetUmaQouta(&uma_qouta); | |
| 125 if (!is_qouta_specified || log_bytes + uma_total_data_use <= uma_qouta) | |
| 126 return true; | |
| 127 | |
| 128 double uma_ratio; | |
| 129 bool is_ratio_specified = GetUmaRatio(&uma_ratio); | |
| 130 if (!is_ratio_specified) | |
| 131 return true; | |
| 132 | |
| 133 int user_total_data_use = ComputeTotalDataUse(prefs::kUserCellDataUse); | |
| 134 return (log_bytes + uma_total_data_use) / | |
| 135 (double)(log_bytes + user_total_data_use) <= | |
| 136 uma_ratio; | |
| 137 } | |
| 138 | |
| 139 int DataUseTracker::ComputeTotalDataUse(std::string pref_name) { | |
| 140 int total_data_use = 0; | |
| 141 const base::DictionaryValue* pref_dict = | |
| 142 local_state_->GetDictionary(pref_name); | |
| 143 if (!pref_dict) | |
| 144 return total_data_use; | |
| 145 for (base::DictionaryValue::Iterator it(*pref_dict); !it.IsAtEnd(); | |
| 146 it.Advance()) { | |
| 147 int value = 0; | |
| 148 it.value().GetAsInteger(&value); | |
| 149 total_data_use += value; | |
| 150 } | |
| 151 return total_data_use; | |
| 152 } | |
| 153 | |
| 154 bool DataUseTracker::GetUmaQouta(int* qouta) { | |
| 155 if (uma_qouta_for_testing_ > 0) { | |
| 156 *qouta = uma_qouta_for_testing_; | |
| 157 return true; | |
| 158 } | |
| 159 | |
| 160 std::string param_value_str = variations::GetVariationParamValue( | |
| 161 "UMA_EnableCellularLogUpload", "Uma_Qouta"); | |
| 162 if (param_value_str.empty()) | |
| 163 return false; | |
| 164 | |
| 165 base::StringToInt(param_value_str, qouta); | |
| 166 return true; | |
| 167 } | |
| 168 | |
| 169 bool DataUseTracker::GetUmaRatio(double* ratio) { | |
| 170 if (uma_ratio_for_testing_ > 0) { | |
| 171 *ratio = uma_ratio_for_testing_; | |
| 172 return true; | |
| 173 } | |
| 174 | |
| 175 std::string param_value_str = variations::GetVariationParamValue( | |
| 176 "UMA_EnableCellularLogUpload", "Uma_Ratio"); | |
| 177 if (param_value_str.empty()) | |
| 178 return false; | |
| 179 base::StringToDouble(param_value_str, ratio); | |
| 180 return true; | |
| 181 } | |
| 182 | |
| 183 void DataUseTracker::SetMeasurementDateForTesting(const std::string& date) { | |
| 184 date_for_testing_ = date; | |
| 185 } | |
| 186 | |
| 187 void DataUseTracker::SetUmaQoutaForTesting(int uma_qouta) { | |
| 188 uma_qouta_for_testing_ = uma_qouta; | |
| 189 } | |
| 190 | |
| 191 void DataUseTracker::SetUmaRatioForTesting(double uma_ratio) { | |
| 192 uma_ratio_for_testing_ = uma_ratio; | |
| 193 } | |
| 194 | |
| 195 base::WeakPtr<DataUseTracker> DataUseTracker::GetWeakPtr() { | |
| 196 return weak_ptr_factory_.GetWeakPtr(); | |
| 197 } | |
| 198 | |
| 199 } // namespace metrics | |
| OLD | NEW |