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); |
+} |