| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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 | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 #include "components/data_use_measurement/content/data_use_measurement.h" | 
|  | 6 | 
|  | 7 #include "base/metrics/histogram.h" | 
|  | 8 #include "base/metrics/sparse_histogram.h" | 
|  | 9 #include "base/strings/stringprintf.h" | 
|  | 10 #include "content/public/browser/resource_request_info.h" | 
|  | 11 #include "net/base/network_change_notifier.h" | 
|  | 12 #include "net/base/upload_data_stream.h" | 
|  | 13 #include "net/http/http_response_headers.h" | 
|  | 14 #include "net/url_request/url_request.h" | 
|  | 15 | 
|  | 16 namespace data_use_measurement { | 
|  | 17 | 
|  | 18 namespace { | 
|  | 19 | 
|  | 20 // Records the occurrence of |sample| in |name| histogram. Conventional UMA | 
|  | 21 // histograms are not used because the |name| is not static. | 
|  | 22 void RecordUMAHistogramCount(const std::string& name, int64_t sample) { | 
|  | 23   base::HistogramBase* histogram_pointer = base::Histogram::FactoryGet( | 
|  | 24       name, | 
|  | 25       1,        // Minimum sample size in bytes. | 
|  | 26       1000000,  // Maximum sample size in bytes. Should cover most of the | 
|  | 27                 // requests by services. | 
|  | 28       50,       // Bucket count. | 
|  | 29       base::HistogramBase::kUmaTargetedHistogramFlag); | 
|  | 30   histogram_pointer->Add(sample); | 
|  | 31 } | 
|  | 32 | 
|  | 33 // This function increases the value of |sample| bucket in |name| sparse | 
|  | 34 // histogram by |value|. Conventional UMA histograms are not used because |name| | 
|  | 35 // is not static. | 
|  | 36 void IncreaseSparseHistogramByValue(const std::string& name, | 
|  | 37                                     int64_t sample, | 
|  | 38                                     int64_t value) { | 
|  | 39   base::HistogramBase* histogram = base::SparseHistogram::FactoryGet( | 
|  | 40       name, base::HistogramBase::kUmaTargetedHistogramFlag); | 
|  | 41   histogram->AddCount(sample, value); | 
|  | 42 } | 
|  | 43 | 
|  | 44 }  // namespace | 
|  | 45 | 
|  | 46 DataUseMeasurement::DataUseMeasurement() | 
|  | 47 #if defined(OS_ANDROID) | 
|  | 48     : app_state_(base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES), | 
|  | 49       app_listener_(new base::android::ApplicationStatusListener( | 
|  | 50           base::Bind(&DataUseMeasurement::OnApplicationStateChange, | 
|  | 51                      base::Unretained(this)))) | 
|  | 52 #endif | 
|  | 53 { | 
|  | 54 } | 
|  | 55 | 
|  | 56 DataUseMeasurement::~DataUseMeasurement(){}; | 
|  | 57 | 
|  | 58 void DataUseMeasurement::ReportDataUseUMA( | 
|  | 59     const net::URLRequest* request) const { | 
|  | 60   const content::ResourceRequestInfo* info = | 
|  | 61       content::ResourceRequestInfo::ForRequest(request); | 
|  | 62   // Having |info| is the sign of a request for a web content from user. For now | 
|  | 63   // we could add a condition to check ProcessType in info is | 
|  | 64   // content::PROCESS_TYPE_RENDERER, but it won't be compatible with upcoming | 
|  | 65   // PlzNavigate architecture. So just existence of |info| is verified, and the | 
|  | 66   // current check should be compatible with upcoming changes in PlzNavigate. | 
|  | 67   bool is_user_traffic = info != nullptr; | 
|  | 68 | 
|  | 69   // Counts rely on URLRequest::GetTotalReceivedBytes() and | 
|  | 70   // URLRequest::GetTotalSentBytes(), which does not include the send path, | 
|  | 71   // network layer overhead, TLS overhead, and DNS. | 
|  | 72   // TODO(amohammadkhan): Make these measured bytes more in line with number of | 
|  | 73   // bytes in lower levels. | 
|  | 74   int64_t total_upload_bytes = request->GetTotalSentBytes(); | 
|  | 75   int64_t total_received_bytes = request->GetTotalReceivedBytes(); | 
|  | 76 | 
|  | 77   RecordUMAHistogramCount( | 
|  | 78       GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" | 
|  | 79                                        : "DataUse.TrafficSize.System", | 
|  | 80                        UPSTREAM), | 
|  | 81       total_upload_bytes); | 
|  | 82   RecordUMAHistogramCount( | 
|  | 83       GetHistogramName(is_user_traffic ? "DataUse.TrafficSize.User" | 
|  | 84                                        : "DataUse.TrafficSize.System", | 
|  | 85                        DOWNSTREAM), | 
|  | 86       total_received_bytes); | 
|  | 87 | 
|  | 88   DataUseUserData* attached_service_data = reinterpret_cast<DataUseUserData*>( | 
|  | 89       request->GetUserData(DataUseUserData::kUserDataKey)); | 
|  | 90 | 
|  | 91   if (!is_user_traffic) { | 
|  | 92     DataUseUserData::ServiceName service_name = | 
|  | 93         attached_service_data ? attached_service_data->service_name() | 
|  | 94                               : DataUseUserData::NOT_TAGGED; | 
|  | 95     ReportDataUsageServices(service_name, UPSTREAM, total_upload_bytes); | 
|  | 96     ReportDataUsageServices(service_name, DOWNSTREAM, total_received_bytes); | 
|  | 97   } | 
|  | 98 } | 
|  | 99 | 
|  | 100 #if defined(OS_ANDROID) | 
|  | 101 void DataUseMeasurement::OnApplicationStateChangeForTesting( | 
|  | 102     base::android::ApplicationState application_state) { | 
|  | 103   app_state_ = application_state; | 
|  | 104 } | 
|  | 105 #endif | 
|  | 106 | 
|  | 107 DataUseMeasurement::AppState DataUseMeasurement::CurrentAppState() const { | 
|  | 108 #if defined(OS_ANDROID) | 
|  | 109   if (app_state_ != base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) | 
|  | 110     return BACKGROUND; | 
|  | 111 #endif | 
|  | 112   // If the OS is not Android, all the requests are considered Foreground. | 
|  | 113   return FOREGROUND; | 
|  | 114 } | 
|  | 115 | 
|  | 116 std::string DataUseMeasurement::GetHistogramName(const char* prefix, | 
|  | 117                                                  TrafficDirection dir) const { | 
|  | 118   AppState app_state = CurrentAppState(); | 
|  | 119   bool is_conn_cellular = net::NetworkChangeNotifier::IsConnectionCellular( | 
|  | 120       net::NetworkChangeNotifier::GetConnectionType()); | 
|  | 121   return base::StringPrintf( | 
|  | 122       "%s.%s.%s.%s", prefix, dir == UPSTREAM ? "Upstream" : "Downstream", | 
|  | 123       app_state == BACKGROUND ? "Background" : "Foreground", | 
|  | 124       is_conn_cellular ? "Cellular" : "NotCellular"); | 
|  | 125 } | 
|  | 126 | 
|  | 127 #if defined(OS_ANDROID) | 
|  | 128 void DataUseMeasurement::OnApplicationStateChange( | 
|  | 129     base::android::ApplicationState application_state) { | 
|  | 130   app_state_ = application_state; | 
|  | 131 } | 
|  | 132 #endif | 
|  | 133 | 
|  | 134 void DataUseMeasurement::ReportDataUsageServices( | 
|  | 135     DataUseUserData::ServiceName service, | 
|  | 136     TrafficDirection dir, | 
|  | 137     int64_t message_size) const { | 
|  | 138   RecordUMAHistogramCount( | 
|  | 139       "DataUse.MessageSize." + DataUseUserData::GetServiceNameAsString(service), | 
|  | 140       message_size); | 
|  | 141   if (message_size > 0) { | 
|  | 142     IncreaseSparseHistogramByValue( | 
|  | 143         GetHistogramName("DataUse.MessageSize.AllServices", dir), service, | 
|  | 144         message_size); | 
|  | 145   } | 
|  | 146 } | 
|  | 147 | 
|  | 148 }  // namespace data_use_measurement | 
| OLD | NEW | 
|---|