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

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

Powered by Google App Engine
This is Rietveld 408576698