blob: 06176d94c5b847586a44f338dd905ffdb36cd01f [file] [log] [blame]
// 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 "services/network/throttling/throttling_controller.h"
#include "net/http/http_request_info.h"
#include "services/network/throttling/network_conditions.h"
#include "services/network/throttling/scoped_throttling_token.h"
#include "services/network/throttling/throttling_network_interceptor.h"
namespace network {
ThrottlingController* ThrottlingController::instance_ = nullptr;
ThrottlingController::ThrottlingController() = default;
ThrottlingController::~ThrottlingController() = default;
// static
void ThrottlingController::SetConditions(
const base::UnguessableToken& throttling_profile_id,
std::unique_ptr<NetworkConditions> conditions) {
if (!instance_) {
if (!conditions)
return;
instance_ = new ThrottlingController();
}
instance_->SetNetworkConditions(throttling_profile_id, std::move(conditions));
}
// static
ThrottlingNetworkInterceptor* ThrottlingController::GetInterceptor(
uint32_t net_log_source_id) {
if (!instance_)
return nullptr;
return instance_->FindInterceptor(net_log_source_id);
}
// static
void ThrottlingController::RegisterProfileIDForNetLogSource(
uint32_t net_log_source_id,
const base::UnguessableToken& throttling_profile_id) {
if (!instance_)
return;
instance_->Register(net_log_source_id, throttling_profile_id);
}
// static
void ThrottlingController::UnregisterNetLogSource(uint32_t net_log_source_id) {
if (instance_)
instance_->Unregister(net_log_source_id);
}
// static
bool ThrottlingController::HasInterceptor(
const base::UnguessableToken& throttling_profile_id) {
// Null |instance_| means there is no network condition registered.
if (!instance_)
return false;
return instance_->interceptors_.find(throttling_profile_id) !=
instance_->interceptors_.end();
}
void ThrottlingController::Register(
uint32_t net_log_source_id,
const base::UnguessableToken& throttling_profile_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (interceptors_.find(throttling_profile_id) == interceptors_.end())
return;
net_log_source_profile_map_[net_log_source_id] = throttling_profile_id;
}
void ThrottlingController::Unregister(uint32_t net_log_source_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
net_log_source_profile_map_.erase(net_log_source_id);
}
base::Optional<base::UnguessableToken> ThrottlingController::GetProfileID(
uint32_t net_log_source_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto it = net_log_source_profile_map_.find(net_log_source_id);
if (it == net_log_source_profile_map_.end())
return base::nullopt;
return it->second;
}
void ThrottlingController::SetNetworkConditions(
const base::UnguessableToken& throttling_profile_id,
std::unique_ptr<NetworkConditions> conditions) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto it = interceptors_.find(throttling_profile_id);
if (it == interceptors_.end()) {
if (!conditions)
return;
std::unique_ptr<ThrottlingNetworkInterceptor> new_interceptor(
new ThrottlingNetworkInterceptor());
new_interceptor->UpdateConditions(std::move(conditions));
interceptors_[throttling_profile_id] = std::move(new_interceptor);
} else {
if (!conditions) {
std::unique_ptr<NetworkConditions> online_conditions(
new NetworkConditions());
it->second->UpdateConditions(std::move(online_conditions));
interceptors_.erase(throttling_profile_id);
if (interceptors_.empty()) {
delete this;
instance_ = nullptr;
}
} else {
it->second->UpdateConditions(std::move(conditions));
}
}
}
ThrottlingNetworkInterceptor* ThrottlingController::FindInterceptor(
uint32_t net_log_source_id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
auto source_profile_map_it =
net_log_source_profile_map_.find(net_log_source_id);
if (source_profile_map_it == net_log_source_profile_map_.end())
return nullptr;
auto it = interceptors_.find(source_profile_map_it->second);
return it != interceptors_.end() ? it->second.get() : nullptr;
}
} // namespace network