blob: 4ec3a2051611b3689bd6bbd566ba1ff625d901eb [file] [log] [blame]
// Copyright 2017 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 "content/browser/url_loader_factory_getter.h"
#include "base/bind.h"
#include "base/lazy_instance.h"
#include "content/browser/storage_partition_impl.h"
#include "services/network/public/mojom/network_service.mojom.h"
namespace content {
namespace {
base::LazyInstance<URLLoaderFactoryGetter::GetNetworkFactoryCallback>::Leaky
g_get_network_factory_callback = LAZY_INSTANCE_INITIALIZER;
}
URLLoaderFactoryGetter::URLLoaderFactoryGetter() {}
void URLLoaderFactoryGetter::Initialize(StoragePartitionImpl* partition) {
DCHECK(partition);
partition_ = partition;
network::mojom::URLLoaderFactoryPtr network_factory;
HandleNetworkFactoryRequestOnUIThread(MakeRequest(&network_factory));
network::mojom::URLLoaderFactoryPtr blob_factory;
partition_->GetBlobURLLoaderFactory()->HandleRequest(
mojo::MakeRequest(&blob_factory));
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&URLLoaderFactoryGetter::InitializeOnIOThread, this,
network_factory.PassInterface(),
blob_factory.PassInterface()));
}
void URLLoaderFactoryGetter::OnStoragePartitionDestroyed() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
partition_ = nullptr;
}
network::mojom::URLLoaderFactory* URLLoaderFactoryGetter::GetNetworkFactory() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (g_get_network_factory_callback.Get() && !test_factory_)
g_get_network_factory_callback.Get().Run(this);
if (test_factory_)
return test_factory_;
if (!network_factory_.is_bound() || network_factory_.encountered_error()) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(
&URLLoaderFactoryGetter::HandleNetworkFactoryRequestOnUIThread,
this, mojo::MakeRequest(&network_factory_)));
}
return network_factory_.get();
}
network::mojom::URLLoaderFactory* URLLoaderFactoryGetter::GetBlobFactory() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return blob_factory_.get();
}
void URLLoaderFactoryGetter::SetNetworkFactoryForTesting(
network::mojom::URLLoaderFactory* test_factory) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!test_factory_ || !test_factory);
test_factory_ = test_factory;
}
void URLLoaderFactoryGetter::SetGetNetworkFactoryCallbackForTesting(
const GetNetworkFactoryCallback& get_network_factory_callback) {
DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::IO) ||
BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(!g_get_network_factory_callback.Get() ||
!get_network_factory_callback);
g_get_network_factory_callback.Get() = get_network_factory_callback;
}
void URLLoaderFactoryGetter::FlushNetworkInterfaceOnIOThreadForTesting() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::RunLoop run_loop;
BrowserThread::PostTaskAndReply(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&URLLoaderFactoryGetter::FlushNetworkInterfaceForTesting,
this),
run_loop.QuitClosure());
run_loop.Run();
}
void URLLoaderFactoryGetter::FlushNetworkInterfaceForTesting() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (network_factory_)
network_factory_.FlushForTesting();
}
URLLoaderFactoryGetter::~URLLoaderFactoryGetter() {}
void URLLoaderFactoryGetter::InitializeOnIOThread(
network::mojom::URLLoaderFactoryPtrInfo network_factory,
network::mojom::URLLoaderFactoryPtrInfo blob_factory) {
network_factory_.Bind(std::move(network_factory));
blob_factory_.Bind(std::move(blob_factory));
}
void URLLoaderFactoryGetter::HandleNetworkFactoryRequestOnUIThread(
network::mojom::URLLoaderFactoryRequest network_factory_request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// |StoragePartitionImpl| may have went away while |URLLoaderFactoryGetter| is
// still held by consumers.
if (!partition_)
return;
partition_->GetNetworkContext()->CreateURLLoaderFactory(
std::move(network_factory_request), 0);
}
} // namespace content