Upstream version 10.38.220.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / net / chrome_url_request_context_getter.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/net/chrome_url_request_context_getter.h"
6
7 #include "base/bind.h"
8 #include "base/compiler_specific.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/io_thread.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/profiles/profile_io_data.h"
15 #include "chrome/browser/profiles/storage_partition_descriptor.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "net/cookies/cookie_store.h"
18
19 using content::BrowserThread;
20
21 class ChromeURLRequestContextFactory {
22  public:
23   ChromeURLRequestContextFactory() {}
24   virtual ~ChromeURLRequestContextFactory() {}
25
26   // Called to create a new instance (will only be called once).
27   virtual net::URLRequestContext* Create() = 0;
28
29  protected:
30   DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory);
31 };
32
33 namespace {
34
35 // ----------------------------------------------------------------------------
36 // Helper factories
37 // ----------------------------------------------------------------------------
38
39 // Factory that creates the main URLRequestContext.
40 class FactoryForMain : public ChromeURLRequestContextFactory {
41  public:
42   FactoryForMain(
43       const ProfileIOData* profile_io_data,
44       content::ProtocolHandlerMap* protocol_handlers,
45       content::URLRequestInterceptorScopedVector request_interceptors)
46       : profile_io_data_(profile_io_data),
47         request_interceptors_(request_interceptors.Pass()) {
48     std::swap(protocol_handlers_, *protocol_handlers);
49   }
50
51   virtual net::URLRequestContext* Create() OVERRIDE {
52     profile_io_data_->Init(&protocol_handlers_, request_interceptors_.Pass());
53     return profile_io_data_->GetMainRequestContext();
54   }
55
56  private:
57   const ProfileIOData* const profile_io_data_;
58   content::ProtocolHandlerMap protocol_handlers_;
59   content::URLRequestInterceptorScopedVector request_interceptors_;
60 };
61
62 // Factory that creates the URLRequestContext for extensions.
63 class FactoryForExtensions : public ChromeURLRequestContextFactory {
64  public:
65   explicit FactoryForExtensions(const ProfileIOData* profile_io_data)
66       : profile_io_data_(profile_io_data) {}
67
68   virtual net::URLRequestContext* Create() OVERRIDE {
69     return profile_io_data_->GetExtensionsRequestContext();
70   }
71
72  private:
73   const ProfileIOData* const profile_io_data_;
74 };
75
76 // Factory that creates the URLRequestContext for a given isolated app.
77 class FactoryForIsolatedApp : public ChromeURLRequestContextFactory {
78  public:
79   FactoryForIsolatedApp(
80       const ProfileIOData* profile_io_data,
81       const StoragePartitionDescriptor& partition_descriptor,
82       ChromeURLRequestContextGetter* main_context,
83       scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
84           protocol_handler_interceptor,
85       content::ProtocolHandlerMap* protocol_handlers,
86       content::URLRequestInterceptorScopedVector request_interceptors)
87       : profile_io_data_(profile_io_data),
88         partition_descriptor_(partition_descriptor),
89         main_request_context_getter_(main_context),
90         protocol_handler_interceptor_(protocol_handler_interceptor.Pass()),
91         request_interceptors_(request_interceptors.Pass()) {
92     std::swap(protocol_handlers_, *protocol_handlers);
93   }
94
95   virtual net::URLRequestContext* Create() OVERRIDE {
96     // We will copy most of the state from the main request context.
97     //
98     // Note that this factory is one-shot.  After Create() is called once, the
99     // factory is actually destroyed. Thus it is safe to destructively pass
100     // state onwards.
101     return profile_io_data_->GetIsolatedAppRequestContext(
102         main_request_context_getter_->GetURLRequestContext(),
103         partition_descriptor_,
104         protocol_handler_interceptor_.Pass(),
105         &protocol_handlers_,
106         request_interceptors_.Pass());
107   }
108
109  private:
110   const ProfileIOData* const profile_io_data_;
111   const StoragePartitionDescriptor partition_descriptor_;
112   scoped_refptr<ChromeURLRequestContextGetter>
113       main_request_context_getter_;
114   scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
115       protocol_handler_interceptor_;
116   content::ProtocolHandlerMap protocol_handlers_;
117   content::URLRequestInterceptorScopedVector request_interceptors_;
118 };
119
120 // Factory that creates the media URLRequestContext for a given isolated
121 // app.  The media context is based on the corresponding isolated app's context.
122 class FactoryForIsolatedMedia : public ChromeURLRequestContextFactory {
123  public:
124   FactoryForIsolatedMedia(
125       const ProfileIOData* profile_io_data,
126       const StoragePartitionDescriptor& partition_descriptor,
127       ChromeURLRequestContextGetter* app_context)
128     : profile_io_data_(profile_io_data),
129       partition_descriptor_(partition_descriptor),
130       app_context_getter_(app_context) {}
131
132   virtual net::URLRequestContext* Create() OVERRIDE {
133     // We will copy most of the state from the corresopnding app's
134     // request context. We expect to have the same lifetime as
135     // the associated |app_context_getter_| so we can just reuse
136     // all its backing objects, including the
137     // |protocol_handler_interceptor|.  This is why the API
138     // looks different from FactoryForIsolatedApp's.
139     return profile_io_data_->GetIsolatedMediaRequestContext(
140         app_context_getter_->GetURLRequestContext(), partition_descriptor_);
141   }
142
143  private:
144   const ProfileIOData* const profile_io_data_;
145   const StoragePartitionDescriptor partition_descriptor_;
146   scoped_refptr<ChromeURLRequestContextGetter> app_context_getter_;
147 };
148
149 // Factory that creates the URLRequestContext for media.
150 class FactoryForMedia : public ChromeURLRequestContextFactory {
151  public:
152   explicit FactoryForMedia(const ProfileIOData* profile_io_data)
153       : profile_io_data_(profile_io_data) {
154   }
155
156   virtual net::URLRequestContext* Create() OVERRIDE {
157     return profile_io_data_->GetMediaRequestContext();
158   }
159
160  private:
161   const ProfileIOData* const profile_io_data_;
162 };
163
164 }  // namespace
165
166 // ----------------------------------------------------------------------------
167 // ChromeURLRequestContextGetter
168 // ----------------------------------------------------------------------------
169
170 ChromeURLRequestContextGetter::ChromeURLRequestContextGetter(
171     ChromeURLRequestContextFactory* factory)
172     : factory_(factory),
173       url_request_context_(NULL) {
174   DCHECK(factory);
175 }
176
177 ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {}
178
179 // Lazily create a URLRequestContext using our factory.
180 net::URLRequestContext*
181 ChromeURLRequestContextGetter::GetURLRequestContext() {
182   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
183
184   if (factory_.get()) {
185     DCHECK(!url_request_context_);
186     url_request_context_ = factory_->Create();
187     factory_.reset();
188   }
189
190   // Context reference is valid, unless we're trying to use the
191   // URLRequestContextGetter after the Profile has already been deleted.
192   CHECK(url_request_context_);
193
194   return url_request_context_;
195 }
196
197 void ChromeURLRequestContextGetter::Invalidate() {
198   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
199   factory_.reset();
200   url_request_context_ = NULL;
201 }
202
203 scoped_refptr<base::SingleThreadTaskRunner>
204 ChromeURLRequestContextGetter::GetNetworkTaskRunner() const {
205   return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
206 }
207
208 // static
209 ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::Create(
210     Profile* profile,
211     const ProfileIOData* profile_io_data,
212     content::ProtocolHandlerMap* protocol_handlers,
213     content::URLRequestInterceptorScopedVector request_interceptors) {
214   return new ChromeURLRequestContextGetter(new FactoryForMain(
215       profile_io_data, protocol_handlers, request_interceptors.Pass()));
216 }
217
218 // static
219 ChromeURLRequestContextGetter*
220 ChromeURLRequestContextGetter::CreateForMedia(
221     Profile* profile, const ProfileIOData* profile_io_data) {
222   return new ChromeURLRequestContextGetter(
223       new FactoryForMedia(profile_io_data));
224 }
225
226 // static
227 ChromeURLRequestContextGetter*
228 ChromeURLRequestContextGetter::CreateForExtensions(
229     Profile* profile, const ProfileIOData* profile_io_data) {
230   return new ChromeURLRequestContextGetter(
231       new FactoryForExtensions(profile_io_data));
232 }
233
234 // static
235 ChromeURLRequestContextGetter*
236 ChromeURLRequestContextGetter::CreateForIsolatedApp(
237     Profile* profile,
238     const ProfileIOData* profile_io_data,
239     const StoragePartitionDescriptor& partition_descriptor,
240     scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
241         protocol_handler_interceptor,
242     content::ProtocolHandlerMap* protocol_handlers,
243     content::URLRequestInterceptorScopedVector request_interceptors) {
244   ChromeURLRequestContextGetter* main_context =
245       static_cast<ChromeURLRequestContextGetter*>(profile->GetRequestContext());
246   return new ChromeURLRequestContextGetter(
247       new FactoryForIsolatedApp(profile_io_data,
248                                 partition_descriptor,
249                                 main_context,
250                                 protocol_handler_interceptor.Pass(),
251                                 protocol_handlers,
252                                 request_interceptors.Pass()));
253 }
254
255 // static
256 ChromeURLRequestContextGetter*
257 ChromeURLRequestContextGetter::CreateForIsolatedMedia(
258     Profile* profile,
259     ChromeURLRequestContextGetter* app_context,
260     const ProfileIOData* profile_io_data,
261     const StoragePartitionDescriptor& partition_descriptor) {
262   return new ChromeURLRequestContextGetter(
263       new FactoryForIsolatedMedia(
264           profile_io_data, partition_descriptor, app_context));
265 }