Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1867)

Unified Diff: chrome/browser/net/data_use_measurement.cc

Issue 1279543002: Support needed to measure user and service traffic in Chrome. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@NewHistogram
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698