diff --git a/brightray/browser/browser_context.cc b/brightray/browser/browser_context.cc index f5d6effdeba..96e21ae854d 100644 --- a/brightray/browser/browser_context.cc +++ b/brightray/browser/browser_context.cc @@ -136,6 +136,7 @@ net::URLRequestContextGetter* BrowserContext::CreateRequestContext( DCHECK(!url_request_getter_.get()); url_request_getter_ = new URLRequestContextGetter( this, + GetDevToolsNetworkController(), net_log, GetPath(), in_memory_, @@ -147,6 +148,12 @@ net::URLRequestContextGetter* BrowserContext::CreateRequestContext( return url_request_getter_.get(); } +DevToolsNetworkController* BrowserContext::GetDevToolsNetworkController() { + if (!controller_) + controller_.reset(new DevToolsNetworkController); + return controller_.get(); +} + net::NetworkDelegate* BrowserContext::CreateNetworkDelegate() { return new NetworkDelegate; } diff --git a/brightray/browser/browser_context.h b/brightray/browser/browser_context.h index 836d17c84bf..e6c339d8eef 100644 --- a/brightray/browser/browser_context.h +++ b/brightray/browser/browser_context.h @@ -7,6 +7,7 @@ #include +#include "browser/net/devtools_network_controller.h" #include "browser/permission_manager.h" #include "browser/url_request_context_getter.h" @@ -57,6 +58,7 @@ class BrowserContext : public base::RefCounted, NetLog* net_log, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector protocol_interceptors); + DevToolsNetworkController* GetDevToolsNetworkController(); net::URLRequestContextGetter* url_request_context_getter() const { return url_request_getter_.get(); @@ -107,6 +109,7 @@ class BrowserContext : public base::RefCounted, base::FilePath path_; bool in_memory_; scoped_ptr resource_context_; + scoped_ptr controller_; scoped_refptr url_request_getter_; scoped_ptr prefs_; scoped_ptr permission_manager_; diff --git a/brightray/browser/devtools_manager_delegate.cc b/brightray/browser/devtools_manager_delegate.cc index 89c3469fc0d..95b6fb3b5b2 100644 --- a/brightray/browser/devtools_manager_delegate.cc +++ b/brightray/browser/devtools_manager_delegate.cc @@ -6,6 +6,8 @@ #include +#include "browser/net/devtools_network_protocol_handler.h" + #include "base/bind.h" #include "base/command_line.h" #include "base/files/file_path.h" @@ -140,7 +142,8 @@ DevToolsManagerDelegate::CreateHttpHandler() { GetBrightrayUserAgent()); } -DevToolsManagerDelegate::DevToolsManagerDelegate() { +DevToolsManagerDelegate::DevToolsManagerDelegate() + : handler_(new DevToolsNetworkProtocolHandler) { // NB(zcbenz): This call does nothing, the only purpose is to make sure the // devtools_discovery module is linked into the final executable on Linux. // Though it is possible to achieve this by modifying the gyp settings, it @@ -155,7 +158,7 @@ DevToolsManagerDelegate::~DevToolsManagerDelegate() { base::DictionaryValue* DevToolsManagerDelegate::HandleCommand( content::DevToolsAgentHost* agent_host, base::DictionaryValue* command) { - return NULL; + return handler_->HandleCommand(agent_host, command); } } // namespace brightray diff --git a/brightray/browser/devtools_manager_delegate.h b/brightray/browser/devtools_manager_delegate.h index 154ea9ccbf7..ed8e357482b 100644 --- a/brightray/browser/devtools_manager_delegate.h +++ b/brightray/browser/devtools_manager_delegate.h @@ -16,6 +16,8 @@ class DevToolsHttpHandler; namespace brightray { +class DevToolsNetworkProtocolHandler; + class DevToolsManagerDelegate : public content::DevToolsManagerDelegate { public: static devtools_http_handler::DevToolsHttpHandler* CreateHttpHandler(); @@ -32,6 +34,8 @@ class DevToolsManagerDelegate : public content::DevToolsManagerDelegate { base::DictionaryValue* command) override; private: + scoped_ptr handler_; + DISALLOW_COPY_AND_ASSIGN(DevToolsManagerDelegate); }; diff --git a/brightray/browser/net/devtools_network_conditions.cc b/brightray/browser/net/devtools_network_conditions.cc new file mode 100644 index 00000000000..0005c7f56c7 --- /dev/null +++ b/brightray/browser/net/devtools_network_conditions.cc @@ -0,0 +1,35 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "browser/net/devtools_network_conditions.h" + +namespace brightray { + +DevToolsNetworkConditions::DevToolsNetworkConditions(bool offline) + : offline_(offline), + latency_(0), + download_throughput_(0), + upload_throughput_(0) { +} + +DevToolsNetworkConditions::DevToolsNetworkConditions( + bool offline, + double latency, + double download_throughput, + double upload_throughput) + : offline_(offline), + latency_(latency), + download_throughput_(download_throughput), + upload_throughput_(upload_throughput) { +} + +DevToolsNetworkConditions::~DevToolsNetworkConditions() { +} + +bool DevToolsNetworkConditions::IsThrottling() const { + return !offline_ && ((latency_ != 0.0) || (download_throughput_ != 0.0) || + (upload_throughput_ != 0.0)); +} + +} // namespace brightray diff --git a/brightray/browser/net/devtools_network_conditions.h b/brightray/browser/net/devtools_network_conditions.h new file mode 100644 index 00000000000..81aae86f8d4 --- /dev/null +++ b/brightray/browser/net/devtools_network_conditions.h @@ -0,0 +1,43 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BROWSER_DEVTOOLS_NETWORK_CONDITIONS_H_ +#define BROWSER_DEVTOOLS_NETWORK_CONDITIONS_H_ + +#include +#include + +#include "base/macros.h" +#include "url/gurl.h" + +namespace brightray { + +class DevToolsNetworkConditions { + public: + explicit DevToolsNetworkConditions(bool offline); + DevToolsNetworkConditions(bool offline, + double latency, + double download_throughput, + double upload_throughput); + ~DevToolsNetworkConditions(); + + bool IsThrottling() const; + + bool offline() const { return offline_; } + double latency() const { return latency_; } + double download_throughput() const { return download_throughput_; } + double upload_throughput() const { return upload_throughput_; } + + private: + const bool offline_; + const double latency_; + const double download_throughput_; + const double upload_throughput_; + + DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkConditions); +}; + +} // namespace brightray + +#endif // BROWSER_DEVTOOLS_NETWORK_CONDITIONS_H_ diff --git a/brightray/browser/net/devtools_network_controller.cc b/brightray/browser/net/devtools_network_controller.cc new file mode 100644 index 00000000000..42ebf06471f --- /dev/null +++ b/brightray/browser/net/devtools_network_controller.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser/net/devtools_network_controller.h" + +#include "browser/net/devtools_network_conditions.h" +#include "browser/net/devtools_network_interceptor.h" +#include "browser/net/devtools_network_transaction.h" + +#include "base/bind.h" +#include "content/public/browser/browser_thread.h" + +using content::BrowserThread; + +namespace brightray { + +DevToolsNetworkController::DevToolsNetworkController() + : default_interceptor_(new DevToolsNetworkInterceptor) { +} + +DevToolsNetworkController::~DevToolsNetworkController() { +} + +void DevToolsNetworkController::SetNetworkState( + const std::string& client_id, + scoped_ptr conditions) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + if (client_id.empty()) { + if (!conditions) + return; + default_interceptor_->UpdateConditions(conditions.Pass()); + return; + } + + auto interceptor = interceptors_.get(client_id); + if (!interceptor) { + if (!conditions) + return; + scoped_ptr new_interceptor( + new DevToolsNetworkInterceptor); + new_interceptor->UpdateConditions(conditions.Pass()); + interceptors_.set(client_id, new_interceptor.Pass()); + } else { + if (!conditions) { + scoped_ptr online_conditions( + new DevToolsNetworkConditions(false)); + interceptor->UpdateConditions(online_conditions.Pass()); + interceptors_.erase(client_id); + } else { + interceptor->UpdateConditions(conditions.Pass()); + } + } +} + +base::WeakPtr +DevToolsNetworkController::GetInterceptor(DevToolsNetworkTransaction* transaction) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + DCHECK(transaction->request()); + + if (!interceptors_.size()) + return default_interceptor_->GetWeakPtr(); + + transaction->ProcessRequest(); + auto& client_id = transaction->client_id(); + auto interceptor = interceptors_.get(client_id); + if (!interceptor) + return default_interceptor_->GetWeakPtr(); + + return interceptor->GetWeakPtr(); +} + +} // namespace brightray diff --git a/brightray/browser/net/devtools_network_controller.h b/brightray/browser/net/devtools_network_controller.h new file mode 100644 index 00000000000..a73268f798f --- /dev/null +++ b/brightray/browser/net/devtools_network_controller.h @@ -0,0 +1,40 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef BROWSER_DEVTOOLS_NETWORK_CONTROLLER_H_ +#define BROWSER_DEVTOOLS_NETWORK_CONTROLLER_H_ + +#include "base/containers/scoped_ptr_hash_map.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" + +namespace brightray { + +class DevToolsNetworkConditions; +class DevToolsNetworkInterceptor; +class DevToolsNetworkTransaction; + +class DevToolsNetworkController { + public: + DevToolsNetworkController(); + virtual ~DevToolsNetworkController(); + + void SetNetworkState(const std::string& client_id, + scoped_ptr conditions); + base::WeakPtr GetInterceptor( + DevToolsNetworkTransaction* transaction); + + private: + using InterceptorMap = base::ScopedPtrHashMap>; + scoped_ptr default_interceptor_; + InterceptorMap interceptors_; + + DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkController); +}; + +} // namespace brightray + +#endif // BROWSER_DEVTOOLS_NETWORK_CONTROLLER_H_ diff --git a/brightray/browser/net/devtools_network_interceptor.cc b/brightray/browser/net/devtools_network_interceptor.cc new file mode 100644 index 00000000000..78afb00a09a --- /dev/null +++ b/brightray/browser/net/devtools_network_interceptor.cc @@ -0,0 +1,255 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "browser/net/devtools_network_interceptor.h" + +#include + +#include "browser/net/devtools_network_conditions.h" +#include "browser/net/devtools_network_transaction.h" + +#include "base/time/time.h" +#include "net/base/load_timing_info.h" + +namespace brightray { + +namespace { + +int64_t kPacketSize = 1500; + +} // namespace + +DevToolsNetworkInterceptor::DevToolsNetworkInterceptor() + : conditions_(new DevToolsNetworkConditions(false)), + weak_ptr_factory_(this) { +} + +DevToolsNetworkInterceptor::~DevToolsNetworkInterceptor() { +} + +base::WeakPtr +DevToolsNetworkInterceptor::GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); +} + +void DevToolsNetworkInterceptor::UpdateConditions( + scoped_ptr conditions) { + DCHECK(conditions); + base::TimeTicks now = base::TimeTicks::Now(); + if (conditions_->IsThrottling()) + UpdateThrottledTransactions(now); + + conditions_ = conditions.Pass(); + + if (conditions_->offline()) { + timer_.Stop(); + throttled_transactions_.clear(); + suspended_transactions_.clear(); + Transactions old_transactions(transactions_); + Transactions::iterator it = old_transactions.begin(); + for (; it != old_transactions.end(); ++it) { + if (transactions_.find(*it) == transactions_.end()) + continue; + if (!(*it)->request() || (*it)->failed()) + continue; + if (ShouldFail(*it)) + (*it)->Fail(); + } + return; + } + + if (conditions_->IsThrottling()) { + DCHECK_NE(conditions_->download_throughput(), 0); + offset_ = now; + last_tick_ = 0; + int64_t us_tick_length = + (1000000L * kPacketSize) / conditions_->download_throughput(); + DCHECK_NE(us_tick_length, 0); + if (us_tick_length == 0) + us_tick_length = 1; + tick_length_ = base::TimeDelta::FromMicroseconds(us_tick_length); + latency_length_ = base::TimeDelta(); + double latency = conditions_->latency(); + if (latency > 0) + latency_length_ = base::TimeDelta::FromMillisecondsD(latency); + ArmTimer(now); + } else { + timer_.Stop(); + + std::vector throttled_transactions; + throttled_transactions.swap(throttled_transactions_); + for (auto& throttled_transaction : throttled_transactions) + FireThrottledCallback(throttled_transaction); + + SuspendedTransactions suspended_transactions; + suspended_transactions.swap(suspended_transactions_); + for (auto& suspended_transaction : suspended_transactions) + FireThrottledCallback(suspended_transaction.first); + } +} + +void DevToolsNetworkInterceptor::AddTransaction( + DevToolsNetworkTransaction* transaction) { + DCHECK(transactions_.find(transaction) == transactions_.end()); + transactions_.insert(transaction); +} + +void DevToolsNetworkInterceptor::RemoveTransaction( + DevToolsNetworkTransaction* transaction) { + DCHECK(transactions_.find(transaction) != transactions_.end()); + transactions_.erase(transaction); + + if (!conditions_->IsThrottling()) + return; + + base::TimeTicks now = base::TimeTicks::Now(); + UpdateThrottledTransactions(now); + throttled_transactions_.erase(std::remove(throttled_transactions_.begin(), + throttled_transactions_.end(), transaction), + throttled_transactions_.end()); + + SuspendedTransactions::iterator it = suspended_transactions_.begin(); + for (; it != suspended_transactions_.end(); ++it) { + if (it->first == transaction) { + suspended_transactions_.erase(it); + break; + } + } + + ArmTimer(now); +} + +bool DevToolsNetworkInterceptor::ShouldFail( + const DevToolsNetworkTransaction* transaction) { + return conditions_->offline(); +} + +bool DevToolsNetworkInterceptor::ShouldThrottle( + const DevToolsNetworkTransaction* transaction) { + return conditions_->IsThrottling(); +} + +void DevToolsNetworkInterceptor::ThrottleTransaction( + DevToolsNetworkTransaction* transaction, bool start) { + base::TimeTicks now = base::TimeTicks::Now(); + UpdateThrottledTransactions(now); + if (start && latency_length_ != base::TimeDelta()) { + net::LoadTimingInfo load_timing_info; + base::TimeTicks send_end; + if (transaction->GetLoadTimingInfo(&load_timing_info)) + send_end = load_timing_info.send_end; + if (send_end.is_null()) + send_end = now; + int64_t us_send_end = (send_end - base::TimeTicks()).InMicroseconds(); + suspended_transactions_.push_back( + SuspendedTransaction(transaction, us_send_end)); + UpdateSuspendedTransactions(now); + } else { + throttled_transactions_.push_back(transaction); + } + ArmTimer(now); +} + +void DevToolsNetworkInterceptor::UpdateThrottledTransactions( + base::TimeTicks now) { + int64_t last_tick = (now - offset_) / tick_length_; + int64_t ticks = last_tick - last_tick_; + last_tick_ = last_tick; + + int64_t length = throttled_transactions_.size(); + if (!length) { + UpdateSuspendedTransactions(now); + return; + } + + int64_t shift = ticks % length; + for (int64_t i = 0; i < length; ++i) { + throttled_transactions_[i]->DecreaseThrottledByteCount( + (ticks / length) * kPacketSize + (i < shift ? kPacketSize : 0)); + } + std::rotate(throttled_transactions_.begin(), + throttled_transactions_.begin() + shift, throttled_transactions_.end()); + + UpdateSuspendedTransactions(now); +} + +void DevToolsNetworkInterceptor::UpdateSuspendedTransactions( + base::TimeTicks now) { + int64_t activation_baseline = + (now - latency_length_ - base::TimeTicks()).InMicroseconds(); + SuspendedTransactions suspended_transactions; + SuspendedTransactions::iterator it = suspended_transactions_.begin(); + for (; it != suspended_transactions_.end(); ++it) { + if (it->second <= activation_baseline) + throttled_transactions_.push_back(it->first); + else + suspended_transactions.push_back(*it); + } + suspended_transactions_.swap(suspended_transactions); +} + +void DevToolsNetworkInterceptor::ArmTimer(base::TimeTicks now) { + size_t throttle_count = throttled_transactions_.size(); + size_t suspend_count = suspended_transactions_.size(); + if (!throttle_count && !suspend_count) + return; + + int64_t min_ticks_left = 0x10000L; + for (size_t i = 0; i < throttle_count; ++i) { + int64_t packets_left = (throttled_transactions_[i]->throttled_byte_count() + + kPacketSize - 1) / kPacketSize; + int64_t ticks_left = (i + 1) + throttle_count * (packets_left - 1); + if (i == 0 || ticks_left < min_ticks_left) + min_ticks_left = ticks_left; + } + + base::TimeTicks desired_time = + offset_ + tick_length_ * (last_tick_ + min_ticks_left); + + int64_t min_baseline = std::numeric_limits::max(); + for (size_t i = 0; i < suspend_count; ++i) { + if (suspended_transactions_[i].second < min_baseline) + min_baseline = suspended_transactions_[i].second; + } + + if (suspend_count) { + base::TimeTicks activation_time = base::TimeTicks() + + base::TimeDelta::FromMicroseconds(min_baseline) + latency_length_; + if (activation_time < desired_time) + desired_time = activation_time; + } + + timer_.Start(FROM_HERE, desired_time - now, + base::Bind(&DevToolsNetworkInterceptor::OnTimer, + base::Unretained(this))); +} + +void DevToolsNetworkInterceptor::OnTimer() { + base::TimeTicks now = base::TimeTicks::Now(); + UpdateThrottledTransactions(now); + + std::vector active_transactions; + std::vector finished_transactions; + size_t length = throttled_transactions_.size(); + for (size_t i = 0; i < length; ++i) { + if (throttled_transactions_[i]->throttled_byte_count() < 0) + finished_transactions.push_back(throttled_transactions_[i]); + else + active_transactions.push_back(throttled_transactions_[i]); + } + throttled_transactions_.swap(active_transactions); + + for (auto& transaction : finished_transactions) + FireThrottledCallback(transaction); + + ArmTimer(now); +} + +void DevToolsNetworkInterceptor::FireThrottledCallback( + DevToolsNetworkTransaction* transaction) { + if (transactions_.find(transaction) != transactions_.end()) + transaction->FireThrottledCallback(); +} + +} // namespace brightray diff --git a/brightray/browser/net/devtools_network_interceptor.h b/brightray/browser/net/devtools_network_interceptor.h new file mode 100644 index 00000000000..330a7340bd5 --- /dev/null +++ b/brightray/browser/net/devtools_network_interceptor.h @@ -0,0 +1,84 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BROWSER_DEVTOOLS_NETWORK_INTERCEPTOR_H_ +#define BROWSER_DEVTOOLS_NETWORK_INTERCEPTOR_H_ + +#include +#include +#include +#include + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/timer/timer.h" + +namespace base { +class TimeDelta; +class TimeTicks; +} + +namespace brightray { + +class DevToolsNetworkConditions; +class DevToolsNetworkTransaction; + +class DevToolsNetworkInterceptor { + public: + DevToolsNetworkInterceptor(); + virtual ~DevToolsNetworkInterceptor(); + + base::WeakPtr GetWeakPtr(); + + // Applies network emulation configuration. + void UpdateConditions(scoped_ptr conditions); + + void AddTransaction(DevToolsNetworkTransaction* transaction); + void RemoveTransaction(DevToolsNetworkTransaction* transaction); + + // Returns whether transaction should fail with |net::ERR_INTERNET_DISCONNECTED| + bool ShouldFail(const DevToolsNetworkTransaction* transaction); + // Returns whether transaction should be throttled. + bool ShouldThrottle(const DevToolsNetworkTransaction* transaction); + + void ThrottleTransaction(DevToolsNetworkTransaction* transaction, bool start); + + const DevToolsNetworkConditions* conditions() const { + return conditions_.get(); + } + + private: + void UpdateThrottledTransactions(base::TimeTicks now); + void UpdateSuspendedTransactions(base::TimeTicks now); + void ArmTimer(base::TimeTicks now); + void OnTimer(); + void FireThrottledCallback(DevToolsNetworkTransaction* transaction); + + scoped_ptr conditions_; + + using Transactions = std::set; + Transactions transactions_; + + // Transactions suspended for a latency period. + using SuspendedTransaction = std::pair; + using SuspendedTransactions = std::vector; + SuspendedTransactions suspended_transactions_; + + // Transactions waiting certain amount of transfer to be accounted. + std::vector throttled_transactions_; + + base::OneShotTimer timer_; + base::TimeTicks offset_; + base::TimeDelta tick_length_; + base::TimeDelta latency_length_; + uint64_t last_tick_; + + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkInterceptor); +}; + +} // namespace brightray + +#endif // BROWSER_DEVTOOLS_NETWORK_INTERCEPTOR_H_ diff --git a/brightray/browser/net/devtools_network_protocol_handler.cc b/brightray/browser/net/devtools_network_protocol_handler.cc new file mode 100644 index 00000000000..b94a0413289 --- /dev/null +++ b/brightray/browser/net/devtools_network_protocol_handler.cc @@ -0,0 +1,173 @@ +// Copyright (c) 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser/net/devtools_network_protocol_handler.h" + +#include "browser/browser_context.h" +#include "browser/net/devtools_network_conditions.h" +#include "browser/net/devtools_network_controller.h" + +#include "base/strings/stringprintf.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/devtools_agent_host.h" + +using content::BrowserThread; + +namespace brightray { + +namespace { + +namespace params { + +const char kDownloadThroughput[] = "downloadThroughput"; +const char kLatency[] = "latency"; +const char kOffline[] = "offline"; +const char kUploadThroughput[] = "uploadThroughput"; +const char kResult[] = "result"; +const char kErrorCode[] = "code"; +const char kErrorMessage[] = "message"; + +} // namespace params + +const char kEmulateNetworkConditions[] = "Network.emulateNetworkConditions"; +const char kCanEmulateNetworkConditions[] = "Network.canEmulateNetworkConditions"; +const char kId[] = "id"; +const char kMethod[] = "method"; +const char kParams[] = "params"; +const char kError[] = "error"; +// JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object +const int kErrorInvalidParams = -32602; + + +bool ParseCommand(const base::DictionaryValue* command, + int* id, + std::string* method, + const base::DictionaryValue** params) { + if (!command) + return false; + + if (!command->GetInteger(kId, id) || *id < 0) + return false; + + if (!command->GetString(kMethod, method)) + return false; + + if (!command->GetDictionary(kParams, params)) + *params = nullptr; + + return true; +} + +scoped_ptr +CreateSuccessResponse(int id, scoped_ptr result) { + scoped_ptr response(new base::DictionaryValue); + response->SetInteger(kId, id); + response->Set(params::kResult, result.release()); + return response.Pass(); +} + +scoped_ptr +CreateFailureResponse(int id, const std::string& param) { + scoped_ptr response(new base::DictionaryValue); + auto error_object = new base::DictionaryValue; + response->Set(kError, error_object); + error_object->SetInteger(params::kErrorCode, kErrorInvalidParams); + error_object->SetString(params::kErrorMessage, + base::StringPrintf("Missing or Invalid '%s' parameter", param.c_str())); + return response.Pass(); +} + +void UpdateNetworkStateInIO(brightray::DevToolsNetworkController* controller, + const std::string& client_id, + scoped_ptr conditions) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + controller->SetNetworkState(client_id, conditions.Pass()); +} + +} // namespace + +DevToolsNetworkProtocolHandler::DevToolsNetworkProtocolHandler() { +} + +DevToolsNetworkProtocolHandler::~DevToolsNetworkProtocolHandler() { +} + +base::DictionaryValue* DevToolsNetworkProtocolHandler::HandleCommand( + content::DevToolsAgentHost* agent_host, + base::DictionaryValue* command) { + int id = 0; + std::string method; + const base::DictionaryValue* params = nullptr; + + if (!ParseCommand(command, &id, &method, ¶ms)) + return nullptr; + + if (method == kEmulateNetworkConditions) + return EmulateNetworkConditions(agent_host, id, params).release(); + + if (method == kCanEmulateNetworkConditions) + return CanEmulateNetworkConditions(agent_host, id, params).release(); + + return nullptr; +} + +scoped_ptr +DevToolsNetworkProtocolHandler::CanEmulateNetworkConditions( + content::DevToolsAgentHost* agent_host, + int id, + const base::DictionaryValue* params) { + scoped_ptr result(new base::DictionaryValue); + result->SetBoolean(params::kResult, true); + return CreateSuccessResponse(id, result.Pass()); +} + +scoped_ptr +DevToolsNetworkProtocolHandler::EmulateNetworkConditions( + content::DevToolsAgentHost* agent_host, + int id, + const base::DictionaryValue* params) { + bool offline = false; + if (!params || !params->GetBoolean(params::kOffline, &offline)) + return CreateFailureResponse(id, params::kOffline); + + double latency = 0.0; + if (!params->GetDouble(params::kLatency, &latency)) + return CreateFailureResponse(id, params::kLatency); + if (latency < 0.0) + latency = 0.0; + + double download_throughput = 0.0; + if (!params->GetDouble(params::kDownloadThroughput, &download_throughput)) + return CreateFailureResponse(id, params::kDownloadThroughput); + if (download_throughput < 0.0) + download_throughput = 0.0; + + double upload_throughput = 0.0; + if (!params->GetDouble(params::kUploadThroughput, &upload_throughput)) + return CreateFailureResponse(id, params::kUploadThroughput); + if (upload_throughput < 0.0) + upload_throughput = 0.0; + + scoped_ptr conditions( + new DevToolsNetworkConditions(offline, + latency, + download_throughput, + upload_throughput)); + UpdateNetworkState(agent_host, conditions.Pass()); + return scoped_ptr(); +} + +void DevToolsNetworkProtocolHandler::UpdateNetworkState( + content::DevToolsAgentHost* agent_host, + scoped_ptr conditions) { + auto browser_context = + static_cast(agent_host->GetBrowserContext()); + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::Bind(&UpdateNetworkStateInIO, + browser_context->GetDevToolsNetworkController(), + agent_host->GetId(), + base::Passed(&conditions))); +} + +} // namespace brightray diff --git a/brightray/browser/net/devtools_network_protocol_handler.h b/brightray/browser/net/devtools_network_protocol_handler.h new file mode 100644 index 00000000000..4fba01b74d3 --- /dev/null +++ b/brightray/browser/net/devtools_network_protocol_handler.h @@ -0,0 +1,47 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BROWSER_DEVTOOLS_NETWORK_PROTOCOL_HANDLER_H_ +#define BROWSER_DEVTOOLS_NETWORK_PROTOCOL_HANDLER_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" + +namespace content { +class DevToolsAgentHost; +} + +namespace brightray { + +class DevToolsNetworkConditions; + +class DevToolsNetworkProtocolHandler { + public: + DevToolsNetworkProtocolHandler(); + ~DevToolsNetworkProtocolHandler(); + + base::DictionaryValue* HandleCommand( + content::DevToolsAgentHost* agent_host, + base::DictionaryValue* command); + + private: + scoped_ptr CanEmulateNetworkConditions( + content::DevToolsAgentHost* agent_host, + int command_id, + const base::DictionaryValue* params); + scoped_ptr EmulateNetworkConditions( + content::DevToolsAgentHost* agent_host, + int command_id, + const base::DictionaryValue* params); + void UpdateNetworkState( + content::DevToolsAgentHost* agent_host, + scoped_ptr conditions); + + DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkProtocolHandler); +}; + +} // namespace brightray + +#endif // BROWSER_DEVTOOLS_NETWORK_PROTOCOL_HANDLER_H_ diff --git a/brightray/browser/net/devtools_network_transaction.cc b/brightray/browser/net/devtools_network_transaction.cc new file mode 100644 index 00000000000..c8c74a67999 --- /dev/null +++ b/brightray/browser/net/devtools_network_transaction.cc @@ -0,0 +1,283 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser/net/devtools_network_transaction.h" + +#include "browser/net/devtools_network_controller.h" +#include "browser/net/devtools_network_interceptor.h" + +#include "net/base/net_errors.h" +#include "net/base/upload_progress.h" +#include "net/http/http_network_transaction.h" +#include "net/http/http_request_info.h" +#include "net/socket/connection_attempts.h" + +namespace brightray { + +namespace { + +const char kDevToolsEmulateNetworkConditionsClientId[] = + "X-DevTools-Emulate-Network-Conditions-Client-Id"; + +} // namespace + +DevToolsNetworkTransaction::DevToolsNetworkTransaction( + DevToolsNetworkController* controller, + scoped_ptr transaction) + : controller_(controller), + transaction_(transaction.Pass()), + request_(nullptr), + failed_(false), + throttled_byte_count_(0), + callback_type_(NONE) { + proxy_callback_ = base::Bind(&DevToolsNetworkTransaction::OnCallback, + base::Unretained(this)); +} + +DevToolsNetworkTransaction::~DevToolsNetworkTransaction() { + if (interceptor_) + interceptor_->RemoveTransaction(this); +} + +void DevToolsNetworkTransaction::ProcessRequest() { + DCHECK(request_); + + bool has_devtools_client_id = request_->extra_headers.HasHeader( + kDevToolsEmulateNetworkConditionsClientId); + if (!has_devtools_client_id) + return; + + custom_request_.reset(new net::HttpRequestInfo(*request_)); + custom_request_->extra_headers.GetHeader( + kDevToolsEmulateNetworkConditionsClientId, &client_id_); + custom_request_->extra_headers.RemoveHeader( + kDevToolsEmulateNetworkConditionsClientId); + + request_ = custom_request_.get(); +} + +void DevToolsNetworkTransaction::Fail() { + DCHECK(request_); + DCHECK(!failed_); + + failed_ = true; + transaction_->SetBeforeNetworkStartCallback( + BeforeNetworkStartCallback()); + + if (callback_.is_null()) + return; + + net::CompletionCallback original_callback = callback_; + callback_.Reset(); + callback_type_ = NONE; + original_callback.Run(net::ERR_INTERNET_DISCONNECTED); +} + +void DevToolsNetworkTransaction::DecreaseThrottledByteCount( + int64_t delta) { + throttled_byte_count_ -= delta; +} + +int DevToolsNetworkTransaction::Start( + const net::HttpRequestInfo* request, + const net::CompletionCallback& callback, + const net::BoundNetLog& net_log) { + DCHECK(request); + + request_ = request; + interceptor_ = controller_->GetInterceptor(this); + interceptor_->AddTransaction(this); + + if (interceptor_->ShouldFail(this)) { + failed_ = true; + transaction_->SetBeforeNetworkStartCallback(BeforeNetworkStartCallback()); + return net::ERR_INTERNET_DISCONNECTED; + } + int rv = transaction_->Start(request_, proxy_callback_, net_log); + return SetupCallback(callback, rv, START); +} + +int DevToolsNetworkTransaction::RestartIgnoringLastError( + const net::CompletionCallback& callback) { + if (failed_) + return net::ERR_INTERNET_DISCONNECTED; + int rv = transaction_->RestartIgnoringLastError(proxy_callback_); + return SetupCallback(callback, rv, RESTART_IGNORING_LAST_ERROR); +} + +int DevToolsNetworkTransaction::RestartWithCertificate( + net::X509Certificate* client_certificate, + const net::CompletionCallback& callback) { + if (failed_) + return net::ERR_INTERNET_DISCONNECTED; + int rv = transaction_->RestartWithCertificate(client_certificate, proxy_callback_); + return SetupCallback(callback, rv, RESTART_WITH_CERTIFICATE); +} + +int DevToolsNetworkTransaction::RestartWithAuth( + const net::AuthCredentials& credentials, + const net::CompletionCallback& callback) { + if (failed_) + return net::ERR_INTERNET_DISCONNECTED; + int rv = transaction_->RestartWithAuth(credentials, proxy_callback_); + return SetupCallback(callback, rv, RESTART_WITH_AUTH); +} + +bool DevToolsNetworkTransaction::IsReadyToRestartForAuth() { + return transaction_->IsReadyToRestartForAuth(); +} + +int DevToolsNetworkTransaction::Read( + net::IOBuffer* buffer, + int length, + const net::CompletionCallback& callback) { + if (failed_) + return net::ERR_INTERNET_DISCONNECTED; + int rv = transaction_->Read(buffer, length, proxy_callback_); + return SetupCallback(callback, rv, READ); +} + +void DevToolsNetworkTransaction::StopCaching() { + transaction_->StopCaching(); +} + +bool DevToolsNetworkTransaction::GetFullRequestHeaders( + net::HttpRequestHeaders* headers) const { + return transaction_->GetFullRequestHeaders(headers); +} + +int64_t DevToolsNetworkTransaction::GetTotalReceivedBytes() const { + return transaction_->GetTotalReceivedBytes(); +} + +void DevToolsNetworkTransaction::DoneReading() { + transaction_->DoneReading(); +} + +const net::HttpResponseInfo* +DevToolsNetworkTransaction::GetResponseInfo() const { + return transaction_->GetResponseInfo(); +} + +net::LoadState DevToolsNetworkTransaction::GetLoadState() const { + return transaction_->GetLoadState(); +} + +net::UploadProgress DevToolsNetworkTransaction::GetUploadProgress() const { + return transaction_->GetUploadProgress(); +} + +void DevToolsNetworkTransaction::SetQuicServerInfo( + net::QuicServerInfo* info) { + transaction_->SetQuicServerInfo(info); +} + +bool DevToolsNetworkTransaction::GetLoadTimingInfo( + net::LoadTimingInfo* info) const { + return transaction_->GetLoadTimingInfo(info); +} + +void DevToolsNetworkTransaction::SetPriority(net::RequestPriority priority) { + transaction_->SetPriority(priority); +} + +void DevToolsNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper( + net::WebSocketHandshakeStreamBase::CreateHelper* helper) { + transaction_->SetWebSocketHandshakeStreamCreateHelper(helper); +} + +void DevToolsNetworkTransaction::SetBeforeNetworkStartCallback( + const BeforeNetworkStartCallback& callback) { + transaction_->SetBeforeNetworkStartCallback(callback); +} + +void DevToolsNetworkTransaction::SetBeforeProxyHeadersSentCallback( + const BeforeProxyHeadersSentCallback& callback) { + transaction_->SetBeforeProxyHeadersSentCallback(callback); +} + +int DevToolsNetworkTransaction::ResumeNetworkStart() { + if (failed_) + return net::ERR_INTERNET_DISCONNECTED; + return transaction_->ResumeNetworkStart(); +} + +void DevToolsNetworkTransaction::GetConnectionAttempts( + net::ConnectionAttempts* out) const { + transaction_->GetConnectionAttempts(out); +} + +void DevToolsNetworkTransaction::OnCallback(int rv) { + if (failed_ || callback_.is_null()) + return; + + if (callback_type_ == START || callback_type_ == READ) { + if (interceptor_ && interceptor_->ShouldThrottle(this)) { + Throttle(rv); + return; + } + } + + net::CompletionCallback original_callback = callback_; + callback_.Reset(); + callback_type_ = NONE; + original_callback.Run(rv); +} + +int DevToolsNetworkTransaction::SetupCallback( + net::CompletionCallback callback, + int result, + CallbackType callback_type) { + DCHECK(callback_type_ == NONE); + + if (result == net::ERR_IO_PENDING) { + callback_type_ = callback_type; + callback_ = callback; + return result; + } + + if (!interceptor_ || !interceptor_->ShouldThrottle(this)) + return result; + + // Only START and READ operation throttling is supported. + if (callback_type != START && callback_type != READ) + return result; + + // In case of error |throttled_byte_count_| is unknown. + if (result < 0) + return result; + + // URLRequestJob relies on synchronous end-of-stream notification. + if (callback_type == READ && result == 0) + return result; + + callback_type_ = callback_type; + callback_ = callback; + Throttle(result); + return net::ERR_IO_PENDING; +} + +void DevToolsNetworkTransaction::Throttle(int result) { + throttled_result_ = result; + + if (callback_type_ == START) + throttled_byte_count_ += transaction_->GetTotalReceivedBytes(); + if (result > 0) + throttled_byte_count_ += result; + + if (interceptor_) + interceptor_->ThrottleTransaction(this, callback_type_ == START); +} + +void DevToolsNetworkTransaction::FireThrottledCallback() { + DCHECK(!callback_.is_null()); + DCHECK(callback_type_ == READ || callback_type_ == START); + + net::CompletionCallback original_callback = callback_; + callback_.Reset(); + callback_type_ = NONE; + original_callback.Run(throttled_result_); +} + +} // namespace brightray diff --git a/brightray/browser/net/devtools_network_transaction.h b/brightray/browser/net/devtools_network_transaction.h new file mode 100644 index 00000000000..19295bf0dc7 --- /dev/null +++ b/brightray/browser/net/devtools_network_transaction.h @@ -0,0 +1,131 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BROWSER_DEVTOOLS_NETWORK_TRANSACTION_H_ +#define BROWSER_DEVTOOLS_NETWORK_TRANSACTION_H_ + +#include + +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "net/base/completion_callback.h" +#include "net/base/load_states.h" +#include "net/base/request_priority.h" +#include "net/http/http_transaction.h" +#include "net/websockets/websocket_handshake_stream_base.h" + +namespace brightray { + +class DevToolsNetworkController; +class DevToolsNetworkInterceptor; + +class DevToolsNetworkTransaction : public net::HttpTransaction { + public: + DevToolsNetworkTransaction( + DevToolsNetworkController* controller, + scoped_ptr network_transaction); + ~DevToolsNetworkTransaction() override; + + // Checks if request contains DevTools specific headers. Found values are + // remembered and corresponding keys are removed from headers. + void ProcessRequest(); + + // Runs callback with net::ERR_INTERNET_DISCONNECTED result. + void Fail(); + + void DecreaseThrottledByteCount(int64_t delta); + void FireThrottledCallback(); + + // HttpTransaction methods: + int Start(const net::HttpRequestInfo* request, + const net::CompletionCallback& callback, + const net::BoundNetLog& net_log) override; + int RestartIgnoringLastError( + const net::CompletionCallback& callback) override; + int RestartWithCertificate(net::X509Certificate* client_cert, + const net::CompletionCallback& callback) override; + int RestartWithAuth(const net::AuthCredentials& credentials, + const net::CompletionCallback& callback) override; + bool IsReadyToRestartForAuth() override; + + int Read(net::IOBuffer* buf, + int buf_len, + const net::CompletionCallback& callback) override; + void StopCaching() override; + bool GetFullRequestHeaders(net::HttpRequestHeaders* headers) const override; + int64_t GetTotalReceivedBytes() const override; + void DoneReading() override; + const net::HttpResponseInfo* GetResponseInfo() const override; + net::LoadState GetLoadState() const override; + net::UploadProgress GetUploadProgress() const override; + void SetQuicServerInfo(net::QuicServerInfo* quic_server_info) override; + bool GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override; + void SetPriority(net::RequestPriority priority) override; + void SetWebSocketHandshakeStreamCreateHelper( + net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) override; + void SetBeforeNetworkStartCallback( + const BeforeNetworkStartCallback& callback) override; + void SetBeforeProxyHeadersSentCallback( + const BeforeProxyHeadersSentCallback& callback) override; + int ResumeNetworkStart() override; + void GetConnectionAttempts(net::ConnectionAttempts* out) const override; + + bool failed() const { return failed_; } + + const net::HttpRequestInfo* request() const { return request_; } + + int64_t throttled_byte_count() const { return throttled_byte_count_; } + + const std::string& client_id() const { + return client_id_; + } + + private: + enum CallbackType { + NONE, + READ, + RESTART_IGNORING_LAST_ERROR, + RESTART_WITH_AUTH, + RESTART_WITH_CERTIFICATE, + START + }; + + // Proxy callback handler. Runs saved callback. + void OnCallback(int result); + + int SetupCallback( + net::CompletionCallback callback, + int result, + CallbackType callback_type); + void Throttle(int result); + + DevToolsNetworkController* controller_; + base::WeakPtr interceptor_; + + // Modified request. Should be destructed after |transaction_| + scoped_ptr custom_request_; + + // Original network transaction. + scoped_ptr transaction_; + + const net::HttpRequestInfo* request_; + + // True if Fail was already invoked. + bool failed_; + + // Value of "X-DevTools-Emulate-Network-Conditions-Client-Id" request header. + std::string client_id_; + + int throttled_result_; + int64_t throttled_byte_count_; + CallbackType callback_type_; + net::CompletionCallback proxy_callback_; + net::CompletionCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkTransaction); +}; + +} // namespace brightray + +#endif // BROWSER_DEVTOOLS_NETWORK_TRANSACTION_H_ diff --git a/brightray/browser/net/devtools_network_transaction_factory.cc b/brightray/browser/net/devtools_network_transaction_factory.cc new file mode 100644 index 00000000000..72367112f8f --- /dev/null +++ b/brightray/browser/net/devtools_network_transaction_factory.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#include "browser/net/devtools_network_transaction_factory.h" + +#include "browser/net/devtools_network_controller.h" +#include "browser/net/devtools_network_transaction.h" + +#include "net/base/net_errors.h" +#include "net/http/http_network_layer.h" +#include "net/http/http_network_transaction.h" + +namespace brightray { + +DevToolsNetworkTransactionFactory::DevToolsNetworkTransactionFactory( + DevToolsNetworkController* controller, + net::HttpNetworkSession* session) + : controller_(controller), + network_layer_(new net::HttpNetworkLayer(session)) { +} + +DevToolsNetworkTransactionFactory::~DevToolsNetworkTransactionFactory() { +} + +int DevToolsNetworkTransactionFactory::CreateTransaction( + net::RequestPriority priority, + scoped_ptr* transaction) { + scoped_ptr new_transaction; + int rv = network_layer_->CreateTransaction(priority, &new_transaction); + if (rv != net::OK) + return rv; + transaction->reset(new DevToolsNetworkTransaction(controller_, new_transaction.Pass())); + return net::OK; +} + +net::HttpCache* DevToolsNetworkTransactionFactory::GetCache() { + return network_layer_->GetCache(); +} + +net::HttpNetworkSession* DevToolsNetworkTransactionFactory::GetSession() { + return network_layer_->GetSession(); +} + +} // namespace brightray diff --git a/brightray/browser/net/devtools_network_transaction_factory.h b/brightray/browser/net/devtools_network_transaction_factory.h new file mode 100644 index 00000000000..a14d97c1d13 --- /dev/null +++ b/brightray/browser/net/devtools_network_transaction_factory.h @@ -0,0 +1,39 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE-CHROMIUM file. + +#ifndef BROWSER_DEVTOOLS_NETWORK_TRANSACTION_FACTORY_H_ +#define BROWSER_DEVTOOLS_NETWORK_TRANSACTION_FACTORY_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "net/base/request_priority.h" +#include "net/http/http_transaction_factory.h" + +namespace brightray { + +class DevToolsNetworkController; + +class DevToolsNetworkTransactionFactory : public net::HttpTransactionFactory { + public: + explicit DevToolsNetworkTransactionFactory( + DevToolsNetworkController* controller, + net::HttpNetworkSession* session); + ~DevToolsNetworkTransactionFactory() override; + + // net::HttpTransactionFactory: + int CreateTransaction(net::RequestPriority priority, + scoped_ptr* transaction) override; + net::HttpCache* GetCache() override; + net::HttpNetworkSession* GetSession() override; + + private: + DevToolsNetworkController* controller_; + scoped_ptr network_layer_; + + DISALLOW_COPY_AND_ASSIGN(DevToolsNetworkTransactionFactory); +}; + +} // namespace brightray + +#endif // BROWSER_DEVTOOLS_NETWORK_TRANSACTION_FACTORY_H_ diff --git a/brightray/browser/url_request_context_getter.cc b/brightray/browser/url_request_context_getter.cc index 4150b777f7a..840e86ce9c0 100644 --- a/brightray/browser/url_request_context_getter.cc +++ b/brightray/browser/url_request_context_getter.cc @@ -6,6 +6,8 @@ #include +#include "browser/net/devtools_network_controller.h" +#include "browser/net/devtools_network_transaction_factory.h" #include "browser/net_log.h" #include "browser/network_delegate.h" @@ -123,6 +125,7 @@ net::SSLConfigService* URLRequestContextGetter::Delegate::CreateSSLConfigService URLRequestContextGetter::URLRequestContextGetter( Delegate* delegate, + DevToolsNetworkController* controller, NetLog* net_log, const base::FilePath& base_path, bool in_memory, @@ -131,6 +134,7 @@ URLRequestContextGetter::URLRequestContextGetter( content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector protocol_interceptors) : delegate_(delegate), + controller_(controller), net_log_(net_log), base_path_(base_path), in_memory_(in_memory), @@ -279,13 +283,17 @@ net::URLRequestContext* URLRequestContextGetter::GetURLRequestContext() { storage_->set_host_resolver(host_resolver.Pass()); network_session_params.host_resolver = url_request_context_->host_resolver(); + net::HttpNetworkSession* session = new net::HttpNetworkSession(network_session_params); net::HttpCache::BackendFactory* backend = nullptr; if (in_memory_) { backend = net::HttpCache::DefaultBackend::InMemory(0); } else { backend = delegate_->CreateHttpCacheBackendFactory(base_path_); } - storage_->set_http_transaction_factory(new net::HttpCache(network_session_params, backend)); + storage_->set_http_transaction_factory(new net::HttpCache( + new DevToolsNetworkTransactionFactory(controller_, session), + url_request_context_->net_log(), + backend)); storage_->set_job_factory(delegate_->CreateURLRequestJobFactory( &protocol_handlers_, &protocol_interceptors_)); diff --git a/brightray/browser/url_request_context_getter.h b/brightray/browser/url_request_context_getter.h index 830171a52c2..4794f1bf6e5 100644 --- a/brightray/browser/url_request_context_getter.h +++ b/brightray/browser/url_request_context_getter.h @@ -27,6 +27,7 @@ class URLRequestJobFactory; namespace brightray { +class DevToolsNetworkController; class NetLog; class URLRequestContextGetter : public net::URLRequestContextGetter { @@ -48,6 +49,7 @@ class URLRequestContextGetter : public net::URLRequestContextGetter { URLRequestContextGetter( Delegate* delegate, + DevToolsNetworkController* controller, NetLog* net_log, const base::FilePath& base_path, bool in_memory, @@ -66,6 +68,7 @@ class URLRequestContextGetter : public net::URLRequestContextGetter { private: Delegate* delegate_; + DevToolsNetworkController* controller_; NetLog* net_log_; base::FilePath base_path_; bool in_memory_; diff --git a/brightray/filenames.gypi b/brightray/filenames.gypi index 8334e44cd5e..b614b6538f2 100644 --- a/brightray/filenames.gypi +++ b/brightray/filenames.gypi @@ -38,6 +38,18 @@ 'browser/media/media_capture_devices_dispatcher.h', 'browser/media/media_stream_devices_controller.cc', 'browser/media/media_stream_devices_controller.h', + 'browser/net/devtools_network_conditions.cc', + 'browser/net/devtools_network_conditions.h', + 'browser/net/devtools_network_controller.cc', + 'browser/net/devtools_network_controller.h', + 'browser/net/devtools_network_interceptor.cc', + 'browser/net/devtools_network_interceptor.h', + 'browser/net/devtools_network_protocol_handler.cc', + 'browser/net/devtools_network_protocol_handler.h', + 'browser/net/devtools_network_transaction_factory.cc', + 'browser/net/devtools_network_transaction_factory.h', + 'browser/net/devtools_network_transaction.cc', + 'browser/net/devtools_network_transaction.h', 'browser/net_log.cc', 'browser/net_log.h', 'browser/network_delegate.cc',