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

Side by Side Diff: chrome/browser/devtools/devtools_network_interceptor.cc

Issue 342473004: DevTools: make network conditions emulation scoped (browser) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rename + fix nits + polish Created 6 years, 6 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/devtools/devtools_network_controller.h" 5 #include "chrome/browser/devtools/devtools_network_interceptor.h"
6 6
7 #include "base/time/time.h" 7 #include "base/time/time.h"
8 #include "chrome/browser/devtools/devtools_network_conditions.h" 8 #include "chrome/browser/devtools/devtools_network_conditions.h"
9 #include "chrome/browser/devtools/devtools_network_transaction.h" 9 #include "chrome/browser/devtools/devtools_network_transaction.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/profiles/profile_io_data.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/resource_context.h"
14
15 using content::BrowserThread;
16 10
17 namespace { 11 namespace {
18 12
19 const char kDevToolsRequestInitiator[] = "X-DevTools-Request-Initiator";
20 int64_t kPacketSize = 1500; 13 int64_t kPacketSize = 1500;
21 14
22 } // namespace 15 } // namespace
23 16
24 DevToolsNetworkController::DevToolsNetworkController() 17 DevToolsNetworkInterceptor::DevToolsNetworkInterceptor()
25 : weak_ptr_factory_(this) { 18 : conditions_(new DevToolsNetworkConditions()),
19 weak_ptr_factory_(this) {
26 } 20 }
27 21
28 DevToolsNetworkController::~DevToolsNetworkController() { 22 DevToolsNetworkInterceptor::~DevToolsNetworkInterceptor() {
29 } 23 }
30 24
31 void DevToolsNetworkController::AddTransaction( 25 base::WeakPtr<DevToolsNetworkInterceptor>
26 DevToolsNetworkInterceptor::GetWeakPtr() {
27 return weak_ptr_factory_.GetWeakPtr();
28 }
29
30 void DevToolsNetworkInterceptor::AddTransaction(
32 DevToolsNetworkTransaction* transaction) { 31 DevToolsNetworkTransaction* transaction) {
33 DCHECK(thread_checker_.CalledOnValidThread()); 32 DCHECK(transactions_.find(transaction) == transactions_.end());
34 transactions_.insert(transaction); 33 transactions_.insert(transaction);
35 } 34 }
36 35
37 void DevToolsNetworkController::RemoveTransaction( 36 void DevToolsNetworkInterceptor::RemoveTransaction(
38 DevToolsNetworkTransaction* transaction) { 37 DevToolsNetworkTransaction* transaction) {
39 DCHECK(thread_checker_.CalledOnValidThread());
40 DCHECK(transactions_.find(transaction) != transactions_.end()); 38 DCHECK(transactions_.find(transaction) != transactions_.end());
41 transactions_.erase(transaction); 39 transactions_.erase(transaction);
42 40
43 if (conditions_ && conditions_->IsThrottling()) { 41 if (!conditions_->IsThrottling())
44 UpdateThrottles(); 42 return;
45 throttled_transactions_.erase(std::remove(throttled_transactions_.begin(), 43
46 throttled_transactions_.end(), transaction), 44 UpdateThrottles();
47 throttled_transactions_.end()); 45 throttled_transactions_.erase(std::remove(throttled_transactions_.begin(),
48 ArmTimer(); 46 throttled_transactions_.end(), transaction),
49 } 47 throttled_transactions_.end());
48 ArmTimer();
50 } 49 }
51 50
52 void DevToolsNetworkController::SetNetworkState( 51 void DevToolsNetworkInterceptor::UpdateConditions(
53 const scoped_refptr<DevToolsNetworkConditions> conditions) { 52 const scoped_refptr<DevToolsNetworkConditions> conditions) {
54 DCHECK_CURRENTLY_ON(BrowserThread::UI); 53 DCHECK(conditions);
55 BrowserThread::PostTask( 54 if (conditions_->IsThrottling())
56 content::BrowserThread::IO,
57 FROM_HERE,
58 base::Bind(
59 &DevToolsNetworkController::SetNetworkStateOnIO,
60 weak_ptr_factory_.GetWeakPtr(),
61 conditions));
62 }
63
64 void DevToolsNetworkController::SetNetworkStateOnIO(
65 const scoped_refptr<DevToolsNetworkConditions> conditions) {
66 DCHECK(thread_checker_.CalledOnValidThread());
67 if (conditions_ && conditions_->IsThrottling())
68 UpdateThrottles(); 55 UpdateThrottles();
69 56
70 conditions_ = conditions; 57 conditions_ = conditions;
71 if (!conditions || !(conditions->IsThrottling() || conditions->IsOffline())) { 58
59 if (conditions->offline()) {
60 throttled_transactions_.clear();
61 Transactions old_transactions(transactions_);
62 Transactions::iterator it = old_transactions.begin();
63 for (;it != old_transactions.end(); ++it) {
64 if (transactions_.find(*it) == transactions_.end())
65 continue;
66 if (!(*it)->request() || (*it)->failed())
67 continue;
68 if (ShouldFail(*it))
69 (*it)->Fail();
70 }
vsevik 2014/06/18 13:18:32 timer_.Stop(); return;
eustas 2014/06/18 13:27:53 Done.
71 }
72
73 if (conditions->IsThrottling()) {
74 DCHECK(conditions->download_throughput() != 0);
75 offset_ = base::TimeTicks::Now();
76 last_tick_ = 0;
77 int64_t us_tick_length =
78 (1000000L * kPacketSize) / conditions->download_throughput();
79 DCHECK(us_tick_length != 0);
80 if (us_tick_length == 0)
81 us_tick_length = 1;
82 tick_length_ = base::TimeDelta::FromMicroseconds(us_tick_length);
83 ArmTimer();
84 } else {
72 timer_.Stop(); 85 timer_.Stop();
73 int64_t length = throttled_transactions_.size(); 86 int64_t length = throttled_transactions_.size();
74 for (int64_t i = 0; i < length; ++i) 87 for (int64_t i = 0; i < length; ++i)
75 throttled_transactions_[i]->FireThrottledCallback(); 88 throttled_transactions_[i]->FireThrottledCallback();
76 throttled_transactions_.clear(); 89 throttled_transactions_.clear();
77 } 90 }
78
79 if (!conditions)
80 return;
81
82 if (conditions_->IsOffline()) {
83 // Iterate over a copy of set, because failing of transaction could
84 // result in creating a new one, or (theoretically) destroying one.
85 Transactions old_transactions(transactions_);
86 for (Transactions::iterator it = old_transactions.begin();
87 it != old_transactions.end(); ++it) {
88 if (transactions_.find(*it) == transactions_.end())
89 continue;
90 if (!(*it)->request() || (*it)->failed())
91 continue;
92 if (ShouldFail((*it)->request()))
93 (*it)->Fail();
94 }
95 }
96
97 if (conditions_->IsThrottling()) {
98 DCHECK(conditions_->maximal_throughput() != 0);
99 offset_ = base::TimeTicks::Now();
100 last_tick_ = 0;
101 int64_t us_tick_length =
102 (1000000L * kPacketSize) / conditions_->maximal_throughput();
103 DCHECK(us_tick_length != 0);
104 if (us_tick_length == 0)
105 us_tick_length = 1;
106 tick_length_ = base::TimeDelta::FromMicroseconds(us_tick_length);
107 ArmTimer();
108 }
109 } 91 }
110 92
111 bool DevToolsNetworkController::ShouldFail( 93 void DevToolsNetworkInterceptor::UpdateThrottles() {
112 const net::HttpRequestInfo* request) {
113 DCHECK(thread_checker_.CalledOnValidThread());
114 DCHECK(request);
115 if (!conditions_ || !conditions_->IsOffline())
116 return false;
117
118 if (!conditions_->HasMatchingDomain(request->url))
119 return false;
120
121 return !request->extra_headers.HasHeader(kDevToolsRequestInitiator);
122 }
123
124 bool DevToolsNetworkController::ShouldThrottle(
125 const net::HttpRequestInfo* request) {
126 DCHECK(thread_checker_.CalledOnValidThread());
127 DCHECK(request);
128 if (!conditions_ || !conditions_->IsThrottling())
129 return false;
130
131 if (!conditions_->HasMatchingDomain(request->url))
132 return false;
133
134 return !request->extra_headers.HasHeader(kDevToolsRequestInitiator);
135 }
136
137 void DevToolsNetworkController::UpdateThrottles() {
138 int64_t last_tick = (base::TimeTicks::Now() - offset_) / tick_length_; 94 int64_t last_tick = (base::TimeTicks::Now() - offset_) / tick_length_;
139 int64_t ticks = last_tick - last_tick_; 95 int64_t ticks = last_tick - last_tick_;
140 last_tick_ = last_tick; 96 last_tick_ = last_tick;
141 97
142 int64_t length = throttled_transactions_.size(); 98 int64_t length = throttled_transactions_.size();
143 if (!length) 99 if (!length)
144 return; 100 return;
145 101
146 int64_t shift = ticks % length; 102 int64_t shift = ticks % length;
147 for (int64_t i = 0; i < length; ++i) { 103 for (int64_t i = 0; i < length; ++i) {
148 throttled_transactions_[i]->DecreaseThrottledByteCount( 104 throttled_transactions_[i]->DecreaseThrottledByteCount(
149 (ticks / length) * kPacketSize + (i < shift ? kPacketSize : 0)); 105 (ticks / length) * kPacketSize + (i < shift ? kPacketSize : 0));
150 } 106 }
151 std::rotate(throttled_transactions_.begin(), 107 std::rotate(throttled_transactions_.begin(),
152 throttled_transactions_.begin() + shift, throttled_transactions_.end()); 108 throttled_transactions_.begin() + shift, throttled_transactions_.end());
153 } 109 }
154 110
155 void DevToolsNetworkController::OnTimer() { 111 void DevToolsNetworkInterceptor::OnTimer() {
156 UpdateThrottles(); 112 UpdateThrottles();
157 113
158 std::vector<DevToolsNetworkTransaction*> active_transactions; 114 std::vector<DevToolsNetworkTransaction*> active_transactions;
159 std::vector<DevToolsNetworkTransaction*> finished_transactions; 115 std::vector<DevToolsNetworkTransaction*> finished_transactions;
160 size_t length = throttled_transactions_.size(); 116 size_t length = throttled_transactions_.size();
161 for (size_t i = 0; i < length; ++i) { 117 for (size_t i = 0; i < length; ++i) {
162 if (throttled_transactions_[i]->throttled_byte_count() < 0) 118 if (throttled_transactions_[i]->throttled_byte_count() < 0)
163 finished_transactions.push_back(throttled_transactions_[i]); 119 finished_transactions.push_back(throttled_transactions_[i]);
164 else 120 else
165 active_transactions.push_back(throttled_transactions_[i]); 121 active_transactions.push_back(throttled_transactions_[i]);
166 } 122 }
167 throttled_transactions_.swap(active_transactions); 123 throttled_transactions_.swap(active_transactions);
168 124
169 length = finished_transactions.size(); 125 length = finished_transactions.size();
170 for (size_t i = 0; i < length; ++i) 126 for (size_t i = 0; i < length; ++i)
171 finished_transactions[i]->FireThrottledCallback(); 127 finished_transactions[i]->FireThrottledCallback();
172 128
173 ArmTimer(); 129 ArmTimer();
174 } 130 }
175 131
176 void DevToolsNetworkController::ArmTimer() { 132 void DevToolsNetworkInterceptor::ArmTimer() {
177 size_t length = throttled_transactions_.size(); 133 size_t length = throttled_transactions_.size();
178 if (!length) 134 if (!length)
179 return; 135 return;
180 int64_t min_ticks_left = 0x10000L; 136 int64_t min_ticks_left = 0x10000L;
181 for (size_t i = 0; i < length; ++i) { 137 for (size_t i = 0; i < length; ++i) {
182 int64_t packets_left = (throttled_transactions_[i]->throttled_byte_count() + 138 int64_t packets_left = (throttled_transactions_[i]->throttled_byte_count() +
183 kPacketSize - 1) / kPacketSize; 139 kPacketSize - 1) / kPacketSize;
184 int64_t ticks_left = (i + 1) + length * (packets_left - 1); 140 int64_t ticks_left = (i + 1) + length * (packets_left - 1);
185 if (i == 0 || ticks_left < min_ticks_left) 141 if (i == 0 || ticks_left < min_ticks_left)
186 min_ticks_left = ticks_left; 142 min_ticks_left = ticks_left;
187 } 143 }
188 base::TimeTicks desired_time = 144 base::TimeTicks desired_time =
189 offset_ + tick_length_ * (last_tick_ + min_ticks_left); 145 offset_ + tick_length_ * (last_tick_ + min_ticks_left);
190 timer_.Start( 146 timer_.Start(
191 FROM_HERE, 147 FROM_HERE,
192 desired_time - base::TimeTicks::Now(), 148 desired_time - base::TimeTicks::Now(),
193 base::Bind( 149 base::Bind(
194 &DevToolsNetworkController::OnTimer, 150 &DevToolsNetworkInterceptor::OnTimer,
195 weak_ptr_factory_.GetWeakPtr())); 151 base::Unretained(this)));
196 } 152 }
197 153
198 void DevToolsNetworkController::ThrottleTransaction( 154 void DevToolsNetworkInterceptor::ThrottleTransaction(
199 DevToolsNetworkTransaction* transaction) { 155 DevToolsNetworkTransaction* transaction) {
200 UpdateThrottles(); 156 UpdateThrottles();
201 throttled_transactions_.push_back(transaction); 157 throttled_transactions_.push_back(transaction);
202 ArmTimer(); 158 ArmTimer();
203 } 159 }
160
161 bool DevToolsNetworkInterceptor::ShouldFail(
162 const DevToolsNetworkTransaction* transaction) {
163 if (!conditions_->offline())
164 return false;
165
166 if (!transaction->request_initiator().empty())
167 return false;
168
169 return true;
170 }
171
172 bool DevToolsNetworkInterceptor::ShouldThrottle(
173 const DevToolsNetworkTransaction* transaction) {
174 if (!conditions_->IsThrottling())
175 return false;
176
177 if (!transaction->request_initiator().empty())
178 return false;
179
180 return true;
181 }
OLDNEW
« no previous file with comments | « chrome/browser/devtools/devtools_network_interceptor.h ('k') | chrome/browser/devtools/devtools_network_transaction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698