| 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/core/data_use_measurement.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram_macros.h" | 7 #include "base/metrics/histogram_macros.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" |
| 11 #include "components/data_use_measurement/core/data_use_user_data.h" | 11 #include "components/data_use_measurement/core/data_use_user_data.h" |
| 12 #include "content/public/browser/resource_request_info.h" | 12 #include "components/data_use_measurement/core/url_request_classifier.h" |
| 13 #include "net/base/network_change_notifier.h" | 13 #include "net/base/network_change_notifier.h" |
| 14 #include "net/base/upload_data_stream.h" | 14 #include "net/base/upload_data_stream.h" |
| 15 #include "net/http/http_response_headers.h" | 15 #include "net/http/http_response_headers.h" |
| 16 #include "net/url_request/url_request.h" | 16 #include "net/url_request/url_request.h" |
| 17 | 17 |
| 18 #if defined(OS_ANDROID) | 18 #if defined(OS_ANDROID) |
| 19 #include "net/android/traffic_stats.h" | 19 #include "net/android/traffic_stats.h" |
| 20 #endif | 20 #endif |
| 21 | 21 |
| 22 namespace data_use_measurement { | 22 namespace data_use_measurement { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 base::TimeDelta::FromHours(1), // Maximum sample | 57 base::TimeDelta::FromHours(1), // Maximum sample |
| 58 50, // Bucket count. | 58 50, // Bucket count. |
| 59 base::HistogramBase::kUmaTargetedHistogramFlag); | 59 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 60 histogram_pointer->AddCount(latency.InMilliseconds(), count); | 60 histogram_pointer->AddCount(latency.InMilliseconds(), count); |
| 61 } | 61 } |
| 62 #endif | 62 #endif |
| 63 | 63 |
| 64 } // namespace | 64 } // namespace |
| 65 | 65 |
| 66 DataUseMeasurement::DataUseMeasurement( | 66 DataUseMeasurement::DataUseMeasurement( |
| 67 std::unique_ptr<URLRequestClassifier> url_request_classifier, |
| 67 const metrics::UpdateUsagePrefCallbackType& metrics_data_use_forwarder) | 68 const metrics::UpdateUsagePrefCallbackType& metrics_data_use_forwarder) |
| 68 : metrics_data_use_forwarder_(metrics_data_use_forwarder) | 69 : url_request_classifier_(std::move(url_request_classifier)), |
| 70 metrics_data_use_forwarder_(metrics_data_use_forwarder) |
| 69 #if defined(OS_ANDROID) | 71 #if defined(OS_ANDROID) |
| 70 , | 72 , |
| 71 app_state_(base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES), | 73 app_state_(base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES), |
| 72 app_listener_(new base::android::ApplicationStatusListener( | 74 app_listener_(new base::android::ApplicationStatusListener( |
| 73 base::Bind(&DataUseMeasurement::OnApplicationStateChange, | 75 base::Bind(&DataUseMeasurement::OnApplicationStateChange, |
| 74 base::Unretained(this)))), | 76 base::Unretained(this)))), |
| 75 rx_bytes_os_(0), | 77 rx_bytes_os_(0), |
| 76 tx_bytes_os_(0), | 78 tx_bytes_os_(0), |
| 77 bytes_transferred_since_last_traffic_stats_query_(0), | 79 bytes_transferred_since_last_traffic_stats_query_(0), |
| 78 no_reads_since_background_(false) | 80 no_reads_since_background_(false) |
| 79 #endif | 81 #endif |
| 80 { | 82 { |
| 83 DCHECK(url_request_classifier_); |
| 81 } | 84 } |
| 82 | 85 |
| 83 DataUseMeasurement::~DataUseMeasurement(){}; | 86 DataUseMeasurement::~DataUseMeasurement(){}; |
| 84 | 87 |
| 85 void DataUseMeasurement::OnBeforeURLRequest(net::URLRequest* request) { | 88 void DataUseMeasurement::OnBeforeURLRequest(net::URLRequest* request) { |
| 86 DataUseUserData* data_use_user_data = reinterpret_cast<DataUseUserData*>( | 89 DataUseUserData* data_use_user_data = reinterpret_cast<DataUseUserData*>( |
| 87 request->GetUserData(DataUseUserData::kUserDataKey)); | 90 request->GetUserData(DataUseUserData::kUserDataKey)); |
| 88 if (!data_use_user_data) { | 91 if (!data_use_user_data) { |
| 89 data_use_user_data = new DataUseUserData( | 92 data_use_user_data = new DataUseUserData( |
| 90 DataUseUserData::ServiceName::NOT_TAGGED, CurrentAppState()); | 93 DataUseUserData::ServiceName::NOT_TAGGED, CurrentAppState()); |
| 91 request->SetUserData(DataUseUserData::kUserDataKey, data_use_user_data); | 94 request->SetUserData(DataUseUserData::kUserDataKey, data_use_user_data); |
| 92 } | 95 } |
| 93 } | 96 } |
| 94 | 97 |
| 95 void DataUseMeasurement::OnBeforeRedirect(const net::URLRequest& request, | 98 void DataUseMeasurement::OnBeforeRedirect(const net::URLRequest& request, |
| 96 const GURL& new_location) { | 99 const GURL& new_location) { |
| 97 // Recording data use of request on redirects. | 100 // Recording data use of request on redirects. |
| 98 // TODO(rajendrant): May not be needed when http://crbug/651957 is fixed. | 101 // TODO(rajendrant): May not be needed when http://crbug/651957 is fixed. |
| 99 UpdateDataUsePrefs(request); | 102 UpdateDataUsePrefs(request); |
| 103 ReportServicesMessageSizeUMA(request); |
| 100 } | 104 } |
| 101 | 105 |
| 102 void DataUseMeasurement::OnNetworkBytesReceived(const net::URLRequest& request, | 106 void DataUseMeasurement::OnNetworkBytesReceived(const net::URLRequest& request, |
| 103 int64_t bytes_received) { | 107 int64_t bytes_received) { |
| 104 UMA_HISTOGRAM_COUNTS("DataUse.BytesReceived.Delegate", bytes_received); | 108 UMA_HISTOGRAM_COUNTS("DataUse.BytesReceived.Delegate", bytes_received); |
| 105 ReportDataUseUMA(request, DOWNSTREAM, bytes_received); | 109 ReportDataUseUMA(request, DOWNSTREAM, bytes_received); |
| 106 #if defined(OS_ANDROID) | 110 #if defined(OS_ANDROID) |
| 107 bytes_transferred_since_last_traffic_stats_query_ += bytes_received; | 111 bytes_transferred_since_last_traffic_stats_query_ += bytes_received; |
| 108 #endif | 112 #endif |
| 109 } | 113 } |
| 110 | 114 |
| 111 void DataUseMeasurement::OnNetworkBytesSent(const net::URLRequest& request, | 115 void DataUseMeasurement::OnNetworkBytesSent(const net::URLRequest& request, |
| 112 int64_t bytes_sent) { | 116 int64_t bytes_sent) { |
| 113 UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.Delegate", bytes_sent); | 117 UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.Delegate", bytes_sent); |
| 114 ReportDataUseUMA(request, UPSTREAM, bytes_sent); | 118 ReportDataUseUMA(request, UPSTREAM, bytes_sent); |
| 115 #if defined(OS_ANDROID) | 119 #if defined(OS_ANDROID) |
| 116 bytes_transferred_since_last_traffic_stats_query_ += bytes_sent; | 120 bytes_transferred_since_last_traffic_stats_query_ += bytes_sent; |
| 117 #endif | 121 #endif |
| 118 } | 122 } |
| 119 | 123 |
| 120 void DataUseMeasurement::OnCompleted(const net::URLRequest& request, | 124 void DataUseMeasurement::OnCompleted(const net::URLRequest& request, |
| 121 bool started) { | 125 bool started) { |
| 122 // TODO(amohammadkhan): Verify that there is no double recording in data use | 126 // TODO(amohammadkhan): Verify that there is no double recording in data use |
| 123 // of redirected requests. | 127 // of redirected requests. |
| 124 UpdateDataUsePrefs(request); | 128 UpdateDataUsePrefs(request); |
| 129 ReportServicesMessageSizeUMA(request); |
| 125 #if defined(OS_ANDROID) | 130 #if defined(OS_ANDROID) |
| 126 MaybeRecordNetworkBytesOS(); | 131 MaybeRecordNetworkBytesOS(); |
| 127 #endif | 132 #endif |
| 128 } | 133 } |
| 129 | 134 |
| 130 void DataUseMeasurement::ReportDataUseUMA(const net::URLRequest& request, | 135 void DataUseMeasurement::ReportDataUseUMA(const net::URLRequest& request, |
| 131 TrafficDirection dir, | 136 TrafficDirection dir, |
| 132 int64_t bytes) { | 137 int64_t bytes) { |
| 133 bool is_user_traffic = IsUserInitiatedRequest(request); | 138 bool is_user_traffic = url_request_classifier_->IsUserRequest(request); |
| 134 bool is_connection_cellular = | 139 bool is_connection_cellular = |
| 135 net::NetworkChangeNotifier::IsConnectionCellular( | 140 net::NetworkChangeNotifier::IsConnectionCellular( |
| 136 net::NetworkChangeNotifier::GetConnectionType()); | 141 net::NetworkChangeNotifier::GetConnectionType()); |
| 137 | 142 |
| 138 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( | 143 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( |
| 139 request.GetUserData(DataUseUserData::kUserDataKey)); | 144 request.GetUserData(DataUseUserData::kUserDataKey)); |
| 140 DataUseUserData::ServiceName service_name = DataUseUserData::NOT_TAGGED; | |
| 141 DataUseUserData::AppState old_app_state = DataUseUserData::FOREGROUND; | 145 DataUseUserData::AppState old_app_state = DataUseUserData::FOREGROUND; |
| 142 DataUseUserData::AppState new_app_state = DataUseUserData::UNKNOWN; | 146 DataUseUserData::AppState new_app_state = DataUseUserData::UNKNOWN; |
| 143 | 147 |
| 144 if (attached_service_data) { | 148 if (attached_service_data) |
| 145 service_name = attached_service_data->service_name(); | |
| 146 old_app_state = attached_service_data->app_state(); | 149 old_app_state = attached_service_data->app_state(); |
| 147 } | 150 |
| 148 if (old_app_state == CurrentAppState()) | 151 if (old_app_state == CurrentAppState()) |
| 149 new_app_state = old_app_state; | 152 new_app_state = old_app_state; |
| 150 | 153 |
| 151 if (attached_service_data && old_app_state != new_app_state) | 154 if (attached_service_data && old_app_state != new_app_state) |
| 152 attached_service_data->set_app_state(CurrentAppState()); | 155 attached_service_data->set_app_state(CurrentAppState()); |
| 153 | 156 |
| 154 RecordUMAHistogramCount( | 157 RecordUMAHistogramCount( |
| 155 GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" | 158 GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" |
| 156 : "DataUse.TrafficSize.System", | 159 : "DataUse.TrafficSize.System", |
| 157 dir, new_app_state, is_connection_cellular), | 160 dir, new_app_state, is_connection_cellular), |
| 158 bytes); | 161 bytes); |
| 159 | 162 |
| 160 if (!is_user_traffic) { | |
| 161 ReportDataUsageServices(service_name, dir, new_app_state, | |
| 162 is_connection_cellular, bytes); | |
| 163 } | |
| 164 #if defined(OS_ANDROID) | 163 #if defined(OS_ANDROID) |
| 165 if (dir == DOWNSTREAM && CurrentAppState() == DataUseUserData::BACKGROUND) { | 164 if (dir == DOWNSTREAM && CurrentAppState() == DataUseUserData::BACKGROUND) { |
| 166 DCHECK(!last_app_background_time_.is_null()); | 165 DCHECK(!last_app_background_time_.is_null()); |
| 167 | 166 |
| 168 const base::TimeDelta time_since_background = | 167 const base::TimeDelta time_since_background = |
| 169 base::TimeTicks::Now() - last_app_background_time_; | 168 base::TimeTicks::Now() - last_app_background_time_; |
| 170 IncrementLatencyHistogramByCount( | 169 IncrementLatencyHistogramByCount( |
| 171 is_user_traffic ? "DataUse.BackgroundToDataRecievedPerByte.User" | 170 is_user_traffic ? "DataUse.BackgroundToDataRecievedPerByte.User" |
| 172 : "DataUse.BackgroundToDataRecievedPerByte.System", | 171 : "DataUse.BackgroundToDataRecievedPerByte.System", |
| 173 time_since_background, bytes); | 172 time_since_background, bytes); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 196 | 195 |
| 197 // Update data use prefs for cellular connections. | 196 // Update data use prefs for cellular connections. |
| 198 if (!metrics_data_use_forwarder_.is_null()) { | 197 if (!metrics_data_use_forwarder_.is_null()) { |
| 199 metrics_data_use_forwarder_.Run( | 198 metrics_data_use_forwarder_.Run( |
| 200 DataUseUserData::GetServiceNameAsString(service_name), | 199 DataUseUserData::GetServiceNameAsString(service_name), |
| 201 request.GetTotalSentBytes() + request.GetTotalReceivedBytes(), | 200 request.GetTotalSentBytes() + request.GetTotalReceivedBytes(), |
| 202 is_connection_cellular); | 201 is_connection_cellular); |
| 203 } | 202 } |
| 204 } | 203 } |
| 205 | 204 |
| 206 // static | |
| 207 bool DataUseMeasurement::IsUserInitiatedRequest( | |
| 208 const net::URLRequest& request) { | |
| 209 // Having ResourceRequestInfo in the URL request is a sign that the request is | |
| 210 // for a web content from user. For now we could add a condition to check | |
| 211 // ProcessType in info is content::PROCESS_TYPE_RENDERER, but it won't be | |
| 212 // compatible with upcoming PlzNavigate architecture. So just existence of | |
| 213 // ResourceRequestInfo is verified, and the current check should be compatible | |
| 214 // with upcoming changes in PlzNavigate. | |
| 215 // TODO(rajendrant): Verify this condition for different use cases. See | |
| 216 // crbug.com/626063. | |
| 217 return content::ResourceRequestInfo::ForRequest(&request) != nullptr; | |
| 218 } | |
| 219 | |
| 220 #if defined(OS_ANDROID) | 205 #if defined(OS_ANDROID) |
| 221 void DataUseMeasurement::OnApplicationStateChangeForTesting( | 206 void DataUseMeasurement::OnApplicationStateChangeForTesting( |
| 222 base::android::ApplicationState application_state) { | 207 base::android::ApplicationState application_state) { |
| 223 OnApplicationStateChange(application_state); | 208 OnApplicationStateChange(application_state); |
| 224 } | 209 } |
| 225 #endif | 210 #endif |
| 226 | 211 |
| 227 DataUseUserData::AppState DataUseMeasurement::CurrentAppState() const { | 212 DataUseUserData::AppState DataUseMeasurement::CurrentAppState() const { |
| 228 #if defined(OS_ANDROID) | 213 #if defined(OS_ANDROID) |
| 229 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) | 214 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 if (net::android::traffic_stats::GetCurrentUidTxBytes(&bytes)) { | 271 if (net::android::traffic_stats::GetCurrentUidTxBytes(&bytes)) { |
| 287 if (tx_bytes_os_ != 0) { | 272 if (tx_bytes_os_ != 0) { |
| 288 DCHECK_GE(bytes, tx_bytes_os_); | 273 DCHECK_GE(bytes, tx_bytes_os_); |
| 289 UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.OS", bytes - tx_bytes_os_); | 274 UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.OS", bytes - tx_bytes_os_); |
| 290 } | 275 } |
| 291 tx_bytes_os_ = bytes; | 276 tx_bytes_os_ = bytes; |
| 292 } | 277 } |
| 293 } | 278 } |
| 294 #endif | 279 #endif |
| 295 | 280 |
| 281 void DataUseMeasurement::ReportServicesMessageSizeUMA( |
| 282 const net::URLRequest& request) { |
| 283 bool is_user_traffic = url_request_classifier_->IsUserRequest(request); |
| 284 bool is_connection_cellular = |
| 285 net::NetworkChangeNotifier::IsConnectionCellular( |
| 286 net::NetworkChangeNotifier::GetConnectionType()); |
| 287 |
| 288 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( |
| 289 request.GetUserData(DataUseUserData::kUserDataKey)); |
| 290 DataUseUserData::ServiceName service_name = DataUseUserData::NOT_TAGGED; |
| 291 |
| 292 if (attached_service_data) |
| 293 service_name = attached_service_data->service_name(); |
| 294 |
| 295 if (!is_user_traffic) { |
| 296 ReportDataUsageServices(service_name, UPSTREAM, CurrentAppState(), |
| 297 is_connection_cellular, |
| 298 request.GetTotalSentBytes()); |
| 299 ReportDataUsageServices(service_name, DOWNSTREAM, CurrentAppState(), |
| 300 is_connection_cellular, |
| 301 request.GetTotalReceivedBytes()); |
| 302 } |
| 303 } |
| 304 |
| 296 void DataUseMeasurement::ReportDataUsageServices( | 305 void DataUseMeasurement::ReportDataUsageServices( |
| 297 DataUseUserData::ServiceName service, | 306 DataUseUserData::ServiceName service, |
| 298 TrafficDirection dir, | 307 TrafficDirection dir, |
| 299 DataUseUserData::AppState app_state, | 308 DataUseUserData::AppState app_state, |
| 300 bool is_connection_cellular, | 309 bool is_connection_cellular, |
| 301 int64_t message_size) const { | 310 int64_t message_size) const { |
| 302 RecordUMAHistogramCount( | 311 RecordUMAHistogramCount( |
| 303 "DataUse.MessageSize." + DataUseUserData::GetServiceNameAsString(service), | 312 "DataUse.MessageSize." + DataUseUserData::GetServiceNameAsString(service), |
| 304 message_size); | 313 message_size); |
| 305 if (message_size > 0) { | 314 if (message_size > 0) { |
| 306 IncreaseSparseHistogramByValue( | 315 IncreaseSparseHistogramByValue( |
| 307 GetHistogramName("DataUse.MessageSize.AllServices", dir, app_state, | 316 GetHistogramName("DataUse.MessageSize.AllServices", dir, app_state, |
| 308 is_connection_cellular), | 317 is_connection_cellular), |
| 309 service, message_size); | 318 service, message_size); |
| 310 } | 319 } |
| 311 } | 320 } |
| 312 | 321 |
| 313 } // namespace data_use_measurement | 322 } // namespace data_use_measurement |
| OLD | NEW |