1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_LOADER_RECONNECTABLE_URL_LOADER_FACTORY_H_
#define CONTENT_BROWSER_LOADER_RECONNECTABLE_URL_LOADER_FACTORY_H_
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace content {
// SharedURLLoaderFactory that caches and reuses a URLLoaderFactory remote
// created by its `CreateCallback`, and re-create and reconnect if the cached
// remote is disconnected.
// All methods (including the `CreateCallback` and the destructor) must be/are
// called on the original sequence.
// TODO(crbug.com/40947547): Merge `ReconnectableURLLoaderFactoryForIOThread`
// and rename the file.
class CONTENT_EXPORT ReconnectableURLLoaderFactory final
: public network::SharedURLLoaderFactory {
public:
// On success:
// Creates and assigns a new URLLoaderFactory to the output parameter.
//
// On failure (e.g., underlying network context is gone):
// Leaves the output parameter unchanged.
// Cancellation of the callback is usually achieved by binding a WeakPtr to
// it in the caller's context.
using CreateCallback = base::RepeatingCallback<void(
mojo::PendingRemote<network::mojom::URLLoaderFactory>*)>;
// The constructor doesn't call `create_url_loader_factory_callback`
// synchronously.
explicit ReconnectableURLLoaderFactory(
CreateCallback create_url_loader_factory_callback);
ReconnectableURLLoaderFactory(const ReconnectableURLLoaderFactory&) = delete;
ReconnectableURLLoaderFactory& operator=(
const ReconnectableURLLoaderFactory&) = delete;
void Reset();
void FlushForTesting();
// mojom::URLLoaderFactory implementation:
void CreateLoaderAndStart(
mojo::PendingReceiver<network::mojom::URLLoader> receiver,
int32_t request_id,
uint32_t options,
const network::ResourceRequest& url_request,
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
override;
void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
override;
// SharedURLLoaderFactory implementation:
std::unique_ptr<network::PendingSharedURLLoaderFactory> Clone() override;
private:
friend class base::RefCounted<ReconnectableURLLoaderFactory>;
~ReconnectableURLLoaderFactory() override;
// URLLoaderFactory caching mechanism only accessed from the original thread.
network::mojom::URLLoaderFactory* GetURLLoaderFactory();
mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory_;
bool is_test_url_loader_factory_ = false;
const CreateCallback create_url_loader_factory_callback_;
SEQUENCE_CHECKER(sequence_checker_);
};
// Similar to `ReconnectableURLLoaderFactory`, but this IO-thread-only version
// caches a URLLoaderFactory on IO thread at
// `ReconnectableURLLoaderFactoryForIOThread::url_loader_factory_` and
// re-creates and reconnects it if needed.
//
// `ReconnectableURLLoaderFactoryForIOThread` must live on UI thread (just
// because it is hard-coded using `GetUIThreadTaskRunner`).
class CONTENT_EXPORT ReconnectableURLLoaderFactoryForIOThread final
: public base::RefCountedThreadSafe<
ReconnectableURLLoaderFactoryForIOThread,
BrowserThread::DeleteOnIOThread> {
public:
using CreateCallback = ReconnectableURLLoaderFactory::CreateCallback;
// Initializes this object on the UI thread. Similar to
// `ReconnectableURLLoaderFactory`, this caches and reuses a URLLoaderFactory
// remote created by its `CreateCallback`, and re-create and reconnect if the
// cached remote is disconnected.
// The constructor doesn't call `create_url_loader_factory_callback`
// synchronously.
// `create_url_loader_factory_callback` is always called on UI thread, but can
// be destroyed either on UI or IO thread.
explicit ReconnectableURLLoaderFactoryForIOThread(
CreateCallback create_url_loader_factory_callback);
ReconnectableURLLoaderFactoryForIOThread(
const ReconnectableURLLoaderFactoryForIOThread&) = delete;
ReconnectableURLLoaderFactoryForIOThread& operator=(
const ReconnectableURLLoaderFactoryForIOThread&) = delete;
// Eagerly trigger initialization for the use for IO thread. Note that, even
// if `Initialize()` is not called, `CloneForIOThread()` still can
// be used and is lazily initialized when the created
// `PendingSharedURLLoaderFactory` is actually used.
void Initialize();
// Called on the UI thread to create a PendingSharedURLLoaderFactory that
// holds a reference to this ReconnectableURLLoaderFactoryForIOThread, which
// can be used on IO thread to construct a SharedURLLoaderFactory that can be
// used to access the URLLoaderFactory to the network service and supports
// auto-reconnect after crash.
std::unique_ptr<network::PendingSharedURLLoaderFactory> CloneForIOThread();
void Reset();
// Call |url_loader_factory_.FlushForTesting()| on IO thread. For test use
// only.
void FlushForTesting();
private:
class PendingURLLoaderFactoryForIOThread;
class URLLoaderFactoryForIOThread;
friend class base::DeleteHelper<ReconnectableURLLoaderFactoryForIOThread>;
friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
~ReconnectableURLLoaderFactoryForIOThread();
void InitializeOnIOThread(
mojo::PendingRemote<network::mojom::URLLoaderFactory> network_factory);
// Moves |network_factory| to |url_loader_factory_| and sets up an error
// handler.
void ReinitializeOnIOThread(
mojo::Remote<network::mojom::URLLoaderFactory> network_factory);
// Send |network_factory_request| to cached |StoragePartitionImpl|.
void HandleNetworkFactoryRequestOnUIThread(
mojo::PendingReceiver<network::mojom::URLLoaderFactory>
network_factory_receiver);
// Called on the IO thread to get the URLLoaderFactory to the network service.
// The pointer shouldn't be cached.
network::mojom::URLLoaderFactory* GetURLLoaderFactory();
// Call |url_loader_factory_.FlushForTesting()|. For test use only. When the
// flush is complete, |callback| will be called.
void FlushOnIOThreadForTesting(base::OnceClosure callback);
// Cached URLLoaderFactory only used from the IO thread.
mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory_;
bool is_test_url_loader_factory_ = false;
// Only accessed on UI thread.
const CreateCallback create_url_loader_factory_callback_;
};
// Bundles `ReconnectableURLLoaderFactoryForIOThread` and
// `ReconnectableURLLoaderFactory`. The two classes are held separately by this
// wrapper instead of e.g. being merged into a single object, so that
// `scoped_refptr` for one of them doesn't affect the lifetime of the other.
class CONTENT_EXPORT ReconnectableURLLoaderFactoryForIOThreadWrapper final {
public:
using CreateCallback = ReconnectableURLLoaderFactory::CreateCallback;
// The constructor doesn't call `create_url_loader_factory_callback`
// synchronously.
// `create_url_loader_factory_callback` is always called on UI thread, but can
// be destroyed either on UI or IO thread.
explicit ReconnectableURLLoaderFactoryForIOThreadWrapper(
CreateCallback create_url_loader_factory_callback);
ReconnectableURLLoaderFactoryForIOThreadWrapper(
const ReconnectableURLLoaderFactoryForIOThreadWrapper&) = delete;
ReconnectableURLLoaderFactoryForIOThreadWrapper& operator=(
const ReconnectableURLLoaderFactoryForIOThreadWrapper&) = delete;
~ReconnectableURLLoaderFactoryForIOThreadWrapper();
// Always non-null.
const scoped_refptr<ReconnectableURLLoaderFactory>& factory() const {
return factory_;
}
const scoped_refptr<ReconnectableURLLoaderFactoryForIOThread>&
factory_for_io_thread() const {
return factory_for_io_thread_;
}
private:
scoped_refptr<ReconnectableURLLoaderFactory> factory_;
scoped_refptr<ReconnectableURLLoaderFactoryForIOThread>
factory_for_io_thread_;
};
} // namespace content
#endif // CONTENT_BROWSER_LOADER_RECONNECTABLE_URL_LOADER_FACTORY_H_
|