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
content / browser / loader / reconnectable_url_loader_factory.h [blame]
// 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_