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