Chromium Code Reviews| Index: net/url_request/data_use_measurement.cc |
| diff --git a/net/url_request/data_use_measurement.cc b/net/url_request/data_use_measurement.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..25f0e0fddd9b478dc0e7ee133091a18b3fd6a17f |
| --- /dev/null |
| +++ b/net/url_request/data_use_measurement.cc |
| @@ -0,0 +1,150 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
|
bengr
2015/08/07 18:00:01
This and the other data_use_measurement.cc should
amohammadkhan
2015/08/11 22:04:36
Done.
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <string> |
| + |
| +#include "base/hash.h" |
| +#include "base/metrics/histogram.h" |
| +#include "base/metrics/sparse_histogram.h" |
| +#include "net/base/network_change_notifier.h" |
| +#include "net/url_request/data_use_measurement.h" |
| +#include "net/url_request/url_fetcher.h" |
| + |
| +#if defined(OS_ANDROID) |
| +#include "base/android/application_status_listener.h" |
| +#endif |
| + |
| +#define UMA_HISTOGRAM_SPARSE_SLOWLY_WITH_VALUE(name, sample, value) \ |
| + do { \ |
| + base::HistogramBase* histogram = base::SparseHistogram::FactoryGet( \ |
| + name, base::HistogramBase::kUmaTargetedHistogramFlag); \ |
| + histogram->AddCount(sample, value); \ |
| + } while (0) |
| + |
| +// Copied from chromecast/base/metrics/cast_histograms.h |
|
bengr
2015/08/07 18:00:01
More copying? Add a TODO to unify with cast. Are t
amohammadkhan
2015/08/11 22:04:36
Done.
|
| +#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 |
| +// 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 { |
| + |
| +// Enumerates the direction of data. Specifies the measured data was sent or |
|
bengr
2015/08/07 18:00:01
Remove the first sentence.
amohammadkhan
2015/08/11 22:04:36
Done.
|
| +// received data |
| +enum TrafficDirection { DOWNLOAD, UPLOAD }; |
| + |
| +// Enumerates application state. For non android versions it is always |
|
bengr
2015/08/07 18:00:01
Android.
amohammadkhan
2015/08/11 22:04:36
Done.
|
| +// foreground |
|
bengr
2015/08/07 18:00:01
Add a period.
amohammadkhan
2015/08/11 22:04:36
Done.
|
| +enum AppState { BACKGROUND, FOREGROUND }; |
| + |
| +enum ConnectionType { CELLULAR, WIFI }; |
| + |
| +#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:01
Be clearer about this.
amohammadkhan
2015/08/11 22:04:36
Done.
|
| +base::android::ApplicationState app_state = |
| + base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES; |
| +base::android::ApplicationStatusListener* app_listener; |
| +#endif |
| + |
| +// A flag to signal we have just started and we do not have a listener so we |
| +// need to make one. |
| +bool listener_made = false; |
| + |
| +#if defined(OS_ANDROID) |
| +void OnApplicationStateChange( |
| + base::android::ApplicationState application_state) { |
| + app_state = application_state; |
| +} |
| +#endif |
| + |
| +AppState CurrentAppState() { |
| +#if defined(OS_ANDROID) |
| + if (app_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) |
| + 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; |
| + } |
| + // All not cellular connections are considered Wifi. |
| + return WIFI; |
| +} |
| + |
| +void ReportDataUsage(const std::string& service_name, |
| + TrafficDirection dir, |
| + int message_size) { |
| + AppState current_app_state = CurrentAppState(); |
| + ConnectionType connType = CurrentConnectionType(); |
| + std::string first_suffix = ""; |
| + std::string second_suffix = ""; |
| + std::string third_suffix = ""; |
| + if (dir == UPLOAD) { |
| + first_suffix = ".Download"; |
| + } else { |
| + first_suffix = ".Upload"; |
| + } |
| + if (current_app_state == BACKGROUND) { |
| + second_suffix = ".Background"; |
| + } else { |
| + second_suffix = ".Foreground"; |
| + } |
| + if (connType == WIFI) { |
| + third_suffix = ".Wifi"; |
| + } else { |
| + third_suffix = ".Cell"; |
| + } |
| + std::string serviceHistogramName = "DataUse.Service." + service_name; |
| + std::string combinedHistogramName = |
| + "DataUse.Services" + first_suffix + second_suffix + third_suffix; |
| + UMA_HISTOGRAM_SPARSE_SLOWLY_WITH_VALUE( |
| + combinedHistogramName, base::Hash(service_name), message_size); |
| + TRAFFIC_MEASUREMENT_UMA_HISTOGRAM(serviceHistogramName, message_size); |
| +} |
| + |
| +} // namespace |
| + |
| +void DataUseReport(const std::string& service_name, |
| + const net::URLFetcher* fetcher) { |
| +#if defined(OS_ANDROID) |
| + if (!listener_made) { |
| + listener_made = true; |
| + app_listener = new base::android::ApplicationStatusListener( |
| + base::Bind(&OnApplicationStateChange)); |
| + } |
| +#endif |
| + int total_upload_bytes = fetcher->GetBytesSentSize(); |
| + int total_received_bytes = fetcher->GetBytesReceivedSize(); |
| + ReportDataUsage(service_name, UPLOAD, total_upload_bytes); |
| + ReportDataUsage(service_name, DOWNLOAD, total_received_bytes); |
| +} |