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

Side by Side Diff: components/data_usage/core/data_use_aggregator.cc

Issue 1390993005: Amortize data usage using TrafficStats on Android. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@data_use_buffering
Patch Set: Fixed nit Created 5 years, 1 month 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 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/data_usage/core/data_use_aggregator.h" 5 #include "components/data_usage/core/data_use_aggregator.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/stl_util.h" 9 #include "base/stl_util.h"
13 #include "components/data_usage/core/data_use.h" 10 #include "components/data_usage/core/data_use.h"
11 #include "components/data_usage/core/data_use_amortizer.h"
14 #include "components/data_usage/core/data_use_annotator.h" 12 #include "components/data_usage/core/data_use_annotator.h"
15 #include "net/base/load_timing_info.h" 13 #include "net/base/load_timing_info.h"
16 #include "net/base/network_change_notifier.h" 14 #include "net/base/network_change_notifier.h"
17 #include "net/url_request/url_request.h" 15 #include "net/url_request/url_request.h"
18 16
19 #if defined(OS_ANDROID) 17 #if defined(OS_ANDROID)
20 #include "net/android/network_library.h" 18 #include "net/android/network_library.h"
21 #endif // OS_ANDROID 19 #endif // OS_ANDROID
22 20
23 namespace data_usage { 21 namespace data_usage {
24 22
25 DataUseAggregator::DataUseAggregator(scoped_ptr<DataUseAnnotator> annotator) 23 DataUseAggregator::DataUseAggregator(scoped_ptr<DataUseAnnotator> annotator,
24 scoped_ptr<DataUseAmortizer> amortizer)
26 : annotator_(annotator.Pass()), 25 : annotator_(annotator.Pass()),
26 amortizer_(amortizer.Pass()),
27 connection_type_(net::NetworkChangeNotifier::GetConnectionType()), 27 connection_type_(net::NetworkChangeNotifier::GetConnectionType()),
28 off_the_record_tx_bytes_since_last_flush_(0),
29 off_the_record_rx_bytes_since_last_flush_(0),
30 is_flush_pending_(false),
31 weak_ptr_factory_(this) { 28 weak_ptr_factory_(this) {
32 #if defined(OS_ANDROID) 29 #if defined(OS_ANDROID)
33 mcc_mnc_ = net::android::GetTelephonySimOperator(); 30 mcc_mnc_ = net::android::GetTelephonySimOperator();
34 #endif // OS_ANDROID 31 #endif // OS_ANDROID
35 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 32 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
36 } 33 }
37 34
38 DataUseAggregator::~DataUseAggregator() { 35 DataUseAggregator::~DataUseAggregator() {
39 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 36 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
40 } 37 }
(...skipping 15 matching lines...) Expand all
56 53
57 net::LoadTimingInfo load_timing_info; 54 net::LoadTimingInfo load_timing_info;
58 request->GetLoadTimingInfo(&load_timing_info); 55 request->GetLoadTimingInfo(&load_timing_info);
59 56
60 scoped_ptr<DataUse> data_use( 57 scoped_ptr<DataUse> data_use(
61 new DataUse(request->url(), load_timing_info.request_start, 58 new DataUse(request->url(), load_timing_info.request_start,
62 request->first_party_for_cookies(), -1 /* tab_id */, 59 request->first_party_for_cookies(), -1 /* tab_id */,
63 connection_type_, mcc_mnc_, tx_bytes, rx_bytes)); 60 connection_type_, mcc_mnc_, tx_bytes, rx_bytes));
64 61
65 if (!annotator_) { 62 if (!annotator_) {
66 AppendDataUse(data_use.Pass()); 63 PassDataUseToAmortizer(data_use.Pass());
67 return; 64 return;
68 } 65 }
69 66
67 // TODO(sclittle): Instead of binding a new callback every time, re-use the
68 // same callback every time.
70 annotator_->Annotate( 69 annotator_->Annotate(
71 request, data_use.Pass(), 70 request, data_use.Pass(),
72 base::Bind(&DataUseAggregator::AppendDataUse, GetWeakPtr())); 71 base::Bind(&DataUseAggregator::PassDataUseToAmortizer, GetWeakPtr()));
73 } 72 }
74 73
75 void DataUseAggregator::ReportOffTheRecordDataUse(int64_t tx_bytes, 74 void DataUseAggregator::ReportOffTheRecordDataUse(int64_t tx_bytes,
76 int64_t rx_bytes) { 75 int64_t rx_bytes) {
77 DCHECK(thread_checker_.CalledOnValidThread()); 76 DCHECK(thread_checker_.CalledOnValidThread());
78 off_the_record_tx_bytes_since_last_flush_ += tx_bytes; 77 if (!amortizer_)
79 off_the_record_rx_bytes_since_last_flush_ += rx_bytes; 78 return;
79
80 amortizer_->OnExtraBytes(tx_bytes, rx_bytes);
80 } 81 }
81 82
82 base::WeakPtr<DataUseAggregator> DataUseAggregator::GetWeakPtr() { 83 base::WeakPtr<DataUseAggregator> DataUseAggregator::GetWeakPtr() {
83 DCHECK(thread_checker_.CalledOnValidThread()); 84 DCHECK(thread_checker_.CalledOnValidThread());
84 return weak_ptr_factory_.GetWeakPtr(); 85 return weak_ptr_factory_.GetWeakPtr();
85 } 86 }
86 87
87 void DataUseAggregator::OnConnectionTypeChanged( 88 void DataUseAggregator::OnConnectionTypeChanged(
88 net::NetworkChangeNotifier::ConnectionType type) { 89 net::NetworkChangeNotifier::ConnectionType type) {
89 DCHECK(thread_checker_.CalledOnValidThread()); 90 DCHECK(thread_checker_.CalledOnValidThread());
90 91
91 connection_type_ = type; 92 connection_type_ = type;
92 #if defined(OS_ANDROID) 93 #if defined(OS_ANDROID)
93 mcc_mnc_ = net::android::GetTelephonySimOperator(); 94 mcc_mnc_ = net::android::GetTelephonySimOperator();
94 #endif // OS_ANDROID 95 #endif // OS_ANDROID
95 } 96 }
96 97
97 void DataUseAggregator::SetMccMncForTests(const std::string& mcc_mnc) { 98 void DataUseAggregator::SetMccMncForTests(const std::string& mcc_mnc) {
98 DCHECK(thread_checker_.CalledOnValidThread()); 99 DCHECK(thread_checker_.CalledOnValidThread());
99 mcc_mnc_ = mcc_mnc; 100 mcc_mnc_ = mcc_mnc;
100 } 101 }
101 102
102 void DataUseAggregator::AppendDataUse(scoped_ptr<DataUse> data_use) { 103 void DataUseAggregator::PassDataUseToAmortizer(scoped_ptr<DataUse> data_use) {
103 DCHECK(thread_checker_.CalledOnValidThread()); 104 DCHECK(thread_checker_.CalledOnValidThread());
104 DCHECK(data_use); 105 DCHECK(data_use);
105 106
106 // As an optimization, attempt to combine the newly reported data use with the 107 if (!amortizer_) {
107 // most recent buffered data use, if the annotations on the data use are the 108 OnAmortizationComplete(data_use.Pass());
108 // same. 109 return;
109 if (!buffered_data_use_.empty() &&
110 buffered_data_use_.back()->CanCombineWith(*data_use)) {
111 buffered_data_use_.back()->tx_bytes += data_use->tx_bytes;
112 buffered_data_use_.back()->rx_bytes += data_use->rx_bytes;
113 } else {
114 buffered_data_use_.push_back(data_use.Pass());
115 } 110 }
116 111
117 if (!is_flush_pending_) { 112 // TODO(sclittle): Instead of binding a new callback every time, re-use the
118 // Post a flush operation to happen in the future, so that the 113 // same callback every time.
119 // DataUseAggregator has a chance to batch together some data use before 114 amortizer_->AmortizeDataUse(
120 // notifying observers. 115 data_use.Pass(),
121 base::MessageLoop::current()->task_runner()->PostTask( 116 base::Bind(&DataUseAggregator::OnAmortizationComplete, GetWeakPtr()));
122 FROM_HERE,
123 base::Bind(&DataUseAggregator::FlushBufferedDataUse, GetWeakPtr()));
124 is_flush_pending_ = true;
125 }
126 } 117 }
127 118
128 void DataUseAggregator::FlushBufferedDataUse() { 119 void DataUseAggregator::OnAmortizationComplete(
120 scoped_ptr<DataUse> amortized_data_use) {
129 DCHECK(thread_checker_.CalledOnValidThread()); 121 DCHECK(thread_checker_.CalledOnValidThread());
130 122
131 // TODO(sclittle): Amortize data use on supported platforms before notifying
132 // observers.
133
134 // Pass Observers a sequence of const DataUse pointers instead of using the 123 // Pass Observers a sequence of const DataUse pointers instead of using the
135 // buffer directly in order to prevent Observers from modifying the DataUse 124 // buffer directly in order to prevent Observers from modifying the DataUse
136 // objects. 125 // objects.
137 std::vector<const DataUse*> const_sequence(buffered_data_use_.begin(), 126 // TODO(sclittle): Change the observer interface to take in a const DataUse&.
138 buffered_data_use_.end()); 127 std::vector<const DataUse*> const_sequence(1, amortized_data_use.get());
139 DCHECK(!ContainsValue(const_sequence, nullptr)); 128 DCHECK(!ContainsValue(const_sequence, nullptr));
140 FOR_EACH_OBSERVER(Observer, observer_list_, OnDataUse(const_sequence)); 129 FOR_EACH_OBSERVER(Observer, observer_list_, OnDataUse(const_sequence));
141
142 buffered_data_use_.clear();
143 off_the_record_tx_bytes_since_last_flush_ = 0;
144 off_the_record_rx_bytes_since_last_flush_ = 0;
145 is_flush_pending_ = false;
146 } 130 }
147 131
148 } // namespace data_usage 132 } // namespace data_usage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698