OLD | NEW |
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/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
10 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
11 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
12 #include "components/data_usage/core/data_use.h" | 13 #include "components/data_usage/core/data_use.h" |
| 14 #include "components/data_usage/core/data_use_annotator.h" |
13 #include "net/base/load_timing_info.h" | 15 #include "net/base/load_timing_info.h" |
14 #include "net/base/network_change_notifier.h" | 16 #include "net/base/network_change_notifier.h" |
15 #include "net/url_request/url_request.h" | 17 #include "net/url_request/url_request.h" |
16 | 18 |
17 #if defined(OS_ANDROID) | 19 #if defined(OS_ANDROID) |
18 #include "net/android/network_library.h" | 20 #include "net/android/network_library.h" |
19 #endif // OS_ANDROID | 21 #endif // OS_ANDROID |
20 | 22 |
21 namespace data_usage { | 23 namespace data_usage { |
22 | 24 |
23 DataUseAggregator::DataUseAggregator() | 25 DataUseAggregator::DataUseAggregator(scoped_ptr<DataUseAnnotator> annotator) |
24 : connection_type_(net::NetworkChangeNotifier::GetConnectionType()), | 26 : annotator_(annotator.Pass()), |
| 27 connection_type_(net::NetworkChangeNotifier::GetConnectionType()), |
25 off_the_record_tx_bytes_since_last_flush_(0), | 28 off_the_record_tx_bytes_since_last_flush_(0), |
26 off_the_record_rx_bytes_since_last_flush_(0), | 29 off_the_record_rx_bytes_since_last_flush_(0), |
27 is_flush_pending_(false), | 30 is_flush_pending_(false), |
28 weak_ptr_factory_(this) { | 31 weak_ptr_factory_(this) { |
29 #if defined(OS_ANDROID) | 32 #if defined(OS_ANDROID) |
30 mcc_mnc_ = net::android::GetTelephonySimOperator(); | 33 mcc_mnc_ = net::android::GetTelephonySimOperator(); |
31 #endif // OS_ANDROID | 34 #endif // OS_ANDROID |
32 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); | 35 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); |
33 } | 36 } |
34 | 37 |
35 DataUseAggregator::~DataUseAggregator() { | 38 DataUseAggregator::~DataUseAggregator() { |
36 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 39 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
37 } | 40 } |
38 | 41 |
39 void DataUseAggregator::AddObserver(Observer* observer) { | 42 void DataUseAggregator::AddObserver(Observer* observer) { |
40 DCHECK(thread_checker_.CalledOnValidThread()); | 43 DCHECK(thread_checker_.CalledOnValidThread()); |
41 observer_list_.AddObserver(observer); | 44 observer_list_.AddObserver(observer); |
42 } | 45 } |
43 | 46 |
44 void DataUseAggregator::RemoveObserver(Observer* observer) { | 47 void DataUseAggregator::RemoveObserver(Observer* observer) { |
45 DCHECK(thread_checker_.CalledOnValidThread()); | 48 DCHECK(thread_checker_.CalledOnValidThread()); |
46 observer_list_.RemoveObserver(observer); | 49 observer_list_.RemoveObserver(observer); |
47 } | 50 } |
48 | 51 |
49 void DataUseAggregator::ReportDataUse(const net::URLRequest& request, | 52 void DataUseAggregator::ReportDataUse(net::URLRequest* request, |
50 int32_t tab_id, | |
51 int64_t tx_bytes, | 53 int64_t tx_bytes, |
52 int64_t rx_bytes) { | 54 int64_t rx_bytes) { |
53 DCHECK(thread_checker_.CalledOnValidThread()); | 55 DCHECK(thread_checker_.CalledOnValidThread()); |
| 56 |
54 net::LoadTimingInfo load_timing_info; | 57 net::LoadTimingInfo load_timing_info; |
55 request.GetLoadTimingInfo(&load_timing_info); | 58 request->GetLoadTimingInfo(&load_timing_info); |
56 | 59 |
57 scoped_ptr<DataUse> data_use( | 60 scoped_ptr<DataUse> data_use( |
58 new DataUse(request.url(), load_timing_info.request_start, | 61 new DataUse(request->url(), load_timing_info.request_start, |
59 request.first_party_for_cookies(), tab_id, connection_type_, | 62 request->first_party_for_cookies(), -1 /* tab_id */, |
60 mcc_mnc_, tx_bytes, rx_bytes)); | 63 connection_type_, mcc_mnc_, tx_bytes, rx_bytes)); |
61 | 64 |
62 // As an optimization, attempt to combine the newly reported data use with the | 65 if (!annotator_) { |
63 // most recent buffered data use, if the annotations on the data use are the | 66 AppendDataUse(data_use.Pass()); |
64 // same. | 67 return; |
65 if (!buffered_data_use_.empty() && | |
66 buffered_data_use_.back()->CanCombineWith(*data_use)) { | |
67 buffered_data_use_.back()->tx_bytes += tx_bytes; | |
68 buffered_data_use_.back()->rx_bytes += rx_bytes; | |
69 } else { | |
70 buffered_data_use_.push_back(data_use.Pass()); | |
71 } | 68 } |
72 | 69 |
73 if (!is_flush_pending_) { | 70 annotator_->Annotate( |
74 // Post a flush operation to happen in the future, so that the | 71 request, data_use.Pass(), |
75 // DataUseAggregator has a chance to batch together some data use before | 72 base::Bind(&DataUseAggregator::AppendDataUse, GetWeakPtr())); |
76 // notifying observers. | |
77 base::MessageLoop::current()->task_runner()->PostTask( | |
78 FROM_HERE, | |
79 base::Bind(&DataUseAggregator::FlushBufferedDataUse, GetWeakPtr())); | |
80 is_flush_pending_ = true; | |
81 } | |
82 } | 73 } |
83 | 74 |
84 void DataUseAggregator::ReportOffTheRecordDataUse(int64_t tx_bytes, | 75 void DataUseAggregator::ReportOffTheRecordDataUse(int64_t tx_bytes, |
85 int64_t rx_bytes) { | 76 int64_t rx_bytes) { |
86 DCHECK(thread_checker_.CalledOnValidThread()); | 77 DCHECK(thread_checker_.CalledOnValidThread()); |
87 off_the_record_tx_bytes_since_last_flush_ += tx_bytes; | 78 off_the_record_tx_bytes_since_last_flush_ += tx_bytes; |
88 off_the_record_rx_bytes_since_last_flush_ += rx_bytes; | 79 off_the_record_rx_bytes_since_last_flush_ += rx_bytes; |
89 } | 80 } |
90 | 81 |
91 base::WeakPtr<DataUseAggregator> DataUseAggregator::GetWeakPtr() { | 82 base::WeakPtr<DataUseAggregator> DataUseAggregator::GetWeakPtr() { |
| 83 DCHECK(thread_checker_.CalledOnValidThread()); |
92 return weak_ptr_factory_.GetWeakPtr(); | 84 return weak_ptr_factory_.GetWeakPtr(); |
93 } | 85 } |
94 | 86 |
95 void DataUseAggregator::OnConnectionTypeChanged( | 87 void DataUseAggregator::OnConnectionTypeChanged( |
96 net::NetworkChangeNotifier::ConnectionType type) { | 88 net::NetworkChangeNotifier::ConnectionType type) { |
97 DCHECK(thread_checker_.CalledOnValidThread()); | 89 DCHECK(thread_checker_.CalledOnValidThread()); |
98 | 90 |
99 connection_type_ = type; | 91 connection_type_ = type; |
100 #if defined(OS_ANDROID) | 92 #if defined(OS_ANDROID) |
101 mcc_mnc_ = net::android::GetTelephonySimOperator(); | 93 mcc_mnc_ = net::android::GetTelephonySimOperator(); |
102 #endif // OS_ANDROID | 94 #endif // OS_ANDROID |
103 } | 95 } |
104 | 96 |
105 void DataUseAggregator::SetMccMncForTests(const std::string& mcc_mnc) { | 97 void DataUseAggregator::SetMccMncForTests(const std::string& mcc_mnc) { |
106 DCHECK(thread_checker_.CalledOnValidThread()); | 98 DCHECK(thread_checker_.CalledOnValidThread()); |
107 mcc_mnc_ = mcc_mnc; | 99 mcc_mnc_ = mcc_mnc; |
108 } | 100 } |
109 | 101 |
| 102 void DataUseAggregator::AppendDataUse(scoped_ptr<DataUse> data_use) { |
| 103 DCHECK(thread_checker_.CalledOnValidThread()); |
| 104 DCHECK(data_use); |
| 105 |
| 106 // As an optimization, attempt to combine the newly reported data use with the |
| 107 // most recent buffered data use, if the annotations on the data use are the |
| 108 // same. |
| 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 } |
| 116 |
| 117 if (!is_flush_pending_) { |
| 118 // Post a flush operation to happen in the future, so that the |
| 119 // DataUseAggregator has a chance to batch together some data use before |
| 120 // notifying observers. |
| 121 base::MessageLoop::current()->task_runner()->PostTask( |
| 122 FROM_HERE, |
| 123 base::Bind(&DataUseAggregator::FlushBufferedDataUse, GetWeakPtr())); |
| 124 is_flush_pending_ = true; |
| 125 } |
| 126 } |
| 127 |
110 void DataUseAggregator::FlushBufferedDataUse() { | 128 void DataUseAggregator::FlushBufferedDataUse() { |
111 DCHECK(thread_checker_.CalledOnValidThread()); | 129 DCHECK(thread_checker_.CalledOnValidThread()); |
112 | 130 |
113 // TODO(sclittle): Amortize data use on supported platforms before notifying | 131 // TODO(sclittle): Amortize data use on supported platforms before notifying |
114 // observers. | 132 // observers. |
115 | 133 |
116 // Pass Observers a sequence of const DataUse pointers instead of using the | 134 // Pass Observers a sequence of const DataUse pointers instead of using the |
117 // buffer directly in order to prevent Observers from modifying the DataUse | 135 // buffer directly in order to prevent Observers from modifying the DataUse |
118 // objects. | 136 // objects. |
119 std::vector<const DataUse*> const_sequence(buffered_data_use_.begin(), | 137 std::vector<const DataUse*> const_sequence(buffered_data_use_.begin(), |
120 buffered_data_use_.end()); | 138 buffered_data_use_.end()); |
121 DCHECK(!ContainsValue(const_sequence, nullptr)); | 139 DCHECK(!ContainsValue(const_sequence, nullptr)); |
122 FOR_EACH_OBSERVER(Observer, observer_list_, OnDataUse(const_sequence)); | 140 FOR_EACH_OBSERVER(Observer, observer_list_, OnDataUse(const_sequence)); |
123 | 141 |
124 buffered_data_use_.clear(); | 142 buffered_data_use_.clear(); |
125 off_the_record_tx_bytes_since_last_flush_ = 0; | 143 off_the_record_tx_bytes_since_last_flush_ = 0; |
126 off_the_record_rx_bytes_since_last_flush_ = 0; | 144 off_the_record_rx_bytes_since_last_flush_ = 0; |
127 is_flush_pending_ = false; | 145 is_flush_pending_ = false; |
128 } | 146 } |
129 | 147 |
130 } // namespace data_usage | 148 } // namespace data_usage |
OLD | NEW |