Chromium Code Reviews| Index: chrome/browser/net/data_use_measurement.cc |
| diff --git a/chrome/browser/net/data_use_measurement.cc b/chrome/browser/net/data_use_measurement.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..91181333277ef54e143c849a7e0752c552e21128 |
| --- /dev/null |
| +++ b/chrome/browser/net/data_use_measurement.cc |
| @@ -0,0 +1,185 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <string> |
| + |
| +#include "base/metrics/histogram.h" |
| +#include "chrome/browser/net/data_use_measurement.h" |
| +#include "content/public/browser/resource_request_info.h" |
| +#include "content/public/common/process_type.h" |
| +#include "net/base/network_change_notifier.h" |
| +#include "net/base/upload_data_stream.h" |
| +#include "net/url_request/url_request.h" |
| + |
| +#if defined(OS_ANDROID) |
| +#include "base/android/application_status_listener.h" |
| +#endif |
| + |
| +// Copied from chromecast/base/metrics/cast_histograms.h |
|
bengr
2015/08/07 18:00:01
Why are you copying code? Add a TODO to unify thes
amohammadkhan
2015/08/11 22:04:34
I didn't like copying myself too, but I didn't wan
|
| +#define STATIC_HISTOGRAM_POINTER_BLOCK_NO_CACHE( \ |
| + constant_histogram_name, histogram_add_method_invocation, \ |
| + histogram_factory_get_invocation) \ |
| + do { \ |
| + base::HistogramBase* histogram_pointer = histogram_factory_get_invocation; \ |
| + if (DCHECK_IS_ON()) \ |
| + histogram_pointer->CheckName(constant_histogram_name); \ |
| + histogram_pointer->histogram_add_method_invocation; \ |
| + } while (0) |
| + |
| +// Copied from chromecast/base/metrics/cast_histograms.h |
| +#define UMA_HISTOGRAM_CUSTOM_COUNTS_NO_CACHE(name, sample, min, max, \ |
| + bucket_count) \ |
| + STATIC_HISTOGRAM_POINTER_BLOCK_NO_CACHE(name, Add(sample), \ |
| + base::Histogram::FactoryGet(name, min, max, bucket_count, \ |
| + base::HistogramBase::kUmaTargetedHistogramFlag)) |
| + |
| +// NO_CACHE version of UMA_HISTOGRAM_CUSTOM_COUNT is used because the names of |
|
bengr
2015/08/07 18:00:00
I can't parse this comment.
amohammadkhan
2015/08/11 22:04:35
Sorry. I tried to rephrase it. Please let me know
|
| +// histograms may change when measurement is done for different services |
| +// the maximum size of the request is about 5MB which may not be enough for |
| +// large contents. |
| +#define TRAFFIC_MEASUREMENT_UMA_HISTOGRAM(name, sample) \ |
| + UMA_HISTOGRAM_CUSTOM_COUNTS_NO_CACHE(name, sample, 1, 5000000, 50) |
| + |
| +namespace { |
| + |
| +// Enumerate the direction of data. Specifies the measured data was sent or |
|
bengr
2015/08/07 18:00:01
Rewrite comment:
// Specifies that data is receiv
amohammadkhan
2015/08/11 22:04:35
Done.
|
| +// received data |
| +enum TrafficDirection { |
| + DOWNLOAD, |
| + UPLOAD |
| +}; |
| + |
| +enum AppState { |
|
bengr
2015/08/07 18:00:00
// The state of the application. Only available on
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + BACKGROUND, |
| + FOREGROUND |
| +}; |
| + |
| +enum ConnectionType { |
|
bengr
2015/08/07 18:00:01
The type of network connection that was used.
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + CELLULAR, |
| + WIFI |
|
bengr
2015/08/07 18:00:00
Should this be tri-state: CELLULAR, WIFI, OTHER?
amohammadkhan
2015/08/11 22:04:35
Basically I am checking isCellular, so I changed i
|
| +}; |
| + |
| +enum ChromeServiceType { |
|
bengr
2015/08/07 18:00:01
The reason a request was sent.
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + USER_TRAFFIC, |
| + NOT_USER_TRAFFIC |
|
bengr
2015/08/07 18:00:00
Maybe all this SERVICE_TRAFFIC.
amohammadkhan
2015/08/11 22:04:34
Done.
|
| +}; |
| + |
| +#if defined(OS_ANDROID) |
| +// It seems it is not updated at the beginning, so if we start in background |
| +// somehow, it might be buggy until an event happens. |
|
bengr
2015/08/07 18:00:00
Don't try to land buggy code. We should know for s
amohammadkhan
2015/08/11 22:04:35
I think I was over thinking. The Chrome should alw
|
| +// These are for just android, do I need to add if here? |
|
bengr
2015/08/07 18:00:01
Strange comment. Is it needed?
amohammadkhan
2015/08/11 22:04:35
Done.
|
| +base::android::ApplicationState app_state = |
| + base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES; |
| +base::android::ApplicationStatusListener* app_listener; |
| +#endif |
| + |
| +bool listener_made = false; |
|
bengr
2015/08/07 18:00:00
Don't use file scope variables. If you have state
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + |
| +#if defined(OS_ANDROID) |
| +void OnApplicationStateChange( |
| + base::android::ApplicationState application_state) { |
| + app_state = application_state; |
| +} |
| +#endif |
| + |
| +std::string MakeHistogramName(ChromeServiceType service_type) { |
|
bengr
2015/08/07 18:00:00
Delete this function and see my comment on line 12
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + std::string histogram_prefix = "DataUse."; |
| + switch (service_type) { |
| + case USER_TRAFFIC: |
| + return histogram_prefix + "UserData"; |
| + case NOT_USER_TRAFFIC: |
| + return histogram_prefix + "NotUserData"; |
| + } |
| + assert(false); |
| + return histogram_prefix; |
| +} |
| + |
| +AppState CurrentAppState() { |
|
bengr
2015/08/07 18:00:01
AppState CurrentAppState() {
#if defined(OS_ANDROI
amohammadkhan
2015/08/11 22:04:35
I'm gonna use the similar approach to your propose
|
| +#if defined(OS_ANDROID) |
| + if (app_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) |
|
bengr
2015/08/07 18:00:00
Is this really the right way to check?
amohammadkhan
2015/08/11 22:04:35
I think so. At least it is working well in my test
|
| + return FOREGROUND; |
| + else |
| + return BACKGROUND; |
| +#endif |
| + // If the OS is not Android, all the requests are considered foreground so for |
| + // fair comparison between foreground and background data use, -A histograms |
| + // should be chosen in UMA. |
| + return FOREGROUND; |
| +} |
| + |
| +ConnectionType CurrentConnectionType() { |
| + if (net::NetworkChangeNotifier::IsConnectionCellular( |
| + net::NetworkChangeNotifier::GetConnectionType())) { |
| + return CELLULAR; |
| + } |
| + return WIFI; |
| +} |
| + |
| +void ReportDataUsage(ChromeServiceType service_type, |
| + TrafficDirection dir, int message_size) { |
| + AppState appState = CurrentAppState(); |
| + ConnectionType connType = CurrentConnectionType(); |
| + std::string first_suffix = ""; |
| + std::string second_suffix = ""; |
| + std::string third_suffix = ""; |
| + if (dir == UPLOAD) { |
|
bengr
2015/08/07 18:00:01
Remove curly braces. Also, I think you have the di
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + first_suffix = ".Download"; |
| + } else { |
| + first_suffix = ".Upload"; |
| + } |
| + if (appState == BACKGROUND) { |
| + second_suffix = ".Background"; |
| + } else { |
| + second_suffix = ".Foreground"; |
| + } |
| + if (connType == WIFI) { |
| + third_suffix = ".Wifi"; |
| + } else { |
| + third_suffix = ".Cell"; |
| + } |
| + std::string histogram_name = MakeHistogramName(service_type); |
| + std::string final_histogram_name = histogram_name + first_suffix + |
| + second_suffix + third_suffix; |
| + TRAFFIC_MEASUREMENT_UMA_HISTOGRAM(final_histogram_name, message_size); |
| +} |
| + |
| +} // namespace |
| + |
| +void ReportDataUsage(const net::URLRequest* request) { |
| +#if defined(OS_ANDROID) |
| + if (!listener_made) { |
|
bengr
2015/08/07 18:00:01
What does listener_made mean?
amohammadkhan
2015/08/11 22:04:35
Removed in new version.
|
| + listener_made = true; |
| + app_listener = new base::android::ApplicationStatusListener( |
| + base::Bind(&OnApplicationStateChange)); |
| + } |
| +#endif |
| + bool renderer_flag = false; |
| + const content::ResourceRequestInfo* info = |
| + content::ResourceRequestInfo::ForRequest(request); |
| + if (!info) { |
|
bengr
2015/08/07 18:00:01
Do:
// All data from a renderer process is assume
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + // Requests without info are categorized as NOT_USER_TRAFFIC data |
| + } else if (info->GetProcessType() == content::PROCESS_TYPE_RENDERER) { |
| + // We assume all data from renderer process are USER_DATA |
| + renderer_flag = true; |
| + } |
| + int request_body_bytes = 0; |
| + int request_header_bytes = 0; |
|
bengr
2015/08/07 18:00:01
Add a comment explaining that these won't be the n
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + int total_upload_bytes = 0; |
| + if (request->has_upload()){ |
| + request_body_bytes = request->get_upload()->size(); |
| + } |
| + net::HttpRequestHeaders request_headers; |
| + if (request->GetFullRequestHeaders(&request_headers)) { |
|
bengr
2015/08/07 18:00:01
Remove curly braces.
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + request_header_bytes = request_headers.ToString().length(); |
| + } |
| + total_upload_bytes = request_body_bytes + request_header_bytes; |
|
bengr
2015/08/07 18:00:00
Remove extra space
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + int total_received_bytes = request->GetTotalReceivedBytes(); |
| + if (renderer_flag) { |
|
bengr
2015/08/07 18:00:00
Instead of having two cases, do:
ReportDataUsage(r
amohammadkhan
2015/08/11 22:04:35
Done.
|
| + ReportDataUsage(USER_TRAFFIC, UPLOAD, total_upload_bytes); |
| + ReportDataUsage(USER_TRAFFIC, DOWNLOAD, total_received_bytes); |
| + } else { |
| + ReportDataUsage(NOT_USER_TRAFFIC, UPLOAD, total_upload_bytes); |
| + ReportDataUsage(NOT_USER_TRAFFIC, DOWNLOAD, total_received_bytes); |
| + } |
| +} |