Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/data_use_measurement/content/data_use_measurement.h" | 5 #include "components/data_use_measurement/content/data_use_measurement.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "base/metrics/sparse_histogram.h" | 8 #include "base/metrics/sparse_histogram.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 40 // histogram by |value|. Conventional UMA histograms are not used because |name| | 40 // histogram by |value|. Conventional UMA histograms are not used because |name| |
| 41 // is not static. | 41 // is not static. |
| 42 void IncreaseSparseHistogramByValue(const std::string& name, | 42 void IncreaseSparseHistogramByValue(const std::string& name, |
| 43 int64_t sample, | 43 int64_t sample, |
| 44 int64_t value) { | 44 int64_t value) { |
| 45 base::HistogramBase* histogram = base::SparseHistogram::FactoryGet( | 45 base::HistogramBase* histogram = base::SparseHistogram::FactoryGet( |
| 46 name, base::HistogramBase::kUmaTargetedHistogramFlag); | 46 name, base::HistogramBase::kUmaTargetedHistogramFlag); |
| 47 histogram->AddCount(sample, value); | 47 histogram->AddCount(sample, value); |
| 48 } | 48 } |
| 49 | 49 |
| 50 void IncreaseTimeHistogramByValue(const std::string& name, | |
| 51 const base::TimeDelta& sample, | |
| 52 int64_t value) { | |
| 53 base::HistogramBase* histogram_pointer = base::Histogram::FactoryTimeGet( | |
| 54 name, | |
| 55 base::TimeDelta::FromMilliseconds(1), // Minimum sample | |
| 56 base::TimeDelta::FromHours(1), // Maximum sample | |
| 57 50, // Bucket count. | |
| 58 base::HistogramBase::kUmaTargetedHistogramFlag); | |
| 59 histogram_pointer->AddCount(sample.InMilliseconds(), value); | |
| 60 } | |
| 61 | |
| 50 } // namespace | 62 } // namespace |
| 51 | 63 |
| 52 DataUseMeasurement::DataUseMeasurement( | 64 DataUseMeasurement::DataUseMeasurement( |
| 53 const metrics::UpdateUsagePrefCallbackType& metrics_data_use_forwarder) | 65 const metrics::UpdateUsagePrefCallbackType& metrics_data_use_forwarder) |
| 54 : metrics_data_use_forwarder_(metrics_data_use_forwarder) | 66 : metrics_data_use_forwarder_(metrics_data_use_forwarder) |
| 55 #if defined(OS_ANDROID) | 67 #if defined(OS_ANDROID) |
| 56 , | 68 , |
| 57 app_state_(base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES), | 69 app_state_(base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES), |
| 58 app_listener_(new base::android::ApplicationStatusListener( | 70 app_listener_(new base::android::ApplicationStatusListener( |
| 59 base::Bind(&DataUseMeasurement::OnApplicationStateChange, | 71 base::Bind(&DataUseMeasurement::OnApplicationStateChange, |
| 60 base::Unretained(this)))), | 72 base::Unretained(this)))), |
| 61 rx_bytes_os_(0), | 73 rx_bytes_os_(0), |
| 62 tx_bytes_os_(0), | 74 tx_bytes_os_(0), |
| 63 bytes_transferred_since_last_traffic_stats_query_(0) | 75 bytes_transferred_since_last_traffic_stats_query_(0), |
| 76 first_read_after_background_(false) | |
| 64 #endif | 77 #endif |
| 65 { | 78 { |
| 66 } | 79 } |
| 67 | 80 |
| 68 DataUseMeasurement::~DataUseMeasurement(){}; | 81 DataUseMeasurement::~DataUseMeasurement(){}; |
| 69 | 82 |
| 70 void DataUseMeasurement::OnBeforeURLRequest(net::URLRequest* request) { | 83 void DataUseMeasurement::OnBeforeURLRequest(net::URLRequest* request) { |
| 71 DataUseUserData* data_use_user_data = reinterpret_cast<DataUseUserData*>( | 84 DataUseUserData* data_use_user_data = reinterpret_cast<DataUseUserData*>( |
| 72 request->GetUserData(DataUseUserData::kUserDataKey)); | 85 request->GetUserData(DataUseUserData::kUserDataKey)); |
| 73 if (!data_use_user_data) { | 86 if (!data_use_user_data) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 void DataUseMeasurement::OnCompleted(const net::URLRequest& request, | 118 void DataUseMeasurement::OnCompleted(const net::URLRequest& request, |
| 106 bool started) { | 119 bool started) { |
| 107 // TODO(amohammadkhan): Verify that there is no double recording in data use | 120 // TODO(amohammadkhan): Verify that there is no double recording in data use |
| 108 // of redirected requests. | 121 // of redirected requests. |
| 109 UpdateDataUsePrefs(request); | 122 UpdateDataUsePrefs(request); |
| 110 #if defined(OS_ANDROID) | 123 #if defined(OS_ANDROID) |
| 111 MaybeRecordNetworkBytesOS(); | 124 MaybeRecordNetworkBytesOS(); |
| 112 #endif | 125 #endif |
| 113 } | 126 } |
| 114 | 127 |
| 115 void DataUseMeasurement::ReportDataUseUMA( | 128 void DataUseMeasurement::ReportDataUseUMA(const net::URLRequest& request, |
| 116 const net::URLRequest& request, | 129 TrafficDirection dir, |
| 117 TrafficDirection dir, | 130 int64_t bytes) { |
| 118 int64_t bytes) const { | |
| 119 bool is_user_traffic = IsUserInitiatedRequest(request); | 131 bool is_user_traffic = IsUserInitiatedRequest(request); |
| 120 bool is_connection_cellular = | 132 bool is_connection_cellular = |
| 121 net::NetworkChangeNotifier::IsConnectionCellular( | 133 net::NetworkChangeNotifier::IsConnectionCellular( |
| 122 net::NetworkChangeNotifier::GetConnectionType()); | 134 net::NetworkChangeNotifier::GetConnectionType()); |
| 123 | 135 |
| 124 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( | 136 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( |
| 125 request.GetUserData(DataUseUserData::kUserDataKey)); | 137 request.GetUserData(DataUseUserData::kUserDataKey)); |
| 126 DataUseUserData::ServiceName service_name = DataUseUserData::NOT_TAGGED; | 138 DataUseUserData::ServiceName service_name = DataUseUserData::NOT_TAGGED; |
| 127 DataUseUserData::AppState old_app_state = DataUseUserData::FOREGROUND; | 139 DataUseUserData::AppState old_app_state = DataUseUserData::FOREGROUND; |
| 128 DataUseUserData::AppState new_app_state = DataUseUserData::UNKNOWN; | 140 DataUseUserData::AppState new_app_state = DataUseUserData::UNKNOWN; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 140 RecordUMAHistogramCount( | 152 RecordUMAHistogramCount( |
| 141 GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" | 153 GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" |
| 142 : "DataUse.TrafficSize.System", | 154 : "DataUse.TrafficSize.System", |
| 143 dir, new_app_state, is_connection_cellular), | 155 dir, new_app_state, is_connection_cellular), |
| 144 bytes); | 156 bytes); |
| 145 | 157 |
| 146 if (!is_user_traffic) { | 158 if (!is_user_traffic) { |
| 147 ReportDataUsageServices(service_name, dir, new_app_state, | 159 ReportDataUsageServices(service_name, dir, new_app_state, |
| 148 is_connection_cellular, bytes); | 160 is_connection_cellular, bytes); |
| 149 } | 161 } |
| 162 #if defined(OS_ANDROID) | |
| 163 if (dir == DOWNSTREAM && CurrentAppState() == DataUseUserData::BACKGROUND) { | |
| 164 const base::TimeDelta time_since_background = | |
| 165 base::TimeTicks::Now() - last_app_background_time_; | |
|
Not at Google. Contact bengr
2016/10/14 23:10:57
DCHECK(!last_app_background_time_.is_null());
Raj
2016/10/15 19:36:14
Done.
| |
| 166 IncreaseTimeHistogramByValue( | |
| 167 is_user_traffic ? "DataUse.BackgroundDownstreamBytes.User" | |
| 168 : "DataUse.BackgroundDownstreamBytes.System", | |
| 169 time_since_background, bytes); | |
| 170 if (first_read_after_background_) { | |
| 171 first_read_after_background_ = false; | |
| 172 UMA_HISTOGRAM_LONG_TIMES( | |
| 173 is_user_traffic ? "DataUse.BackgroundDownstreamFirstRead.User" | |
| 174 : "DataUse.BackgroundDownstreamFirstRead.System", | |
| 175 time_since_background); | |
| 176 } | |
| 177 } | |
| 178 #endif | |
| 150 } | 179 } |
| 151 | 180 |
| 152 void DataUseMeasurement::UpdateDataUsePrefs( | 181 void DataUseMeasurement::UpdateDataUsePrefs( |
| 153 const net::URLRequest& request) const { | 182 const net::URLRequest& request) const { |
| 154 bool is_connection_cellular = | 183 bool is_connection_cellular = |
| 155 net::NetworkChangeNotifier::IsConnectionCellular( | 184 net::NetworkChangeNotifier::IsConnectionCellular( |
| 156 net::NetworkChangeNotifier::GetConnectionType()); | 185 net::NetworkChangeNotifier::GetConnectionType()); |
| 157 | 186 |
| 158 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( | 187 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( |
| 159 request.GetUserData(DataUseUserData::kUserDataKey)); | 188 request.GetUserData(DataUseUserData::kUserDataKey)); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 ? "Unknown" | 240 ? "Unknown" |
| 212 : (app_state == DataUseUserData::FOREGROUND ? "Foreground" | 241 : (app_state == DataUseUserData::FOREGROUND ? "Foreground" |
| 213 : "Background"), | 242 : "Background"), |
| 214 is_connection_cellular ? "Cellular" : "NotCellular"); | 243 is_connection_cellular ? "Cellular" : "NotCellular"); |
| 215 } | 244 } |
| 216 | 245 |
| 217 #if defined(OS_ANDROID) | 246 #if defined(OS_ANDROID) |
| 218 void DataUseMeasurement::OnApplicationStateChange( | 247 void DataUseMeasurement::OnApplicationStateChange( |
| 219 base::android::ApplicationState application_state) { | 248 base::android::ApplicationState application_state) { |
| 220 app_state_ = application_state; | 249 app_state_ = application_state; |
| 221 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) | 250 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { |
| 251 last_app_background_time_ = base::TimeTicks::Now(); | |
| 252 first_read_after_background_ = true; | |
| 222 MaybeRecordNetworkBytesOS(); | 253 MaybeRecordNetworkBytesOS(); |
| 254 } else { | |
| 255 last_app_background_time_ = base::TimeTicks(); | |
| 256 } | |
| 223 } | 257 } |
| 224 | 258 |
| 225 void DataUseMeasurement::MaybeRecordNetworkBytesOS() { | 259 void DataUseMeasurement::MaybeRecordNetworkBytesOS() { |
| 226 // Minimum number of bytes that should be reported by the network delegate | 260 // Minimum number of bytes that should be reported by the network delegate |
| 227 // before Android's TrafficStats API is queried (if Chrome is not in | 261 // before Android's TrafficStats API is queried (if Chrome is not in |
| 228 // background). This reduces the overhead of repeatedly calling the API. | 262 // background). This reduces the overhead of repeatedly calling the API. |
| 229 static const int64_t kMinDelegateBytes = 25000; | 263 static const int64_t kMinDelegateBytes = 25000; |
| 230 | 264 |
| 231 if (bytes_transferred_since_last_traffic_stats_query_ < kMinDelegateBytes && | 265 if (bytes_transferred_since_last_traffic_stats_query_ < kMinDelegateBytes && |
| 232 CurrentAppState() == DataUseUserData::FOREGROUND) { | 266 CurrentAppState() == DataUseUserData::FOREGROUND) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 message_size); | 300 message_size); |
| 267 if (message_size > 0) { | 301 if (message_size > 0) { |
| 268 IncreaseSparseHistogramByValue( | 302 IncreaseSparseHistogramByValue( |
| 269 GetHistogramName("DataUse.MessageSize.AllServices", dir, app_state, | 303 GetHistogramName("DataUse.MessageSize.AllServices", dir, app_state, |
| 270 is_connection_cellular), | 304 is_connection_cellular), |
| 271 service, message_size); | 305 service, message_size); |
| 272 } | 306 } |
| 273 } | 307 } |
| 274 | 308 |
| 275 } // namespace data_use_measurement | 309 } // namespace data_use_measurement |
| OLD | NEW |