Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/android/data_usage/external_data_use_observer.h" | 5 #include "chrome/browser/android/data_usage/external_data_use_observer.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/metrics/field_trial.h" | 11 #include "base/metrics/field_trial.h" |
| 12 #include "base/single_thread_task_runner.h" | 12 #include "base/metrics/histogram_base.h" |
| 13 #include "base/metrics/histogram_macros.h" | |
| 13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 14 #include "chrome/browser/android/data_usage/data_use_tab_model.h" | 15 #include "chrome/browser/android/data_usage/data_use_tab_model.h" |
| 15 #include "chrome/browser/android/data_usage/external_data_use_observer_bridge.h" | 16 #include "chrome/browser/android/data_usage/external_data_use_observer_bridge.h" |
| 16 #include "components/data_usage/core/data_use.h" | 17 #include "components/data_usage/core/data_use.h" |
| 17 #include "components/variations/variations_associated_data.h" | 18 #include "components/variations/variations_associated_data.h" |
| 18 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 19 #include "third_party/re2/re2/re2.h" | 20 #include "third_party/re2/re2/re2.h" |
| 20 #include "url/gurl.h" | 21 #include "url/gurl.h" |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
|
Alexei Svitkine (slow)
2015/12/09 18:15:47
Nit: Move this anon namespace to be inside of chro
tbansal1
2015/12/10 00:41:39
Done.
| |
| 23 | 24 |
| 25 // Record the result of data use report submission. |bytes| is the sum of send | |
| 26 // and received bytes in the report. | |
| 27 void RecordDataUsageReportSubmission( | |
| 28 chrome::android::ExternalDataUseObserver::DataUsageReportSubmissionResult | |
| 29 result, | |
| 30 int64_t bytes) { | |
| 31 DCHECK_LE(0, bytes); | |
| 32 UMA_HISTOGRAM_ENUMERATION("DataUsage.ReportSubmissionResult", result, | |
| 33 chrome::android::ExternalDataUseObserver:: | |
| 34 DATAUSAGE_REPORT_SUBMISSION_MAX); | |
| 35 // Cap to the maximum sample value. | |
| 36 const int32_t bytes_capped = bytes <= base::HistogramBase::kSampleType_MAX - 1 | |
| 37 ? bytes | |
| 38 : base::HistogramBase::kSampleType_MAX - 1; | |
| 39 switch (result) { | |
| 40 case chrome::android::ExternalDataUseObserver:: | |
| 41 DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL: | |
| 42 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Successful.Bytes", | |
| 43 bytes_capped); | |
| 44 break; | |
| 45 case chrome::android::ExternalDataUseObserver:: | |
| 46 DATAUSAGE_REPORT_SUBMISSION_FAILED: | |
| 47 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Failed.Bytes", | |
| 48 bytes_capped); | |
| 49 break; | |
| 50 case chrome::android::ExternalDataUseObserver:: | |
| 51 DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT: | |
| 52 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.TimedOut.Bytes", | |
| 53 bytes_capped); | |
| 54 break; | |
| 55 case chrome::android::ExternalDataUseObserver:: | |
| 56 DATAUSAGE_REPORT_SUBMISSION_LOST: | |
| 57 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Lost.Bytes", | |
| 58 bytes_capped); | |
| 59 break; | |
| 60 default: | |
| 61 NOTIMPLEMENTED(); | |
| 62 break; | |
| 63 } | |
| 64 } | |
| 65 | |
| 24 // Default duration after which matching rules are periodically fetched. May be | 66 // Default duration after which matching rules are periodically fetched. May be |
| 25 // overridden by the field trial. | 67 // overridden by the field trial. |
| 26 const int kDefaultFetchMatchingRulesDurationSeconds = 60 * 15; // 15 minutes. | 68 const int kDefaultFetchMatchingRulesDurationSeconds = 60 * 15; // 15 minutes. |
| 27 | 69 |
| 70 // Default duration after which a pending data use report is considered timed | |
| 71 // out. May be overridden by the field trial. | |
| 72 const int kDefaultDataUseReportSubmitTimeoutMsec = 60 * 2 * 1000; // 2 minutes. | |
| 73 | |
| 28 // Default value of the minimum number of bytes that should be buffered before | 74 // Default value of the minimum number of bytes that should be buffered before |
| 29 // a data use report is submitted. May be overridden by the field trial. | 75 // a data use report is submitted. May be overridden by the field trial. |
| 30 const int64_t kDefaultDataUseReportMinBytes = 100 * 1024; // 100 KB. | 76 const int64_t kDefaultDataUseReportMinBytes = 100 * 1024; // 100 KB. |
| 31 | 77 |
| 32 // Populates various parameters from the values specified in the field trial. | 78 // Populates various parameters from the values specified in the field trial. |
| 33 int32_t GetFetchMatchingRulesDurationSeconds() { | 79 int32_t GetFetchMatchingRulesDurationSeconds() { |
| 34 int32_t duration_seconds = -1; | 80 int32_t duration_seconds = -1; |
| 35 std::string variation_value = variations::GetVariationParamValue( | 81 const std::string variation_value = variations::GetVariationParamValue( |
| 36 chrome::android::ExternalDataUseObserver:: | 82 chrome::android::ExternalDataUseObserver:: |
| 37 kExternalDataUseObserverFieldTrial, | 83 kExternalDataUseObserverFieldTrial, |
| 38 "fetch_matching_rules_duration_seconds"); | 84 "fetch_matching_rules_duration_seconds"); |
| 39 if (!variation_value.empty() && | 85 if (!variation_value.empty() && |
| 40 base::StringToInt(variation_value, &duration_seconds)) { | 86 base::StringToInt(variation_value, &duration_seconds)) { |
| 41 DCHECK_LE(0, duration_seconds); | 87 DCHECK_LE(0, duration_seconds); |
| 42 return duration_seconds; | 88 return duration_seconds; |
| 43 } | 89 } |
| 44 return kDefaultFetchMatchingRulesDurationSeconds; | 90 return kDefaultFetchMatchingRulesDurationSeconds; |
| 45 } | 91 } |
| 46 | 92 |
| 47 // Populates various parameters from the values specified in the field trial. | 93 // Populates various parameters from the values specified in the field trial. |
| 94 int32_t GetDataReportSubmitTimeoutMsec() { | |
| 95 int32_t duration_seconds = -1; | |
| 96 const std::string variation_value = variations::GetVariationParamValue( | |
| 97 chrome::android::ExternalDataUseObserver:: | |
| 98 kExternalDataUseObserverFieldTrial, | |
| 99 "data_report_submit_timeout_msec"); | |
| 100 if (!variation_value.empty() && | |
| 101 base::StringToInt(variation_value, &duration_seconds)) { | |
| 102 DCHECK_LE(0, duration_seconds); | |
| 103 return duration_seconds; | |
| 104 } | |
| 105 return kDefaultDataUseReportSubmitTimeoutMsec; | |
| 106 } | |
| 107 | |
| 108 // Populates various parameters from the values specified in the field trial. | |
| 48 int64_t GetMinBytes() { | 109 int64_t GetMinBytes() { |
| 49 int64_t min_bytes = -1; | 110 int64_t min_bytes = -1; |
| 50 std::string variation_value = variations::GetVariationParamValue( | 111 const std::string variation_value = variations::GetVariationParamValue( |
| 51 chrome::android::ExternalDataUseObserver:: | 112 chrome::android::ExternalDataUseObserver:: |
| 52 kExternalDataUseObserverFieldTrial, | 113 kExternalDataUseObserverFieldTrial, |
| 53 "data_use_report_min_bytes"); | 114 "data_use_report_min_bytes"); |
| 54 if (!variation_value.empty() && | 115 if (!variation_value.empty() && |
| 55 base::StringToInt64(variation_value, &min_bytes)) { | 116 base::StringToInt64(variation_value, &min_bytes)) { |
| 56 DCHECK_LE(0, min_bytes); | 117 DCHECK_LE(0, min_bytes); |
| 57 return min_bytes; | 118 return min_bytes; |
| 58 } | 119 } |
| 59 return kDefaultDataUseReportMinBytes; | 120 return kDefaultDataUseReportMinBytes; |
| 60 } | 121 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 71 | 132 |
| 72 // static | 133 // static |
| 73 const size_t ExternalDataUseObserver::kMaxBufferSize = 100; | 134 const size_t ExternalDataUseObserver::kMaxBufferSize = 100; |
| 74 | 135 |
| 75 ExternalDataUseObserver::ExternalDataUseObserver( | 136 ExternalDataUseObserver::ExternalDataUseObserver( |
| 76 data_usage::DataUseAggregator* data_use_aggregator, | 137 data_usage::DataUseAggregator* data_use_aggregator, |
| 77 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, | 138 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, |
| 78 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) | 139 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) |
| 79 : data_use_aggregator_(data_use_aggregator), | 140 : data_use_aggregator_(data_use_aggregator), |
| 80 matching_rules_fetch_pending_(false), | 141 matching_rules_fetch_pending_(false), |
| 81 submit_data_report_pending_(false), | 142 last_data_report_submitted_ticks_(base::TimeTicks()), |
| 143 pending_report_bytes_(0), | |
| 82 registered_as_observer_(false), | 144 registered_as_observer_(false), |
| 83 ui_task_runner_(ui_task_runner), | 145 ui_task_runner_(ui_task_runner), |
| 84 previous_report_time_(base::Time::Now()), | 146 previous_report_time_(base::Time::Now()), |
| 85 last_matching_rules_fetch_time_(base::TimeTicks::Now()), | 147 last_matching_rules_fetch_time_(base::TimeTicks::Now()), |
| 86 external_data_use_observer_bridge_(new ExternalDataUseObserverBridge()), | 148 external_data_use_observer_bridge_(new ExternalDataUseObserverBridge()), |
| 87 total_bytes_buffered_(0), | 149 total_bytes_buffered_(0), |
| 88 fetch_matching_rules_duration_( | 150 fetch_matching_rules_duration_( |
| 89 base::TimeDelta::FromSeconds(GetFetchMatchingRulesDurationSeconds())), | 151 base::TimeDelta::FromSeconds(GetFetchMatchingRulesDurationSeconds())), |
| 90 data_use_report_min_bytes_(GetMinBytes()), | 152 data_use_report_min_bytes_(GetMinBytes()), |
| 153 data_report_submit_timeout_( | |
| 154 base::TimeDelta::FromMilliseconds(GetDataReportSubmitTimeoutMsec())), | |
| 91 weak_factory_(this) { | 155 weak_factory_(this) { |
| 92 DCHECK(data_use_aggregator_); | 156 DCHECK(data_use_aggregator_); |
| 93 DCHECK(io_task_runner); | 157 DCHECK(io_task_runner); |
| 94 DCHECK(ui_task_runner_); | 158 DCHECK(ui_task_runner_); |
| 159 DCHECK(last_data_report_submitted_ticks_.is_null()); | |
| 95 | 160 |
| 96 // Initialize the ExternalDataUseObserverBridge object. Initialization will | 161 // Initialize the ExternalDataUseObserverBridge object. Initialization will |
| 97 // also trigger the fetching of matching rules. It is okay to use | 162 // also trigger the fetching of matching rules. It is okay to use |
| 98 // base::Unretained here since |external_data_use_observer_bridge_| is | 163 // base::Unretained here since |external_data_use_observer_bridge_| is |
| 99 // owned by |this|, and is destroyed on UI thread when |this| is destroyed. | 164 // owned by |this|, and is destroyed on UI thread when |this| is destroyed. |
| 100 ui_task_runner_->PostTask( | 165 ui_task_runner_->PostTask( |
| 101 FROM_HERE, | 166 FROM_HERE, |
| 102 base::Bind(&ExternalDataUseObserverBridge::Init, | 167 base::Bind(&ExternalDataUseObserverBridge::Init, |
| 103 base::Unretained(external_data_use_observer_bridge_), | 168 base::Unretained(external_data_use_observer_bridge_), |
| 104 io_task_runner, GetWeakPtr())); | 169 io_task_runner, GetWeakPtr())); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 131 const std::vector<std::string>* label) { | 196 const std::vector<std::string>* label) { |
| 132 DCHECK(thread_checker_.CalledOnValidThread()); | 197 DCHECK(thread_checker_.CalledOnValidThread()); |
| 133 | 198 |
| 134 RegisterURLRegexes(app_package_name, domain_path_regex, label); | 199 RegisterURLRegexes(app_package_name, domain_path_regex, label); |
| 135 matching_rules_fetch_pending_ = false; | 200 matching_rules_fetch_pending_ = false; |
| 136 // Process buffered reports. | 201 // Process buffered reports. |
| 137 } | 202 } |
| 138 | 203 |
| 139 void ExternalDataUseObserver::OnReportDataUseDone(bool success) { | 204 void ExternalDataUseObserver::OnReportDataUseDone(bool success) { |
| 140 DCHECK(thread_checker_.CalledOnValidThread()); | 205 DCHECK(thread_checker_.CalledOnValidThread()); |
| 141 DCHECK(submit_data_report_pending_); | 206 DCHECK(!last_data_report_submitted_ticks_.is_null()); |
| 142 | 207 |
| 143 // TODO(tbansal): If not successful, record UMA. | 208 if (success) { |
| 209 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL, | |
| 210 pending_report_bytes_); | |
| 211 } else { | |
| 212 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_FAILED, | |
| 213 pending_report_bytes_); | |
| 214 } | |
| 144 | 215 |
| 145 submit_data_report_pending_ = false; | 216 last_data_report_submitted_ticks_ = base::TimeTicks(); |
| 217 pending_report_bytes_ = 0; | |
| 146 | 218 |
| 147 SubmitBufferedDataUseReport(); | 219 SubmitBufferedDataUseReport(); |
| 148 } | 220 } |
| 149 | 221 |
| 150 void ExternalDataUseObserver::OnDataUse(const data_usage::DataUse& data_use) { | 222 void ExternalDataUseObserver::OnDataUse(const data_usage::DataUse& data_use) { |
| 151 DCHECK(thread_checker_.CalledOnValidThread()); | 223 DCHECK(thread_checker_.CalledOnValidThread()); |
| 152 const base::TimeTicks now_ticks = base::TimeTicks::Now(); | 224 const base::TimeTicks now_ticks = base::TimeTicks::Now(); |
| 153 const base::Time now_time = base::Time::Now(); | 225 const base::Time now_time = base::Time::Now(); |
| 154 | 226 |
| 155 // If the time when the matching rules were last fetched is more than | 227 // If the time when the matching rules were last fetched is more than |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 182 | 254 |
| 183 void ExternalDataUseObserver::BufferDataUseReport( | 255 void ExternalDataUseObserver::BufferDataUseReport( |
| 184 const data_usage::DataUse& data_use, | 256 const data_usage::DataUse& data_use, |
| 185 const std::string& label, | 257 const std::string& label, |
| 186 const base::Time& start_time, | 258 const base::Time& start_time, |
| 187 const base::Time& end_time) { | 259 const base::Time& end_time) { |
| 188 DCHECK(thread_checker_.CalledOnValidThread()); | 260 DCHECK(thread_checker_.CalledOnValidThread()); |
| 189 DCHECK(!label.empty()); | 261 DCHECK(!label.empty()); |
| 190 DCHECK_LE(0, data_use.rx_bytes); | 262 DCHECK_LE(0, data_use.rx_bytes); |
| 191 DCHECK_LE(0, data_use.tx_bytes); | 263 DCHECK_LE(0, data_use.tx_bytes); |
| 192 if (data_use.rx_bytes < 0 || data_use.tx_bytes < 0) | 264 // Skip if the |data_use| does not report any network traffic. |
| 265 if (data_use.rx_bytes == 0 && data_use.tx_bytes == 0) | |
| 193 return; | 266 return; |
| 194 | 267 |
| 195 DataUseReportKey data_use_report_key = | 268 DataUseReportKey data_use_report_key = |
| 196 DataUseReportKey(label, data_use.connection_type, data_use.mcc_mnc); | 269 DataUseReportKey(label, data_use.connection_type, data_use.mcc_mnc); |
| 197 | 270 |
| 198 DataUseReport report = | 271 DataUseReport report = |
| 199 DataUseReport(start_time, end_time, data_use.rx_bytes, data_use.tx_bytes); | 272 DataUseReport(start_time, end_time, data_use.rx_bytes, data_use.tx_bytes); |
| 200 | 273 |
| 201 // Check if the |data_use_report_key| is already in the buffered reports. | 274 // Check if the |data_use_report_key| is already in the buffered reports. |
| 202 DataUseReports::iterator it = | 275 DataUseReports::iterator it = |
| 203 buffered_data_reports_.find(data_use_report_key); | 276 buffered_data_reports_.find(data_use_report_key); |
| 204 if (it == buffered_data_reports_.end()) { | 277 if (it == buffered_data_reports_.end()) { |
| 205 // Limit the buffer size. | 278 // Limit the buffer size. |
| 206 if (buffered_data_reports_.size() == kMaxBufferSize) { | 279 if (buffered_data_reports_.size() == kMaxBufferSize) { |
| 207 // TODO(tbansal): Add UMA to track impact of lost reports. | 280 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_LOST, |
| 281 data_use.rx_bytes + data_use.tx_bytes); | |
| 208 return; | 282 return; |
| 209 } | 283 } |
| 210 buffered_data_reports_.insert(std::make_pair(data_use_report_key, report)); | 284 buffered_data_reports_.insert(std::make_pair(data_use_report_key, report)); |
| 211 } else { | 285 } else { |
| 212 DataUseReport existing_report = DataUseReport(it->second); | 286 DataUseReport existing_report = DataUseReport(it->second); |
| 213 DataUseReport merged_report = DataUseReport( | 287 DataUseReport merged_report = DataUseReport( |
| 214 std::min(existing_report.start_time, report.start_time), | 288 std::min(existing_report.start_time, report.start_time), |
| 215 std::max(existing_report.end_time, report.end_time), | 289 std::max(existing_report.end_time, report.end_time), |
| 216 existing_report.bytes_downloaded + report.bytes_downloaded, | 290 existing_report.bytes_downloaded + report.bytes_downloaded, |
| 217 existing_report.bytes_uploaded + report.bytes_uploaded); | 291 existing_report.bytes_uploaded + report.bytes_uploaded); |
| 218 buffered_data_reports_.erase(it); | 292 buffered_data_reports_.erase(it); |
| 219 buffered_data_reports_.insert( | 293 buffered_data_reports_.insert( |
| 220 std::make_pair(data_use_report_key, merged_report)); | 294 std::make_pair(data_use_report_key, merged_report)); |
| 221 } | 295 } |
| 222 total_bytes_buffered_ += (data_use.rx_bytes + data_use.tx_bytes); | 296 total_bytes_buffered_ += (data_use.rx_bytes + data_use.tx_bytes); |
| 223 | 297 |
| 298 DCHECK_LT(0U, buffered_data_reports_.size()); | |
| 224 DCHECK_LE(buffered_data_reports_.size(), kMaxBufferSize); | 299 DCHECK_LE(buffered_data_reports_.size(), kMaxBufferSize); |
| 225 } | 300 } |
| 226 | 301 |
| 227 void ExternalDataUseObserver::SubmitBufferedDataUseReport() { | 302 void ExternalDataUseObserver::SubmitBufferedDataUseReport() { |
| 228 DCHECK(thread_checker_.CalledOnValidThread()); | 303 DCHECK(thread_checker_.CalledOnValidThread()); |
| 229 | 304 |
| 230 if (submit_data_report_pending_ || buffered_data_reports_.empty()) | 305 const base::TimeTicks ticks_now = base::TimeTicks::Now(); |
| 306 | |
| 307 // Return if a data use report has been pending for less than | |
| 308 // |data_report_submit_timeout_| duration. | |
| 309 if (!last_data_report_submitted_ticks_.is_null() && | |
| 310 ticks_now - last_data_report_submitted_ticks_ < | |
| 311 data_report_submit_timeout_) { | |
| 312 return; | |
| 313 } | |
| 314 | |
| 315 if (buffered_data_reports_.empty()) | |
| 231 return; | 316 return; |
| 232 | 317 |
| 233 if (total_bytes_buffered_ < data_use_report_min_bytes_) | 318 if (total_bytes_buffered_ < data_use_report_min_bytes_) |
| 234 return; | 319 return; |
| 235 | 320 |
| 321 if (!last_data_report_submitted_ticks_.is_null()) { | |
| 322 // Mark the pending DataUsage report as timed out. | |
| 323 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT, | |
| 324 pending_report_bytes_); | |
| 325 pending_report_bytes_ = 0; | |
| 326 last_data_report_submitted_ticks_ = base::TimeTicks(); | |
| 327 } | |
| 328 | |
| 236 // Send one data use report. | 329 // Send one data use report. |
| 237 DataUseReports::iterator it = buffered_data_reports_.begin(); | 330 DataUseReports::iterator it = buffered_data_reports_.begin(); |
| 238 DataUseReportKey key = it->first; | 331 DataUseReportKey key = it->first; |
| 239 DataUseReport report = it->second; | 332 DataUseReport report = it->second; |
| 240 | 333 |
| 334 DCHECK_EQ(0, pending_report_bytes_); | |
| 335 DCHECK(last_data_report_submitted_ticks_.is_null()); | |
| 336 pending_report_bytes_ = report.bytes_downloaded + report.bytes_uploaded; | |
| 337 last_data_report_submitted_ticks_ = ticks_now; | |
| 338 | |
| 241 // Remove the entry from the map. | 339 // Remove the entry from the map. |
| 242 buffered_data_reports_.erase(it); | 340 buffered_data_reports_.erase(it); |
| 243 total_bytes_buffered_ -= (report.bytes_downloaded + report.bytes_uploaded); | 341 total_bytes_buffered_ -= (report.bytes_downloaded + report.bytes_uploaded); |
| 244 | 342 |
| 245 submit_data_report_pending_ = true; | |
| 246 | |
| 247 // It is okay to use base::Unretained here since | 343 // It is okay to use base::Unretained here since |
| 248 // |external_data_use_observer_bridge_| is owned by |this|, and is destroyed | 344 // |external_data_use_observer_bridge_| is owned by |this|, and is destroyed |
| 249 // on UI thread when |this| is destroyed. | 345 // on UI thread when |this| is destroyed. |
| 250 ui_task_runner_->PostTask( | 346 ui_task_runner_->PostTask( |
| 251 FROM_HERE, | 347 FROM_HERE, |
| 252 base::Bind(&ExternalDataUseObserverBridge::ReportDataUse, | 348 base::Bind(&ExternalDataUseObserverBridge::ReportDataUse, |
| 253 base::Unretained(external_data_use_observer_bridge_), | 349 base::Unretained(external_data_use_observer_bridge_), |
| 254 key.label, key.connection_type, key.mcc_mnc, report.start_time, | 350 key.label, key.connection_type, key.mcc_mnc, report.start_time, |
| 255 report.end_time, report.bytes_downloaded, | 351 report.end_time, report.bytes_downloaded, |
| 256 report.bytes_uploaded)); | 352 report.bytes_uploaded)); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 return app_package_name_; | 503 return app_package_name_; |
| 408 } | 504 } |
| 409 | 505 |
| 410 const std::string& ExternalDataUseObserver::MatchingRule::label() const { | 506 const std::string& ExternalDataUseObserver::MatchingRule::label() const { |
| 411 return label_; | 507 return label_; |
| 412 } | 508 } |
| 413 | 509 |
| 414 } // namespace android | 510 } // namespace android |
| 415 | 511 |
| 416 } // namespace chrome | 512 } // namespace chrome |
| OLD | NEW |