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

Side by Side Diff: chrome/browser/android/data_usage/external_data_use_reporter.cc

Issue 2145863002: Separate data use reporting logic in ExternalDataUseObserver (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed nits Created 4 years, 5 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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_reporter.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/containers/hash_tables.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/metrics/field_trial.h" 9 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram_base.h" 10 #include "base/metrics/histogram_base.h"
13 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
16 #include "base/task_runner_util.h" 13 #include "chrome/browser/android/data_usage/data_use_tab_model.h"
17 #include "chrome/browser/android/data_usage/external_data_use_observer_bridge.h" 14 #include "chrome/browser/android/data_usage/external_data_use_observer_bridge.h"
18 #include "components/data_usage/core/data_use.h" 15 #include "components/data_usage/core/data_use.h"
19 #include "components/variations/variations_associated_data.h" 16 #include "components/variations/variations_associated_data.h"
20 #include "content/public/browser/browser_thread.h"
21 17
22 namespace chrome { 18 namespace chrome {
23 19
24 namespace android { 20 namespace android {
25 21
26 namespace { 22 namespace {
27 23
24 // Default duration after which a pending data use report is considered timed
25 // out. May be overridden by the field trial.
26 const int kDefaultDataUseReportSubmitTimeoutMsec = 60 * 2 * 1000; // 2 minutes.
27
28 // 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.
30 const int64_t kDefaultDataUseReportMinBytes = 100 * 1024; // 100 KB.
31
28 // Record the result of data use report submission. |bytes| is the sum of send 32 // Record the result of data use report submission. |bytes| is the sum of send
29 // and received bytes in the report. 33 // and received bytes in the report.
30 void RecordDataUsageReportSubmission( 34 void RecordDataUsageReportSubmission(
31 ExternalDataUseObserver::DataUsageReportSubmissionResult result, 35 ExternalDataUseReporter::DataUsageReportSubmissionResult result,
32 int64_t bytes) { 36 int64_t bytes) {
33 DCHECK_LE(0, bytes); 37 DCHECK_LE(0, bytes);
34 UMA_HISTOGRAM_ENUMERATION( 38 UMA_HISTOGRAM_ENUMERATION(
35 "DataUsage.ReportSubmissionResult", result, 39 "DataUsage.ReportSubmissionResult", result,
36 ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_MAX); 40 ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_MAX);
37 // Cap to the maximum sample value. 41 // Cap to the maximum sample value.
38 const int32_t bytes_capped = bytes <= base::HistogramBase::kSampleType_MAX - 1 42 const int32_t bytes_capped = bytes <= base::HistogramBase::kSampleType_MAX - 1
39 ? bytes 43 ? bytes
40 : base::HistogramBase::kSampleType_MAX - 1; 44 : base::HistogramBase::kSampleType_MAX - 1;
41 switch (result) { 45 switch (result) {
42 case ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL: 46 case ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL:
43 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.Successful", 47 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.Successful",
44 bytes_capped); 48 bytes_capped);
45 break; 49 break;
46 case ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_FAILED: 50 case ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_FAILED:
47 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.Failed", 51 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.Failed",
48 bytes_capped); 52 bytes_capped);
49 break; 53 break;
50 case ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT: 54 case ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_TIMED_OUT:
51 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.TimedOut", 55 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.TimedOut",
52 bytes_capped); 56 bytes_capped);
53 break; 57 break;
54 case ExternalDataUseObserver::DATAUSAGE_REPORT_SUBMISSION_LOST: 58 case ExternalDataUseReporter::DATAUSAGE_REPORT_SUBMISSION_LOST:
55 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.Lost", 59 UMA_HISTOGRAM_COUNTS("DataUsage.ReportSubmission.Bytes.Lost",
56 bytes_capped); 60 bytes_capped);
57 break; 61 break;
58 default: 62 default:
59 NOTIMPLEMENTED(); 63 NOTIMPLEMENTED();
60 break; 64 break;
61 } 65 }
62 } 66 }
63 67
64 // Default duration after which matching rules are periodically fetched. May be 68 // Populates various parameters from the values specified in the field trial
65 // overridden by the field trial. 69 // |field_trial|.
66 const int kDefaultFetchMatchingRulesDurationSeconds = 60 * 15; // 15 minutes. 70 int32_t GetDataReportSubmitTimeoutMsec(const char* field_trial) {
67
68 // Default duration after which a pending data use report is considered timed
69 // out. May be overridden by the field trial.
70 const int kDefaultDataUseReportSubmitTimeoutMsec = 60 * 2 * 1000; // 2 minutes.
71
72 // Default value of the minimum number of bytes that should be buffered before
73 // a data use report is submitted. May be overridden by the field trial.
74 const int64_t kDefaultDataUseReportMinBytes = 100 * 1024; // 100 KB.
75
76 // Populates various parameters from the values specified in the field trial.
77 int32_t GetFetchMatchingRulesDurationSeconds() {
78 int32_t duration_seconds = -1; 71 int32_t duration_seconds = -1;
79 const std::string variation_value = variations::GetVariationParamValue( 72 const std::string variation_value = variations::GetVariationParamValue(
80 chrome::android::ExternalDataUseObserver:: 73 field_trial, "data_report_submit_timeout_msec");
81 kExternalDataUseObserverFieldTrial,
82 "fetch_matching_rules_duration_seconds");
83 if (!variation_value.empty() && 74 if (!variation_value.empty() &&
84 base::StringToInt(variation_value, &duration_seconds)) { 75 base::StringToInt(variation_value, &duration_seconds)) {
85 DCHECK_LE(0, duration_seconds); 76 DCHECK_LE(0, duration_seconds);
86 return duration_seconds;
87 }
88 return kDefaultFetchMatchingRulesDurationSeconds;
89 }
90
91 // Populates various parameters from the values specified in the field trial.
92 int32_t GetDataReportSubmitTimeoutMsec() {
93 int32_t duration_seconds = -1;
94 const std::string variation_value = variations::GetVariationParamValue(
95 chrome::android::ExternalDataUseObserver::
96 kExternalDataUseObserverFieldTrial,
97 "data_report_submit_timeout_msec");
98 if (!variation_value.empty() &&
99 base::StringToInt(variation_value, &duration_seconds)) {
100 DCHECK_LE(0, duration_seconds);
101 return duration_seconds; 77 return duration_seconds;
102 } 78 }
103 return kDefaultDataUseReportSubmitTimeoutMsec; 79 return kDefaultDataUseReportSubmitTimeoutMsec;
104 } 80 }
105 81
106 // Populates various parameters from the values specified in the field trial. 82 // Populates various parameters from the values specified in the field trial
107 int64_t GetMinBytes() { 83 // |field_trial|.
84 int64_t GetMinBytes(const char* field_trial) {
108 int64_t min_bytes = -1; 85 int64_t min_bytes = -1;
109 const std::string variation_value = variations::GetVariationParamValue( 86 const std::string variation_value = variations::GetVariationParamValue(
110 chrome::android::ExternalDataUseObserver:: 87 field_trial, "data_use_report_min_bytes");
111 kExternalDataUseObserverFieldTrial,
112 "data_use_report_min_bytes");
113 if (!variation_value.empty() && 88 if (!variation_value.empty() &&
114 base::StringToInt64(variation_value, &min_bytes)) { 89 base::StringToInt64(variation_value, &min_bytes)) {
115 DCHECK_LE(0, min_bytes); 90 DCHECK_LE(0, min_bytes);
116 return min_bytes; 91 return min_bytes;
117 } 92 }
118 return kDefaultDataUseReportMinBytes; 93 return kDefaultDataUseReportMinBytes;
119 } 94 }
120 95
121 } // namespace 96 } // namespace
122 97
123 // static 98 // static
124 const char ExternalDataUseObserver::kExternalDataUseObserverFieldTrial[] = 99 const size_t ExternalDataUseReporter::kMaxBufferSize = 100;
125 "ExternalDataUseObserver";
126 100
127 // static 101 ExternalDataUseReporter::ExternalDataUseReporter(
128 const size_t ExternalDataUseObserver::kMaxBufferSize = 100; 102 const char* field_trial,
129 103 DataUseTabModel* data_use_tab_model,
130 ExternalDataUseObserver::ExternalDataUseObserver( 104 ExternalDataUseObserverBridge* external_data_use_observer_bridge)
131 data_usage::DataUseAggregator* data_use_aggregator, 105 : external_data_use_observer_bridge_(external_data_use_observer_bridge),
132 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, 106 data_use_tab_model_(data_use_tab_model),
133 const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
134 : data_use_aggregator_(data_use_aggregator),
135 external_data_use_observer_bridge_(new ExternalDataUseObserverBridge()),
136 data_use_tab_model_(new DataUseTabModel()),
137 last_data_report_submitted_ticks_(base::TimeTicks()), 107 last_data_report_submitted_ticks_(base::TimeTicks()),
138 pending_report_bytes_(0), 108 pending_report_bytes_(0),
139 ui_task_runner_(ui_task_runner),
140 previous_report_time_(base::Time::Now()), 109 previous_report_time_(base::Time::Now()),
141 last_matching_rules_fetch_time_(base::TimeTicks::Now()),
142 total_bytes_buffered_(0), 110 total_bytes_buffered_(0),
143 fetch_matching_rules_duration_( 111 data_use_report_min_bytes_(GetMinBytes(field_trial)),
144 base::TimeDelta::FromSeconds(GetFetchMatchingRulesDurationSeconds())), 112 data_report_submit_timeout_(base::TimeDelta::FromMilliseconds(
145 data_use_report_min_bytes_(GetMinBytes()), 113 GetDataReportSubmitTimeoutMsec(field_trial))) {
146 data_report_submit_timeout_(
147 base::TimeDelta::FromMilliseconds(GetDataReportSubmitTimeoutMsec())),
148 #if defined(OS_ANDROID)
149 app_state_listener_(new base::android::ApplicationStatusListener(
150 base::Bind(&ExternalDataUseObserver::OnApplicationStateChange,
151 base::Unretained(this)))),
152 #endif
153 registered_as_data_use_observer_(false),
154 weak_factory_(this) {
155 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
156 DCHECK(data_use_aggregator_);
157 DCHECK(io_task_runner);
158 DCHECK(ui_task_runner_);
159 DCHECK(last_data_report_submitted_ticks_.is_null()); 114 DCHECK(last_data_report_submitted_ticks_.is_null());
160 115 // Detach from current thread since rest of ExternalDataUseReporter lives on
161 ui_task_runner_->PostTask(FROM_HERE, 116 // the UI thread and the current thread may not be UI thread..
162 base::Bind(&DataUseTabModel::InitOnUIThread, 117 thread_checker_.DetachFromThread();
163 base::Unretained(data_use_tab_model_),
164 external_data_use_observer_bridge_));
165
166 // Initialize the ExternalDataUseObserverBridge object. It is okay to use
167 // base::Unretained here since |external_data_use_observer_bridge_| is owned
168 // by |this|, and is destroyed on UI thread when |this| is destroyed.
169 ui_task_runner_->PostTask(
170 FROM_HERE,
171 base::Bind(&ExternalDataUseObserverBridge::Init,
172 base::Unretained(external_data_use_observer_bridge_),
173 io_task_runner, GetWeakPtr(), data_use_tab_model_));
174 } 118 }
175 119
176 ExternalDataUseObserver::~ExternalDataUseObserver() { 120 void ExternalDataUseReporter::InitOnUIThread() {
121 DCHECK(thread_checker_.CalledOnValidThread());
122 #if defined(OS_ANDROID)
123 app_state_listener_.reset(new base::android::ApplicationStatusListener(
124 base::Bind(&ExternalDataUseReporter::OnApplicationStateChange,
125 base::Unretained(this))));
126 #endif
127 }
128
129 ExternalDataUseReporter::~ExternalDataUseReporter() {
130 DCHECK(thread_checker_.CalledOnValidThread());
131 }
132
133 void ExternalDataUseReporter::OnDataUse(const data_usage::DataUse& data_use) {
177 DCHECK(thread_checker_.CalledOnValidThread()); 134 DCHECK(thread_checker_.CalledOnValidThread());
178 135
179 if (registered_as_data_use_observer_) 136 const base::Time now_time = base::Time::Now();
180 data_use_aggregator_->RemoveObserver(this); 137 DataUseTabModel::TrackingInfo tracking_info;
181 138
182 // Delete |data_use_tab_model_| on the UI thread. |data_use_tab_model_| should 139 if (!data_use_tab_model_->GetTrackingInfoForTabAtTime(
183 // be deleted before |external_data_use_observer_bridge_|. 140 data_use.tab_id, data_use.request_start, &tracking_info)) {
184 if (!ui_task_runner_->DeleteSoon(FROM_HERE, data_use_tab_model_)) { 141 return;
185 NOTIMPLEMENTED() << " DataUseTabModel was not deleted successfully";
186 } 142 }
187 143
188 // Delete |external_data_use_observer_bridge_| on the UI thread. 144 BufferDataUseReport(data_use, tracking_info.label, tracking_info.tag,
189 if (!ui_task_runner_->DeleteSoon(FROM_HERE, 145 previous_report_time_, now_time);
190 external_data_use_observer_bridge_)) { 146 SubmitBufferedDataUseReport(false);
191 NOTIMPLEMENTED() 147 previous_report_time_ = now_time;
192 << " ExternalDataUseObserverBridge was not deleted successfully";
193 }
194 } 148 }
195 149
196 void ExternalDataUseObserver::OnReportDataUseDone(bool success) { 150 void ExternalDataUseReporter::OnReportDataUseDone(bool success) {
197 DCHECK(thread_checker_.CalledOnValidThread()); 151 DCHECK(thread_checker_.CalledOnValidThread());
198 DCHECK(!last_data_report_submitted_ticks_.is_null()); 152 DCHECK(!last_data_report_submitted_ticks_.is_null());
199 153
200 if (success) { 154 if (success) {
201 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL, 155 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_SUCCESSFUL,
202 pending_report_bytes_); 156 pending_report_bytes_);
203 } else { 157 } else {
204 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_FAILED, 158 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_FAILED,
205 pending_report_bytes_); 159 pending_report_bytes_);
206 } 160 }
207 UMA_HISTOGRAM_TIMES( 161 UMA_HISTOGRAM_TIMES(
208 "DataUsage.Perf.ReportSubmissionDuration", 162 "DataUsage.Perf.ReportSubmissionDuration",
209 base::TimeTicks::Now() - last_data_report_submitted_ticks_); 163 base::TimeTicks::Now() - last_data_report_submitted_ticks_);
210 164
211 last_data_report_submitted_ticks_ = base::TimeTicks(); 165 last_data_report_submitted_ticks_ = base::TimeTicks();
212 pending_report_bytes_ = 0; 166 pending_report_bytes_ = 0;
213 167
214 SubmitBufferedDataUseReport(false); 168 SubmitBufferedDataUseReport(false);
215 } 169 }
216 170
217 #if defined(OS_ANDROID) 171 #if defined(OS_ANDROID)
218 void ExternalDataUseObserver::OnApplicationStateChange( 172 void ExternalDataUseReporter::OnApplicationStateChange(
219 base::android::ApplicationState new_state) { 173 base::android::ApplicationState new_state) {
220 DCHECK(thread_checker_.CalledOnValidThread()); 174 DCHECK(thread_checker_.CalledOnValidThread());
175
176 // TODO(rajendrant): When Chromium is backgrounded, only one data use report
177 // is submitted since the external API only supports one pending report
178 // submission. Once the external API supports submitting multiple reports
179 // in one call, all reports should be submitted immediately.
221 if (new_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES) 180 if (new_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES)
222 SubmitBufferedDataUseReport(true); 181 SubmitBufferedDataUseReport(true);
223 } 182 }
224 #endif 183 #endif
225 184
226 void ExternalDataUseObserver::OnDataUse(const data_usage::DataUse& data_use) { 185 void ExternalDataUseReporter::BufferDataUseReport(
227 DCHECK(thread_checker_.CalledOnValidThread());
228 DCHECK(registered_as_data_use_observer_);
229
230 const base::TimeTicks now_ticks = base::TimeTicks::Now();
231 const base::Time now_time = base::Time::Now();
232
233 // If the time when the matching rules were last fetched is more than
234 // |fetch_matching_rules_duration_|, fetch them again.
235 if (now_ticks - last_matching_rules_fetch_time_ >=
236 fetch_matching_rules_duration_) {
237 FetchMatchingRules();
238 }
239
240 std::unique_ptr<DataUseTabModel::TrackingInfo> tracking_info(
241 new DataUseTabModel::TrackingInfo());
242
243 content::BrowserThread::PostTaskAndReplyWithResult(
244 content::BrowserThread::UI, FROM_HERE,
245 base::Bind(&DataUseTabModel::GetTrackingInfoForTabAtTime,
246 base::Unretained(data_use_tab_model_), data_use.tab_id,
247 data_use.request_start, tracking_info.get()),
248 base::Bind(&ExternalDataUseObserver::DataUseTrackingInfoRetrieved,
249 GetWeakPtr(), data_use, previous_report_time_, now_time,
250 base::Owned(tracking_info.release())));
251
252 previous_report_time_ = now_time;
253 }
254
255 void ExternalDataUseObserver::ShouldRegisterAsDataUseObserver(
256 bool should_register) {
257 DCHECK(thread_checker_.CalledOnValidThread());
258 if (registered_as_data_use_observer_ == should_register)
259 return;
260
261 if (!registered_as_data_use_observer_ && should_register)
262 data_use_aggregator_->AddObserver(this);
263
264 if (registered_as_data_use_observer_ && !should_register)
265 data_use_aggregator_->RemoveObserver(this);
266
267 registered_as_data_use_observer_ = should_register;
268 }
269
270 void ExternalDataUseObserver::FetchMatchingRules() {
271 DCHECK(thread_checker_.CalledOnValidThread());
272
273 last_matching_rules_fetch_time_ = base::TimeTicks::Now();
274
275 // It is okay to use base::Unretained here since
276 // |external_data_use_observer_bridge_| is owned by |this|, and is destroyed
277 // on UI thread when |this| is destroyed.
278 ui_task_runner_->PostTask(
279 FROM_HERE,
280 base::Bind(&ExternalDataUseObserverBridge::FetchMatchingRules,
281 base::Unretained(external_data_use_observer_bridge_)));
282 }
283
284 void ExternalDataUseObserver::DataUseTrackingInfoRetrieved(
285 const data_usage::DataUse& data_use,
286 const base::Time& start_time,
287 const base::Time& end_time,
288 const DataUseTabModel::TrackingInfo* tracking_info,
289 bool tracking_info_valid) {
290 DCHECK(thread_checker_.CalledOnValidThread());
291
292 if (!tracking_info_valid)
293 return;
294
295 BufferDataUseReport(data_use, tracking_info->label, tracking_info->tag,
296 start_time, end_time);
297 SubmitBufferedDataUseReport(false);
298 }
299
300 void ExternalDataUseObserver::BufferDataUseReport(
301 const data_usage::DataUse& data_use, 186 const data_usage::DataUse& data_use,
302 const std::string& label, 187 const std::string& label,
303 const std::string& tag, 188 const std::string& tag,
304 const base::Time& start_time, 189 const base::Time& start_time,
305 const base::Time& end_time) { 190 const base::Time& end_time) {
306 DCHECK(thread_checker_.CalledOnValidThread()); 191 DCHECK(thread_checker_.CalledOnValidThread());
307 DCHECK(!label.empty()); 192 DCHECK(!label.empty());
308 DCHECK_LE(0, data_use.rx_bytes); 193 DCHECK_LE(0, data_use.rx_bytes);
309 DCHECK_LE(0, data_use.tx_bytes); 194 DCHECK_LE(0, data_use.tx_bytes);
310 // Skip if the |data_use| does not report any network traffic. 195 // Skip if the |data_use| does not report any network traffic.
311 if (data_use.rx_bytes == 0 && data_use.tx_bytes == 0) 196 if (data_use.rx_bytes == 0 && data_use.tx_bytes == 0)
312 return; 197 return;
313 198
314 DataUseReportKey data_use_report_key = 199 DataUseReportKey data_use_report_key =
315 DataUseReportKey(label, tag, data_use.connection_type, data_use.mcc_mnc); 200 DataUseReportKey(label, tag, data_use.connection_type, data_use.mcc_mnc);
316 201
317 DataUseReport report = 202 DataUseReport report =
318 DataUseReport(start_time, end_time, data_use.rx_bytes, data_use.tx_bytes); 203 DataUseReport(start_time, end_time, data_use.rx_bytes, data_use.tx_bytes);
319 204
320 // Check if the |data_use_report_key| is already in the buffered reports. 205 // Check if the |data_use_report_key| is already in the buffered reports.
321 DataUseReports::iterator it = 206 DataUseReports::iterator it =
322 buffered_data_reports_.find(data_use_report_key); 207 buffered_data_reports_.find(data_use_report_key);
323 if (it == buffered_data_reports_.end()) { 208 if (it == buffered_data_reports_.end()) {
324 // Limit the buffer size. 209 // Limit the buffer size.
325 if (buffered_data_reports_.size() == kMaxBufferSize) { 210 if (buffered_data_reports_.size() ==
211 ExternalDataUseReporter::kMaxBufferSize) {
326 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_LOST, 212 RecordDataUsageReportSubmission(DATAUSAGE_REPORT_SUBMISSION_LOST,
327 data_use.rx_bytes + data_use.tx_bytes); 213 data_use.rx_bytes + data_use.tx_bytes);
328 return; 214 return;
329 } 215 }
330 buffered_data_reports_.insert(std::make_pair(data_use_report_key, report)); 216 buffered_data_reports_.insert(std::make_pair(data_use_report_key, report));
331 } else { 217 } else {
332 DataUseReport existing_report = DataUseReport(it->second); 218 DataUseReport existing_report = DataUseReport(it->second);
333 DataUseReport merged_report = DataUseReport( 219 DataUseReport merged_report = DataUseReport(
334 std::min(existing_report.start_time, report.start_time), 220 std::min(existing_report.start_time, report.start_time),
335 std::max(existing_report.end_time, report.end_time), 221 std::max(existing_report.end_time, report.end_time),
336 existing_report.bytes_downloaded + report.bytes_downloaded, 222 existing_report.bytes_downloaded + report.bytes_downloaded,
337 existing_report.bytes_uploaded + report.bytes_uploaded); 223 existing_report.bytes_uploaded + report.bytes_uploaded);
338 buffered_data_reports_.erase(it); 224 buffered_data_reports_.erase(it);
339 buffered_data_reports_.insert( 225 buffered_data_reports_.insert(
340 std::make_pair(data_use_report_key, merged_report)); 226 std::make_pair(data_use_report_key, merged_report));
341 } 227 }
342 total_bytes_buffered_ += (data_use.rx_bytes + data_use.tx_bytes); 228 total_bytes_buffered_ += (data_use.rx_bytes + data_use.tx_bytes);
343 229
344 DCHECK_LT(0U, buffered_data_reports_.size()); 230 DCHECK_LT(0U, buffered_data_reports_.size());
345 DCHECK_LE(buffered_data_reports_.size(), kMaxBufferSize); 231 DCHECK_LE(buffered_data_reports_.size(),
232 ExternalDataUseReporter::kMaxBufferSize);
346 } 233 }
347 234
348 void ExternalDataUseObserver::SubmitBufferedDataUseReport(bool immediate) { 235 void ExternalDataUseReporter::SubmitBufferedDataUseReport(bool immediate) {
349 DCHECK(thread_checker_.CalledOnValidThread()); 236 DCHECK(thread_checker_.CalledOnValidThread());
350 237
351 const base::TimeTicks ticks_now = base::TimeTicks::Now(); 238 const base::TimeTicks ticks_now = base::TimeTicks::Now();
352 239
353 // Return if a data use report has been pending for less than 240 // Return if a data use report has been pending for less than
354 // |data_report_submit_timeout_| duration. 241 // |data_report_submit_timeout_| duration.
355 if (!last_data_report_submitted_ticks_.is_null() && 242 if (!last_data_report_submitted_ticks_.is_null() &&
356 ticks_now - last_data_report_submitted_ticks_ < 243 ticks_now - last_data_report_submitted_ticks_ <
357 data_report_submit_timeout_) { 244 data_report_submit_timeout_) {
358 return; 245 return;
(...skipping 20 matching lines...) Expand all
379 266
380 DCHECK_EQ(0, pending_report_bytes_); 267 DCHECK_EQ(0, pending_report_bytes_);
381 DCHECK(last_data_report_submitted_ticks_.is_null()); 268 DCHECK(last_data_report_submitted_ticks_.is_null());
382 pending_report_bytes_ = report.bytes_downloaded + report.bytes_uploaded; 269 pending_report_bytes_ = report.bytes_downloaded + report.bytes_uploaded;
383 last_data_report_submitted_ticks_ = ticks_now; 270 last_data_report_submitted_ticks_ = ticks_now;
384 271
385 // Remove the entry from the map. 272 // Remove the entry from the map.
386 buffered_data_reports_.erase(it); 273 buffered_data_reports_.erase(it);
387 total_bytes_buffered_ -= (report.bytes_downloaded + report.bytes_uploaded); 274 total_bytes_buffered_ -= (report.bytes_downloaded + report.bytes_uploaded);
388 275
389 // It is okay to use base::Unretained here since 276 external_data_use_observer_bridge_->ReportDataUse(
390 // |external_data_use_observer_bridge_| is owned by |this|, and is destroyed 277 key.label, key.tag, key.connection_type, key.mcc_mnc, report.start_time,
391 // on UI thread when |this| is destroyed. 278 report.end_time, report.bytes_downloaded, report.bytes_uploaded);
392 ui_task_runner_->PostTask(
393 FROM_HERE,
394 base::Bind(&ExternalDataUseObserverBridge::ReportDataUse,
395 base::Unretained(external_data_use_observer_bridge_),
396 key.label, key.tag, key.connection_type, key.mcc_mnc,
397 report.start_time, report.end_time, report.bytes_downloaded,
398 report.bytes_uploaded));
399 } 279 }
400 280
401 base::WeakPtr<ExternalDataUseObserver> ExternalDataUseObserver::GetWeakPtr() { 281 ExternalDataUseReporter::DataUseReportKey::DataUseReportKey(
402 DCHECK(thread_checker_.CalledOnValidThread());
403 return weak_factory_.GetWeakPtr();
404 }
405
406 DataUseTabModel* ExternalDataUseObserver::GetDataUseTabModel() const {
407 DCHECK(thread_checker_.CalledOnValidThread());
408 return data_use_tab_model_;
409 }
410
411 ExternalDataUseObserver::DataUseReportKey::DataUseReportKey(
412 const std::string& label, 282 const std::string& label,
413 const std::string& tag, 283 const std::string& tag,
414 net::NetworkChangeNotifier::ConnectionType connection_type, 284 net::NetworkChangeNotifier::ConnectionType connection_type,
415 const std::string& mcc_mnc) 285 const std::string& mcc_mnc)
416 : label(label), 286 : label(label),
417 tag(tag), 287 tag(tag),
418 connection_type(connection_type), 288 connection_type(connection_type),
419 mcc_mnc(mcc_mnc) {} 289 mcc_mnc(mcc_mnc) {}
420 290
421 ExternalDataUseObserver::DataUseReportKey::DataUseReportKey( 291 ExternalDataUseReporter::DataUseReportKey::DataUseReportKey(
422 const ExternalDataUseObserver::DataUseReportKey& other) = 292 const ExternalDataUseReporter::DataUseReportKey& other) = default;
423 default;
424 293
425 bool ExternalDataUseObserver::DataUseReportKey::operator==( 294 bool ExternalDataUseReporter::DataUseReportKey::operator==(
426 const DataUseReportKey& other) const { 295 const DataUseReportKey& other) const {
427 return label == other.label && tag == other.tag && 296 return label == other.label && tag == other.tag &&
428 connection_type == other.connection_type && mcc_mnc == other.mcc_mnc; 297 connection_type == other.connection_type && mcc_mnc == other.mcc_mnc;
429 } 298 }
430 299
431 ExternalDataUseObserver::DataUseReport::DataUseReport( 300 ExternalDataUseReporter::DataUseReport::DataUseReport(
432 const base::Time& start_time, 301 const base::Time& start_time,
433 const base::Time& end_time, 302 const base::Time& end_time,
434 int64_t bytes_downloaded, 303 int64_t bytes_downloaded,
435 int64_t bytes_uploaded) 304 int64_t bytes_uploaded)
436 : start_time(start_time), 305 : start_time(start_time),
437 end_time(end_time), 306 end_time(end_time),
438 bytes_downloaded(bytes_downloaded), 307 bytes_downloaded(bytes_downloaded),
439 bytes_uploaded(bytes_uploaded) {} 308 bytes_uploaded(bytes_uploaded) {}
440 309
441 size_t ExternalDataUseObserver::DataUseReportKeyHash::operator()( 310 size_t ExternalDataUseReporter::DataUseReportKeyHash::operator()(
442 const DataUseReportKey& k) const { 311 const DataUseReportKey& k) const {
443 // The hash is computed by hashing individual variables and combining them 312 // The hash is computed by hashing individual variables and combining them
444 // using prime numbers. Prime numbers are used for multiplication because the 313 // using prime numbers. Prime numbers are used for multiplication because the
445 // number of buckets used by map is always an even number. Using a prime 314 // number of buckets used by map is always an even number. Using a prime
446 // number ensures that for two different DataUseReportKey objects (say |j| 315 // number ensures that for two different DataUseReportKey objects (say |j|
447 // and |k|), if the hash value of |k.label| is equal to hash value of 316 // and |k|), if the hash value of |k.label| is equal to hash value of
448 // |j.mcc_mnc|, then |j| and |k| map to different buckets. Large prime 317 // |j.mcc_mnc|, then |j| and |k| map to different buckets. Large prime
449 // numbers are used so that hash value is spread over a larger range. 318 // numbers are used so that hash value is spread over a larger range.
450 std::hash<std::string> hash_function; 319 std::hash<std::string> hash_function;
451 size_t hash = 1; 320 size_t hash = 1;
452 hash = hash * 23 + hash_function(k.label); 321 hash = hash * 23 + hash_function(k.label);
453 hash = hash * 31 + hash_function(k.tag); 322 hash = hash * 31 + hash_function(k.tag);
454 hash = hash * 43 + k.connection_type; 323 hash = hash * 43 + k.connection_type;
455 hash = hash * 83 + hash_function(k.mcc_mnc); 324 hash = hash * 83 + hash_function(k.mcc_mnc);
456 return hash; 325 return hash;
457 } 326 }
458 327
459 } // namespace android 328 } // namespace android
460 329
461 } // namespace chrome 330 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698