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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 if (!data_use_user_data) { | 73 if (!data_use_user_data) { |
74 data_use_user_data = new DataUseUserData( | 74 data_use_user_data = new DataUseUserData( |
75 DataUseUserData::ServiceName::NOT_TAGGED, CurrentAppState()); | 75 DataUseUserData::ServiceName::NOT_TAGGED, CurrentAppState()); |
76 request->SetUserData(DataUseUserData::kUserDataKey, data_use_user_data); | 76 request->SetUserData(DataUseUserData::kUserDataKey, data_use_user_data); |
77 } | 77 } |
78 } | 78 } |
79 | 79 |
80 void DataUseMeasurement::OnBeforeRedirect(const net::URLRequest& request, | 80 void DataUseMeasurement::OnBeforeRedirect(const net::URLRequest& request, |
81 const GURL& new_location) { | 81 const GURL& new_location) { |
82 // Recording data use of request on redirects. | 82 // Recording data use of request on redirects. |
83 ReportDataUseUMA(request); | 83 // TODO(rajendrant): May not be needed when http://crbug/651957 is fixed. |
| 84 UpdateDataUsePrefs(request); |
84 } | 85 } |
85 | 86 |
86 void DataUseMeasurement::OnNetworkBytesReceived(const net::URLRequest& request, | 87 void DataUseMeasurement::OnNetworkBytesReceived(const net::URLRequest& request, |
87 int64_t bytes_received) { | 88 int64_t bytes_received) { |
88 UMA_HISTOGRAM_COUNTS("DataUse.BytesReceived.Delegate", bytes_received); | 89 UMA_HISTOGRAM_COUNTS("DataUse.BytesReceived.Delegate", bytes_received); |
| 90 ReportDataUseUMA(request, DOWNSTREAM, bytes_received); |
89 #if defined(OS_ANDROID) | 91 #if defined(OS_ANDROID) |
90 bytes_transferred_since_last_traffic_stats_query_ += bytes_received; | 92 bytes_transferred_since_last_traffic_stats_query_ += bytes_received; |
91 #endif | 93 #endif |
92 } | 94 } |
93 | 95 |
94 void DataUseMeasurement::OnNetworkBytesSent(const net::URLRequest& request, | 96 void DataUseMeasurement::OnNetworkBytesSent(const net::URLRequest& request, |
95 int64_t bytes_sent) { | 97 int64_t bytes_sent) { |
96 UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.Delegate", bytes_sent); | 98 UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.Delegate", bytes_sent); |
| 99 ReportDataUseUMA(request, UPSTREAM, bytes_sent); |
97 #if defined(OS_ANDROID) | 100 #if defined(OS_ANDROID) |
98 bytes_transferred_since_last_traffic_stats_query_ += bytes_sent; | 101 bytes_transferred_since_last_traffic_stats_query_ += bytes_sent; |
99 #endif | 102 #endif |
100 } | 103 } |
101 | 104 |
102 void DataUseMeasurement::OnCompleted(const net::URLRequest& request, | 105 void DataUseMeasurement::OnCompleted(const net::URLRequest& request, |
103 bool started) { | 106 bool started) { |
104 // TODO(amohammadkhan): Verify that there is no double recording in data use | 107 // TODO(amohammadkhan): Verify that there is no double recording in data use |
105 // of redirected requests. | 108 // of redirected requests. |
106 ReportDataUseUMA(request); | 109 UpdateDataUsePrefs(request); |
107 #if defined(OS_ANDROID) | 110 #if defined(OS_ANDROID) |
108 MaybeRecordNetworkBytesOS(); | 111 MaybeRecordNetworkBytesOS(); |
109 #endif | 112 #endif |
110 } | 113 } |
111 | 114 |
112 void DataUseMeasurement::ReportDataUseUMA( | 115 void DataUseMeasurement::ReportDataUseUMA( |
113 const net::URLRequest& request) const { | 116 const net::URLRequest& request, |
114 // Counts rely on URLRequest::GetTotalReceivedBytes() and | 117 TrafficDirection dir, |
115 // URLRequest::GetTotalSentBytes(), which does not include the send path, | 118 int64_t bytes) const { |
116 // network layer overhead, TLS overhead, and DNS. | |
117 // TODO(amohammadkhan): Make these measured bytes more in line with number of | |
118 // bytes in lower levels. | |
119 int64_t total_upload_bytes = request.GetTotalSentBytes(); | |
120 int64_t total_received_bytes = request.GetTotalReceivedBytes(); | |
121 bool is_user_traffic = IsUserInitiatedRequest(request); | 119 bool is_user_traffic = IsUserInitiatedRequest(request); |
122 | |
123 bool is_connection_cellular = | 120 bool is_connection_cellular = |
124 net::NetworkChangeNotifier::IsConnectionCellular( | 121 net::NetworkChangeNotifier::IsConnectionCellular( |
125 net::NetworkChangeNotifier::GetConnectionType()); | 122 net::NetworkChangeNotifier::GetConnectionType()); |
126 | 123 |
127 DataUseUserData* attached_service_data = reinterpret_cast<DataUseUserData*>( | 124 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( |
| 125 request.GetUserData(DataUseUserData::kUserDataKey)); |
| 126 DataUseUserData::ServiceName service_name = DataUseUserData::NOT_TAGGED; |
| 127 DataUseUserData::AppState old_app_state = DataUseUserData::FOREGROUND; |
| 128 DataUseUserData::AppState new_app_state = DataUseUserData::UNKNOWN; |
| 129 |
| 130 if (attached_service_data) { |
| 131 service_name = attached_service_data->service_name(); |
| 132 old_app_state = attached_service_data->app_state(); |
| 133 } |
| 134 if (old_app_state == CurrentAppState()) |
| 135 new_app_state = old_app_state; |
| 136 |
| 137 if (attached_service_data && old_app_state != new_app_state) |
| 138 attached_service_data->set_app_state(CurrentAppState()); |
| 139 |
| 140 RecordUMAHistogramCount( |
| 141 GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" |
| 142 : "DataUse.TrafficSize.System", |
| 143 dir, new_app_state, is_connection_cellular), |
| 144 bytes); |
| 145 |
| 146 if (!is_user_traffic) { |
| 147 ReportDataUsageServices(service_name, dir, new_app_state, |
| 148 is_connection_cellular, bytes); |
| 149 } |
| 150 } |
| 151 |
| 152 void DataUseMeasurement::UpdateDataUsePrefs( |
| 153 const net::URLRequest& request) const { |
| 154 bool is_connection_cellular = |
| 155 net::NetworkChangeNotifier::IsConnectionCellular( |
| 156 net::NetworkChangeNotifier::GetConnectionType()); |
| 157 |
| 158 DataUseUserData* attached_service_data = static_cast<DataUseUserData*>( |
128 request.GetUserData(DataUseUserData::kUserDataKey)); | 159 request.GetUserData(DataUseUserData::kUserDataKey)); |
129 DataUseUserData::ServiceName service_name = | 160 DataUseUserData::ServiceName service_name = |
130 attached_service_data ? attached_service_data->service_name() | 161 attached_service_data ? attached_service_data->service_name() |
131 : DataUseUserData::NOT_TAGGED; | 162 : DataUseUserData::NOT_TAGGED; |
132 bool started_in_foreground = | |
133 attached_service_data | |
134 ? attached_service_data->app_state() == DataUseUserData::FOREGROUND | |
135 : CurrentAppState() == DataUseUserData::FOREGROUND; | |
136 | |
137 RecordUMAHistogramCount( | |
138 GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" | |
139 : "DataUse.TrafficSize.System", | |
140 UPSTREAM, started_in_foreground, is_connection_cellular), | |
141 total_upload_bytes); | |
142 RecordUMAHistogramCount( | |
143 GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" | |
144 : "DataUse.TrafficSize.System", | |
145 DOWNSTREAM, started_in_foreground, | |
146 is_connection_cellular), | |
147 total_received_bytes); | |
148 | |
149 if (!is_user_traffic) { | |
150 ReportDataUsageServices(service_name, UPSTREAM, started_in_foreground, | |
151 is_connection_cellular, total_upload_bytes); | |
152 ReportDataUsageServices(service_name, DOWNSTREAM, started_in_foreground, | |
153 is_connection_cellular, total_received_bytes); | |
154 } | |
155 | 163 |
156 // Update data use prefs for cellular connections. | 164 // Update data use prefs for cellular connections. |
157 if (!metrics_data_use_forwarder_.is_null()) { | 165 if (!metrics_data_use_forwarder_.is_null()) { |
158 metrics_data_use_forwarder_.Run( | 166 metrics_data_use_forwarder_.Run( |
159 attached_service_data->GetServiceNameAsString(service_name), | 167 DataUseUserData::GetServiceNameAsString(service_name), |
160 total_upload_bytes + total_received_bytes, is_connection_cellular); | 168 request.GetTotalSentBytes() + request.GetTotalReceivedBytes(), |
| 169 is_connection_cellular); |
161 } | 170 } |
162 } | 171 } |
163 | 172 |
164 // static | 173 // static |
165 bool DataUseMeasurement::IsUserInitiatedRequest( | 174 bool DataUseMeasurement::IsUserInitiatedRequest( |
166 const net::URLRequest& request) { | 175 const net::URLRequest& request) { |
167 // Having ResourceRequestInfo in the URL request is a sign that the request is | 176 // Having ResourceRequestInfo in the URL request is a sign that the request is |
168 // for a web content from user. For now we could add a condition to check | 177 // for a web content from user. For now we could add a condition to check |
169 // ProcessType in info is content::PROCESS_TYPE_RENDERER, but it won't be | 178 // ProcessType in info is content::PROCESS_TYPE_RENDERER, but it won't be |
170 // compatible with upcoming PlzNavigate architecture. So just existence of | 179 // compatible with upcoming PlzNavigate architecture. So just existence of |
(...skipping 16 matching lines...) Expand all Loading... |
187 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) | 196 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) |
188 return DataUseUserData::BACKGROUND; | 197 return DataUseUserData::BACKGROUND; |
189 #endif | 198 #endif |
190 // If the OS is not Android, all the requests are considered Foreground. | 199 // If the OS is not Android, all the requests are considered Foreground. |
191 return DataUseUserData::FOREGROUND; | 200 return DataUseUserData::FOREGROUND; |
192 } | 201 } |
193 | 202 |
194 std::string DataUseMeasurement::GetHistogramName( | 203 std::string DataUseMeasurement::GetHistogramName( |
195 const char* prefix, | 204 const char* prefix, |
196 TrafficDirection dir, | 205 TrafficDirection dir, |
197 bool started_in_foreground, | 206 DataUseUserData::AppState app_state, |
198 bool is_connection_cellular) const { | 207 bool is_connection_cellular) const { |
199 return base::StringPrintf( | 208 return base::StringPrintf( |
200 "%s.%s.%s.%s", prefix, dir == UPSTREAM ? "Upstream" : "Downstream", | 209 "%s.%s.%s.%s", prefix, dir == UPSTREAM ? "Upstream" : "Downstream", |
201 started_in_foreground ? "Foreground" : "Background", | 210 app_state == DataUseUserData::UNKNOWN |
| 211 ? "Unknown" |
| 212 : (app_state == DataUseUserData::FOREGROUND ? "Foreground" |
| 213 : "Background"), |
202 is_connection_cellular ? "Cellular" : "NotCellular"); | 214 is_connection_cellular ? "Cellular" : "NotCellular"); |
203 } | 215 } |
204 | 216 |
205 #if defined(OS_ANDROID) | 217 #if defined(OS_ANDROID) |
206 void DataUseMeasurement::OnApplicationStateChange( | 218 void DataUseMeasurement::OnApplicationStateChange( |
207 base::android::ApplicationState application_state) { | 219 base::android::ApplicationState application_state) { |
208 app_state_ = application_state; | 220 app_state_ = application_state; |
209 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) | 221 if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) |
210 MaybeRecordNetworkBytesOS(); | 222 MaybeRecordNetworkBytesOS(); |
211 } | 223 } |
(...skipping 27 matching lines...) Expand all Loading... |
239 UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.OS", bytes - tx_bytes_os_); | 251 UMA_HISTOGRAM_COUNTS("DataUse.BytesSent.OS", bytes - tx_bytes_os_); |
240 } | 252 } |
241 tx_bytes_os_ = bytes; | 253 tx_bytes_os_ = bytes; |
242 } | 254 } |
243 } | 255 } |
244 #endif | 256 #endif |
245 | 257 |
246 void DataUseMeasurement::ReportDataUsageServices( | 258 void DataUseMeasurement::ReportDataUsageServices( |
247 DataUseUserData::ServiceName service, | 259 DataUseUserData::ServiceName service, |
248 TrafficDirection dir, | 260 TrafficDirection dir, |
249 bool started_in_foreground, | 261 DataUseUserData::AppState app_state, |
250 bool is_connection_cellular, | 262 bool is_connection_cellular, |
251 int64_t message_size) const { | 263 int64_t message_size) const { |
252 RecordUMAHistogramCount( | 264 RecordUMAHistogramCount( |
253 "DataUse.MessageSize." + DataUseUserData::GetServiceNameAsString(service), | 265 "DataUse.MessageSize." + DataUseUserData::GetServiceNameAsString(service), |
254 message_size); | 266 message_size); |
255 if (message_size > 0) { | 267 if (message_size > 0) { |
256 IncreaseSparseHistogramByValue( | 268 IncreaseSparseHistogramByValue( |
257 GetHistogramName("DataUse.MessageSize.AllServices", dir, | 269 GetHistogramName("DataUse.MessageSize.AllServices", dir, app_state, |
258 started_in_foreground, is_connection_cellular), | 270 is_connection_cellular), |
259 service, message_size); | 271 service, message_size); |
260 } | 272 } |
261 } | 273 } |
262 | 274 |
263 } // namespace data_use_measurement | 275 } // namespace data_use_measurement |
OLD | NEW |