| 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 #if defined(OS_ANDROID) |
| 51 void IncrementLatencyHistogramByCount(const std::string& name, |
| 52 const base::TimeDelta& latency, |
| 53 int64_t count) { |
| 54 base::HistogramBase* histogram_pointer = base::Histogram::FactoryTimeGet( |
| 55 name, |
| 56 base::TimeDelta::FromMilliseconds(1), // Minimum sample |
| 57 base::TimeDelta::FromHours(1), // Maximum sample |
| 58 50, // Bucket count. |
| 59 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 60 histogram_pointer->AddCount(latency.InMilliseconds(), count); |
| 61 } |
| 62 #endif |
| 63 |
| 50 } // namespace | 64 } // namespace |
| 51 | 65 |
| 52 DataUseMeasurement::DataUseMeasurement( | 66 DataUseMeasurement::DataUseMeasurement( |
| 53 const metrics::UpdateUsagePrefCallbackType& metrics_data_use_forwarder) | 67 const metrics::UpdateUsagePrefCallbackType& metrics_data_use_forwarder) |
| 54 : metrics_data_use_forwarder_(metrics_data_use_forwarder) | 68 : metrics_data_use_forwarder_(metrics_data_use_forwarder) |
| 55 #if defined(OS_ANDROID) | 69 #if defined(OS_ANDROID) |
| 56 , | 70 , |
| 57 app_state_(base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES), | 71 app_state_(base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES), |
| 58 app_listener_(new base::android::ApplicationStatusListener( | 72 app_listener_(new base::android::ApplicationStatusListener( |
| 59 base::Bind(&DataUseMeasurement::OnApplicationStateChange, | 73 base::Bind(&DataUseMeasurement::OnApplicationStateChange, |
| 60 base::Unretained(this)))), | 74 base::Unretained(this)))), |
| 61 rx_bytes_os_(0), | 75 rx_bytes_os_(0), |
| 62 tx_bytes_os_(0), | 76 tx_bytes_os_(0), |
| 63 bytes_transferred_since_last_traffic_stats_query_(0) | 77 bytes_transferred_since_last_traffic_stats_query_(0), |
| 78 no_reads_since_background_(false) |
| 64 #endif | 79 #endif |
| 65 { | 80 { |
| 66 } | 81 } |
| 67 | 82 |
| 68 DataUseMeasurement::~DataUseMeasurement(){}; | 83 DataUseMeasurement::~DataUseMeasurement(){}; |
| 69 | 84 |
| 70 void DataUseMeasurement::OnBeforeURLRequest(net::URLRequest* request) { | 85 void DataUseMeasurement::OnBeforeURLRequest(net::URLRequest* request) { |
| 71 DataUseUserData* data_use_user_data = reinterpret_cast<DataUseUserData*>( | 86 DataUseUserData* data_use_user_data = reinterpret_cast<DataUseUserData*>( |
| 72 request->GetUserData(DataUseUserData::kUserDataKey)); | 87 request->GetUserData(DataUseUserData::kUserDataKey)); |
| 73 if (!data_use_user_data) { | 88 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, | 120 void DataUseMeasurement::OnCompleted(const net::URLRequest& request, |
| 106 bool started) { | 121 bool started) { |
| 107 // TODO(amohammadkhan): Verify that there is no double recording in data use | 122 // TODO(amohammadkhan): Verify that there is no double recording in data use |
| 108 // of redirected requests. | 123 // of redirected requests. |
| 109 UpdateDataUsePrefs(request); | 124 UpdateDataUsePrefs(request); |
| 110 #if defined(OS_ANDROID) | 125 #if defined(OS_ANDROID) |
| 111 MaybeRecordNetworkBytesOS(); | 126 MaybeRecordNetworkBytesOS(); |
| 112 #endif | 127 #endif |
| 113 } | 128 } |
| 114 | 129 |
| 115 void DataUseMeasurement::ReportDataUseUMA( | 130 void DataUseMeasurement::ReportDataUseUMA(const net::URLRequest& request, |
| 116 const net::URLRequest& request, | 131 TrafficDirection dir, |
| 117 TrafficDirection dir, | 132 int64_t bytes) { |
| 118 int64_t bytes) const { | |
| 119 bool is_user_traffic = IsUserInitiatedRequest(request); | 133 bool is_user_traffic = IsUserInitiatedRequest(request); |
| 120 bool is_connection_cellular = | 134 bool is_connection_cellular = |
| 121 net::NetworkChangeNotifier::IsConnectionCellular( | 135 net::NetworkChangeNotifier::IsConnectionCellular( |
| 122 net::NetworkChangeNotifier::GetConnectionType()); | 136 net::NetworkChangeNotifier::GetConnectionType()); |
| 123 | 137 |
| 124 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( | 138 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( |
| 125 request.GetUserData(DataUseUserData::kUserDataKey)); | 139 request.GetUserData(DataUseUserData::kUserDataKey)); |
| 126 DataUseUserData::ServiceName service_name = DataUseUserData::NOT_TAGGED; | 140 DataUseUserData::ServiceName service_name = DataUseUserData::NOT_TAGGED; |
| 127 DataUseUserData::AppState old_app_state = DataUseUserData::FOREGROUND; | 141 DataUseUserData::AppState old_app_state = DataUseUserData::FOREGROUND; |
| 128 DataUseUserData::AppState new_app_state = DataUseUserData::UNKNOWN; | 142 DataUseUserData::AppState new_app_state = DataUseUserData::UNKNOWN; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 140 RecordUMAHistogramCount( | 154 RecordUMAHistogramCount( |
| 141 GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" | 155 GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" |
| 142 : "DataUse.TrafficSize.System", | 156 : "DataUse.TrafficSize.System", |
| 143 dir, new_app_state, is_connection_cellular), | 157 dir, new_app_state, is_connection_cellular), |
| 144 bytes); | 158 bytes); |
| 145 | 159 |
| 146 if (!is_user_traffic) { | 160 if (!is_user_traffic) { |
| 147 ReportDataUsageServices(service_name, dir, new_app_state, | 161 ReportDataUsageServices(service_name, dir, new_app_state, |
| 148 is_connection_cellular, bytes); | 162 is_connection_cellular, bytes); |
| 149 } | 163 } |
| 164 #if defined(OS_ANDROID) |
| 165 if (dir == DOWNSTREAM && CurrentAppState() == DataUseUserData::BACKGROUND) { |
| 166 DCHECK(!last_app_background_time_.is_null()); |
| 167 |
| 168 const base::TimeDelta time_since_background = |
| 169 base::TimeTicks::Now() - last_app_background_time_; |
| 170 IncrementLatencyHistogramByCount( |
| 171 is_user_traffic ? "DataUse.BackgroundToDataRecievedPerByte.User" |
| 172 : "DataUse.BackgroundToDataRecievedPerByte.System", |
| 173 time_since_background, bytes); |
| 174 if (no_reads_since_background_) { |
| 175 no_reads_since_background_ = false; |
| 176 UMA_HISTOGRAM_LONG_TIMES( |
| 177 is_user_traffic ? "DataUse.BackgroundToFirstDownstream.User" |
| 178 : "DataUse.BackgroundToFirstDownstream.System", |
| 179 time_since_background); |
| 180 } |
| 181 } |
| 182 #endif |
| 150 } | 183 } |
| 151 | 184 |
| 152 void DataUseMeasurement::UpdateDataUsePrefs( | 185 void DataUseMeasurement::UpdateDataUsePrefs( |
| 153 const net::URLRequest& request) const { | 186 const net::URLRequest& request) const { |
| 154 bool is_connection_cellular = | 187 bool is_connection_cellular = |
| 155 net::NetworkChangeNotifier::IsConnectionCellular( | 188 net::NetworkChangeNotifier::IsConnectionCellular( |
| 156 net::NetworkChangeNotifier::GetConnectionType()); | 189 net::NetworkChangeNotifier::GetConnectionType()); |
| 157 | 190 |
| 158 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( | 191 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( |
| 159 request.GetUserData(DataUseUserData::kUserDataKey)); | 192 request.GetUserData(DataUseUserData::kUserDataKey)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 180 // ResourceRequestInfo is verified, and the current check should be compatible | 213 // ResourceRequestInfo is verified, and the current check should be compatible |
| 181 // with upcoming changes in PlzNavigate. | 214 // with upcoming changes in PlzNavigate. |
| 182 // TODO(rajendrant): Verify this condition for different use cases. See | 215 // TODO(rajendrant): Verify this condition for different use cases. See |
| 183 // crbug.com/626063. | 216 // crbug.com/626063. |
| 184 return content::ResourceRequestInfo::ForRequest(&request) != nullptr; | 217 return content::ResourceRequestInfo::ForRequest(&request) != nullptr; |
| 185 } | 218 } |
| 186 | 219 |
| 187 #if defined(OS_ANDROID) | 220 #if defined(OS_ANDROID) |
| 188 void DataUseMeasurement::OnApplicationStateChangeForTesting( | 221 void DataUseMeasurement::OnApplicationStateChangeForTesting( |
| 189 base::android::ApplicationState application_state) { | 222 base::android::ApplicationState application_state) { |
| 190 app_state_ = application_state; | 223 OnApplicationStateChange(application_state); |
| 191 } | 224 } |
| 192 #endif | 225 #endif |
| 193 | 226 |
| 194 DataUseUserData::AppState DataUseMeasurement::CurrentAppState() const { | 227 DataUseUserData::AppState DataUseMeasurement::CurrentAppState() const { |
| 195 #if defined(OS_ANDROID) | 228 #if defined(OS_ANDROID) |
| 196 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) | 229 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) |
| 197 return DataUseUserData::BACKGROUND; | 230 return DataUseUserData::BACKGROUND; |
| 198 #endif | 231 #endif |
| 199 // If the OS is not Android, all the requests are considered Foreground. | 232 // If the OS is not Android, all the requests are considered Foreground. |
| 200 return DataUseUserData::FOREGROUND; | 233 return DataUseUserData::FOREGROUND; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 211 ? "Unknown" | 244 ? "Unknown" |
| 212 : (app_state == DataUseUserData::FOREGROUND ? "Foreground" | 245 : (app_state == DataUseUserData::FOREGROUND ? "Foreground" |
| 213 : "Background"), | 246 : "Background"), |
| 214 is_connection_cellular ? "Cellular" : "NotCellular"); | 247 is_connection_cellular ? "Cellular" : "NotCellular"); |
| 215 } | 248 } |
| 216 | 249 |
| 217 #if defined(OS_ANDROID) | 250 #if defined(OS_ANDROID) |
| 218 void DataUseMeasurement::OnApplicationStateChange( | 251 void DataUseMeasurement::OnApplicationStateChange( |
| 219 base::android::ApplicationState application_state) { | 252 base::android::ApplicationState application_state) { |
| 220 app_state_ = application_state; | 253 app_state_ = application_state; |
| 221 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) | 254 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { |
| 255 last_app_background_time_ = base::TimeTicks::Now(); |
| 256 no_reads_since_background_ = true; |
| 222 MaybeRecordNetworkBytesOS(); | 257 MaybeRecordNetworkBytesOS(); |
| 258 } else { |
| 259 last_app_background_time_ = base::TimeTicks(); |
| 260 } |
| 223 } | 261 } |
| 224 | 262 |
| 225 void DataUseMeasurement::MaybeRecordNetworkBytesOS() { | 263 void DataUseMeasurement::MaybeRecordNetworkBytesOS() { |
| 226 // Minimum number of bytes that should be reported by the network delegate | 264 // 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 | 265 // before Android's TrafficStats API is queried (if Chrome is not in |
| 228 // background). This reduces the overhead of repeatedly calling the API. | 266 // background). This reduces the overhead of repeatedly calling the API. |
| 229 static const int64_t kMinDelegateBytes = 25000; | 267 static const int64_t kMinDelegateBytes = 25000; |
| 230 | 268 |
| 231 if (bytes_transferred_since_last_traffic_stats_query_ < kMinDelegateBytes && | 269 if (bytes_transferred_since_last_traffic_stats_query_ < kMinDelegateBytes && |
| 232 CurrentAppState() == DataUseUserData::FOREGROUND) { | 270 CurrentAppState() == DataUseUserData::FOREGROUND) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 message_size); | 304 message_size); |
| 267 if (message_size > 0) { | 305 if (message_size > 0) { |
| 268 IncreaseSparseHistogramByValue( | 306 IncreaseSparseHistogramByValue( |
| 269 GetHistogramName("DataUse.MessageSize.AllServices", dir, app_state, | 307 GetHistogramName("DataUse.MessageSize.AllServices", dir, app_state, |
| 270 is_connection_cellular), | 308 is_connection_cellular), |
| 271 service, message_size); | 309 service, message_size); |
| 272 } | 310 } |
| 273 } | 311 } |
| 274 | 312 |
| 275 } // namespace data_use_measurement | 313 } // namespace data_use_measurement |
| OLD | NEW |