OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |