Override server-side simple-cache trial with commandline switches.
[chromium-blink-merge.git] / chrome / browser / profiles / profile_impl_io_data.cc
blob32be9ba32ffa253844db9c70121a84c2f496e902
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/profiles/profile_impl_io_data.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/file_util.h"
10 #include "base/logging.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/prefs/pref_member.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/stl_util.h"
16 #include "base/string_util.h"
17 #include "base/threading/sequenced_worker_pool.h"
18 #include "base/threading/worker_pool.h"
19 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
20 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
21 #include "chrome/browser/io_thread.h"
22 #include "chrome/browser/net/chrome_net_log.h"
23 #include "chrome/browser/net/chrome_network_delegate.h"
24 #include "chrome/browser/net/connect_interceptor.h"
25 #include "chrome/browser/net/http_server_properties_manager.h"
26 #include "chrome/browser/net/predictor.h"
27 #include "chrome/browser/net/sqlite_server_bound_cert_store.h"
28 #include "chrome/browser/profiles/profile.h"
29 #include "chrome/common/chrome_constants.h"
30 #include "chrome/common/chrome_notification_types.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/pref_names.h"
33 #include "chrome/common/url_constants.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/browser/cookie_store_factory.h"
36 #include "content/public/browser/notification_service.h"
37 #include "content/public/browser/resource_context.h"
38 #include "content/public/browser/storage_partition.h"
39 #include "extensions/common/constants.h"
40 #include "net/base/cache_type.h"
41 #include "net/ftp/ftp_network_layer.h"
42 #include "net/http/http_cache.h"
43 #include "net/ssl/server_bound_cert_service.h"
44 #include "net/url_request/protocol_intercept_job_factory.h"
45 #include "net/url_request/url_request_job_factory_impl.h"
46 #include "webkit/quota/special_storage_policy.h"
48 namespace {
50 net::BackendType ChooseCacheBackendType() {
51 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
52 if (command_line.HasSwitch(switches::kUseSimpleCacheBackend)) {
53 const std::string opt_value =
54 command_line.GetSwitchValueASCII(switches::kUseSimpleCacheBackend);
55 if (LowerCaseEqualsASCII(opt_value, "off"))
56 return net::CACHE_BACKEND_BLOCKFILE;
57 if (opt_value == "" || LowerCaseEqualsASCII(opt_value, "on"))
58 return net::CACHE_BACKEND_SIMPLE;
60 const std::string experiment_name =
61 base::FieldTrialList::FindFullName("SimpleCacheTrial");
62 if (experiment_name == "ExperimentYes" ||
63 experiment_name == "ExperimentYes2") {
64 return net::CACHE_BACKEND_SIMPLE;
66 return net::CACHE_BACKEND_BLOCKFILE;
69 } // namespace
71 using content::BrowserThread;
73 ProfileImplIOData::Handle::Handle(Profile* profile)
74 : io_data_(new ProfileImplIOData),
75 profile_(profile),
76 initialized_(false) {
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
78 DCHECK(profile);
81 ProfileImplIOData::Handle::~Handle() {
82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
83 if (io_data_->predictor_ != NULL) {
84 // io_data_->predictor_ might be NULL if Init() was never called
85 // (i.e. we shut down before ProfileImpl::DoFinalInit() got called).
86 PrefService* user_prefs = profile_->GetPrefs();
87 io_data_->predictor_->ShutdownOnUIThread(user_prefs);
90 if (io_data_->http_server_properties_manager_)
91 io_data_->http_server_properties_manager_->ShutdownOnUIThread();
92 io_data_->ShutdownOnUIThread();
95 void ProfileImplIOData::Handle::Init(
96 const base::FilePath& cookie_path,
97 const base::FilePath& server_bound_cert_path,
98 const base::FilePath& cache_path,
99 int cache_max_size,
100 const base::FilePath& media_cache_path,
101 int media_cache_max_size,
102 const base::FilePath& extensions_cookie_path,
103 const base::FilePath& profile_path,
104 const base::FilePath& infinite_cache_path,
105 chrome_browser_net::Predictor* predictor,
106 bool restore_old_session_cookies,
107 quota::SpecialStoragePolicy* special_storage_policy) {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
109 DCHECK(!io_data_->lazy_params_);
110 DCHECK(predictor);
112 LazyParams* lazy_params = new LazyParams;
114 lazy_params->cookie_path = cookie_path;
115 lazy_params->server_bound_cert_path = server_bound_cert_path;
116 lazy_params->cache_path = cache_path;
117 lazy_params->cache_max_size = cache_max_size;
118 lazy_params->media_cache_path = media_cache_path;
119 lazy_params->media_cache_max_size = media_cache_max_size;
120 lazy_params->extensions_cookie_path = extensions_cookie_path;
121 lazy_params->infinite_cache_path = infinite_cache_path;
122 lazy_params->restore_old_session_cookies = restore_old_session_cookies;
123 lazy_params->special_storage_policy = special_storage_policy;
125 io_data_->lazy_params_.reset(lazy_params);
127 // Keep track of profile path and cache sizes separately so we can use them
128 // on demand when creating storage isolated URLRequestContextGetters.
129 io_data_->profile_path_ = profile_path;
130 io_data_->app_cache_max_size_ = cache_max_size;
131 io_data_->app_media_cache_max_size_ = media_cache_max_size;
133 io_data_->predictor_.reset(predictor);
135 io_data_->InitializeMetricsEnabledStateOnUIThread();
138 content::ResourceContext*
139 ProfileImplIOData::Handle::GetResourceContext() const {
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
141 LazyInitialize();
142 return GetResourceContextNoInit();
145 content::ResourceContext*
146 ProfileImplIOData::Handle::GetResourceContextNoInit() const {
147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
148 // Don't call LazyInitialize here, since the resource context is created at
149 // the beginning of initalization and is used by some members while they're
150 // being initialized (i.e. AppCacheService).
151 return io_data_->GetResourceContext();
154 scoped_refptr<ChromeURLRequestContextGetter>
155 ProfileImplIOData::Handle::CreateMainRequestContextGetter(
156 content::ProtocolHandlerMap* protocol_handlers,
157 PrefService* local_state,
158 IOThread* io_thread) const {
159 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
160 LazyInitialize();
161 DCHECK(!main_request_context_getter_);
162 main_request_context_getter_ = ChromeURLRequestContextGetter::CreateOriginal(
163 profile_, io_data_, protocol_handlers);
165 io_data_->predictor_->InitNetworkPredictor(profile_->GetPrefs(),
166 local_state,
167 io_thread,
168 main_request_context_getter_);
170 content::NotificationService::current()->Notify(
171 chrome::NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
172 content::Source<Profile>(profile_),
173 content::NotificationService::NoDetails());
174 return main_request_context_getter_;
177 scoped_refptr<ChromeURLRequestContextGetter>
178 ProfileImplIOData::Handle::GetMediaRequestContextGetter() const {
179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
180 LazyInitialize();
181 if (!media_request_context_getter_) {
182 media_request_context_getter_ =
183 ChromeURLRequestContextGetter::CreateOriginalForMedia(
184 profile_, io_data_);
186 return media_request_context_getter_;
189 scoped_refptr<ChromeURLRequestContextGetter>
190 ProfileImplIOData::Handle::GetExtensionsRequestContextGetter() const {
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
192 LazyInitialize();
193 if (!extensions_request_context_getter_) {
194 extensions_request_context_getter_ =
195 ChromeURLRequestContextGetter::CreateOriginalForExtensions(
196 profile_, io_data_);
198 return extensions_request_context_getter_;
201 scoped_refptr<ChromeURLRequestContextGetter>
202 ProfileImplIOData::Handle::CreateIsolatedAppRequestContextGetter(
203 const base::FilePath& partition_path,
204 bool in_memory,
205 content::ProtocolHandlerMap* protocol_handlers) const {
206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
207 // Check that the partition_path is not the same as the base profile path. We
208 // expect isolated partition, which will never go to the default profile path.
209 CHECK(partition_path != profile_->GetPath());
210 LazyInitialize();
212 // Keep a map of request context getters, one per requested storage partition.
213 StoragePartitionDescriptor descriptor(partition_path, in_memory);
214 ChromeURLRequestContextGetterMap::iterator iter =
215 app_request_context_getter_map_.find(descriptor);
216 if (iter != app_request_context_getter_map_.end())
217 return iter->second;
219 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
220 protocol_handler_interceptor(
221 ProtocolHandlerRegistryFactory::GetForProfile(profile_)->
222 CreateJobInterceptorFactory());
223 ChromeURLRequestContextGetter* context =
224 ChromeURLRequestContextGetter::CreateOriginalForIsolatedApp(
225 profile_, io_data_, descriptor,
226 protocol_handler_interceptor.Pass(),
227 protocol_handlers);
228 app_request_context_getter_map_[descriptor] = context;
230 return context;
233 scoped_refptr<ChromeURLRequestContextGetter>
234 ProfileImplIOData::Handle::GetIsolatedMediaRequestContextGetter(
235 const base::FilePath& partition_path,
236 bool in_memory) const {
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
238 // We must have a non-default path, or this will act like the default media
239 // context.
240 CHECK(partition_path != profile_->GetPath());
241 LazyInitialize();
243 // Keep a map of request context getters, one per requested storage partition.
244 StoragePartitionDescriptor descriptor(partition_path, in_memory);
245 ChromeURLRequestContextGetterMap::iterator iter =
246 isolated_media_request_context_getter_map_.find(descriptor);
247 if (iter != isolated_media_request_context_getter_map_.end())
248 return iter->second;
250 // Get the app context as the starting point for the media context, so that
251 // it uses the app's cookie store.
252 ChromeURLRequestContextGetterMap::const_iterator app_iter =
253 app_request_context_getter_map_.find(descriptor);
254 DCHECK(app_iter != app_request_context_getter_map_.end());
255 ChromeURLRequestContextGetter* app_context = app_iter->second;
256 ChromeURLRequestContextGetter* context =
257 ChromeURLRequestContextGetter::CreateOriginalForIsolatedMedia(
258 profile_, app_context, io_data_, descriptor);
259 isolated_media_request_context_getter_map_[descriptor] = context;
261 return context;
264 void ProfileImplIOData::Handle::ClearNetworkingHistorySince(
265 base::Time time,
266 const base::Closure& completion) {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
268 LazyInitialize();
270 BrowserThread::PostTask(
271 BrowserThread::IO, FROM_HERE,
272 base::Bind(
273 &ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread,
274 base::Unretained(io_data_),
275 time,
276 completion));
279 void ProfileImplIOData::Handle::LazyInitialize() const {
280 if (initialized_)
281 return;
283 // Set initialized_ to true at the beginning in case any of the objects
284 // below try to get the ResourceContext pointer.
285 initialized_ = true;
286 PrefService* pref_service = profile_->GetPrefs();
287 io_data_->http_server_properties_manager_ =
288 new chrome_browser_net::HttpServerPropertiesManager(pref_service);
289 io_data_->set_http_server_properties(
290 io_data_->http_server_properties_manager_);
291 io_data_->session_startup_pref()->Init(
292 prefs::kRestoreOnStartup, pref_service);
293 io_data_->session_startup_pref()->MoveToThread(
294 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
295 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
296 io_data_->safe_browsing_enabled()->Init(prefs::kSafeBrowsingEnabled,
297 pref_service);
298 io_data_->safe_browsing_enabled()->MoveToThread(
299 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO));
300 #endif
301 io_data_->InitializeOnUIThread(profile_);
304 ProfileImplIOData::LazyParams::LazyParams()
305 : cache_max_size(0),
306 media_cache_max_size(0),
307 restore_old_session_cookies(false) {}
309 ProfileImplIOData::LazyParams::~LazyParams() {}
311 ProfileImplIOData::ProfileImplIOData()
312 : ProfileIOData(false),
313 http_server_properties_manager_(NULL) {}
314 ProfileImplIOData::~ProfileImplIOData() {
315 DestroyResourceContext();
317 if (media_request_context_)
318 media_request_context_->AssertNoURLRequests();
321 void ProfileImplIOData::InitializeInternal(
322 ProfileParams* profile_params,
323 content::ProtocolHandlerMap* protocol_handlers) const {
324 ChromeURLRequestContext* main_context = main_request_context();
326 IOThread* const io_thread = profile_params->io_thread;
327 IOThread::Globals* const io_thread_globals = io_thread->globals();
328 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
329 // Only allow Record Mode if we are in a Debug build or where we are running
330 // a cycle, and the user has limited control.
331 bool record_mode = command_line.HasSwitch(switches::kRecordMode) &&
332 (chrome::kRecordModeEnabled ||
333 command_line.HasSwitch(switches::kVisitURLs));
334 bool playback_mode = command_line.HasSwitch(switches::kPlaybackMode);
336 network_delegate()->set_predictor(predictor_.get());
338 // Initialize context members.
340 ApplyProfileParamsToContext(main_context);
342 if (http_server_properties_manager_)
343 http_server_properties_manager_->InitializeOnIOThread();
345 main_context->set_transport_security_state(transport_security_state());
347 main_context->set_net_log(io_thread->net_log());
349 main_context->set_network_delegate(network_delegate());
351 main_context->set_http_server_properties(http_server_properties());
353 main_context->set_host_resolver(
354 io_thread_globals->host_resolver.get());
355 main_context->set_http_auth_handler_factory(
356 io_thread_globals->http_auth_handler_factory.get());
358 main_context->set_fraudulent_certificate_reporter(
359 fraudulent_certificate_reporter());
361 main_context->set_throttler_manager(
362 io_thread_globals->throttler_manager.get());
364 main_context->set_proxy_service(proxy_service());
366 scoped_refptr<net::CookieStore> cookie_store = NULL;
367 net::ServerBoundCertService* server_bound_cert_service = NULL;
368 if (record_mode || playback_mode) {
369 // Don't use existing cookies and use an in-memory store.
370 cookie_store = new net::CookieMonster(
371 NULL, profile_params->cookie_monster_delegate);
372 // Don't use existing server-bound certs and use an in-memory store.
373 server_bound_cert_service = new net::ServerBoundCertService(
374 new net::DefaultServerBoundCertStore(NULL),
375 base::WorkerPool::GetTaskRunner(true));
378 // setup cookie store
379 if (!cookie_store) {
380 DCHECK(!lazy_params_->cookie_path.empty());
382 cookie_store = content::CreatePersistentCookieStore(
383 lazy_params_->cookie_path,
384 lazy_params_->restore_old_session_cookies,
385 lazy_params_->special_storage_policy,
386 profile_params->cookie_monster_delegate);
387 cookie_store->GetCookieMonster()->SetPersistSessionCookies(true);
390 main_context->set_cookie_store(cookie_store);
392 // Setup server bound cert service.
393 if (!server_bound_cert_service) {
394 DCHECK(!lazy_params_->server_bound_cert_path.empty());
396 scoped_refptr<SQLiteServerBoundCertStore> server_bound_cert_db =
397 new SQLiteServerBoundCertStore(
398 lazy_params_->server_bound_cert_path,
399 lazy_params_->special_storage_policy);
400 server_bound_cert_service = new net::ServerBoundCertService(
401 new net::DefaultServerBoundCertStore(server_bound_cert_db.get()),
402 base::WorkerPool::GetTaskRunner(true));
405 set_server_bound_cert_service(server_bound_cert_service);
406 main_context->set_server_bound_cert_service(server_bound_cert_service);
408 net::HttpCache::DefaultBackend* main_backend =
409 new net::HttpCache::DefaultBackend(
410 net::DISK_CACHE,
411 ChooseCacheBackendType(),
412 lazy_params_->cache_path,
413 lazy_params_->cache_max_size,
414 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
415 net::HttpNetworkSession::Params network_session_params;
416 PopulateNetworkSessionParams(profile_params, &network_session_params);
417 net::HttpCache* main_cache = new net::HttpCache(
418 network_session_params, main_backend);
419 main_cache->InitializeInfiniteCache(lazy_params_->infinite_cache_path);
421 if (record_mode || playback_mode) {
422 main_cache->set_mode(
423 record_mode ? net::HttpCache::RECORD : net::HttpCache::PLAYBACK);
426 main_http_factory_.reset(main_cache);
427 main_context->set_http_transaction_factory(main_cache);
429 #if !defined(DISABLE_FTP_SUPPORT)
430 ftp_factory_.reset(
431 new net::FtpNetworkLayer(io_thread_globals->host_resolver.get()));
432 #endif // !defined(DISABLE_FTP_SUPPORT)
434 scoped_ptr<net::URLRequestJobFactoryImpl> main_job_factory(
435 new net::URLRequestJobFactoryImpl());
436 InstallProtocolHandlers(main_job_factory.get(), protocol_handlers);
437 main_job_factory_ = SetUpJobFactoryDefaults(
438 main_job_factory.Pass(),
439 profile_params->protocol_handler_interceptor.Pass(),
440 network_delegate(),
441 ftp_factory_.get());
442 main_context->set_job_factory(main_job_factory_.get());
444 #if defined(ENABLE_EXTENSIONS)
445 InitializeExtensionsRequestContext(profile_params);
446 #endif
448 // Create a media request context based on the main context, but using a
449 // media cache. It shares the same job factory as the main context.
450 StoragePartitionDescriptor details(profile_path_, false);
451 media_request_context_.reset(InitializeMediaRequestContext(main_context,
452 details));
454 lazy_params_.reset();
457 void ProfileImplIOData::
458 InitializeExtensionsRequestContext(ProfileParams* profile_params) const {
459 ChromeURLRequestContext* extensions_context = extensions_request_context();
460 IOThread* const io_thread = profile_params->io_thread;
461 IOThread::Globals* const io_thread_globals = io_thread->globals();
462 ApplyProfileParamsToContext(extensions_context);
464 extensions_context->set_transport_security_state(transport_security_state());
466 extensions_context->set_net_log(io_thread->net_log());
468 extensions_context->set_throttler_manager(
469 io_thread_globals->throttler_manager.get());
471 net::CookieStore* extensions_cookie_store =
472 content::CreatePersistentCookieStore(
473 lazy_params_->extensions_cookie_path,
474 lazy_params_->restore_old_session_cookies,
475 NULL,
476 NULL);
477 // Enable cookies for devtools and extension URLs.
478 const char* schemes[] = {chrome::kChromeDevToolsScheme,
479 extensions::kExtensionScheme};
480 extensions_cookie_store->GetCookieMonster()->SetCookieableSchemes(schemes, 2);
481 extensions_context->set_cookie_store(extensions_cookie_store);
483 scoped_ptr<net::URLRequestJobFactoryImpl> extensions_job_factory(
484 new net::URLRequestJobFactoryImpl());
485 // TODO(shalev): The extensions_job_factory has a NULL NetworkDelegate.
486 // Without a network_delegate, this protocol handler will never
487 // handle file: requests, but as a side effect it makes
488 // job_factory::IsHandledProtocol return true, which prevents attempts to
489 // handle the protocol externally. We pass NULL in to
490 // SetUpJobFactory() to get this effect.
491 extensions_job_factory_ = SetUpJobFactoryDefaults(
492 extensions_job_factory.Pass(),
493 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>(NULL),
494 NULL,
495 ftp_factory_.get());
496 extensions_context->set_job_factory(extensions_job_factory_.get());
499 ChromeURLRequestContext*
500 ProfileImplIOData::InitializeAppRequestContext(
501 ChromeURLRequestContext* main_context,
502 const StoragePartitionDescriptor& partition_descriptor,
503 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
504 protocol_handler_interceptor,
505 content::ProtocolHandlerMap* protocol_handlers) const {
506 // Copy most state from the main context.
507 AppRequestContext* context = new AppRequestContext(load_time_stats());
508 context->CopyFrom(main_context);
510 base::FilePath cookie_path = partition_descriptor.path.Append(
511 chrome::kCookieFilename);
512 base::FilePath cache_path =
513 partition_descriptor.path.Append(chrome::kCacheDirname);
515 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
516 // Only allow Record Mode if we are in a Debug build or where we are running
517 // a cycle, and the user has limited control.
518 bool record_mode = command_line.HasSwitch(switches::kRecordMode) &&
519 (chrome::kRecordModeEnabled ||
520 command_line.HasSwitch(switches::kVisitURLs));
521 bool playback_mode = command_line.HasSwitch(switches::kPlaybackMode);
523 // Use a separate HTTP disk cache for isolated apps.
524 net::HttpCache::BackendFactory* app_backend = NULL;
525 if (partition_descriptor.in_memory) {
526 app_backend = net::HttpCache::DefaultBackend::InMemory(0);
527 } else {
528 app_backend = new net::HttpCache::DefaultBackend(
529 net::DISK_CACHE,
530 ChooseCacheBackendType(),
531 cache_path,
532 app_cache_max_size_,
533 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
535 net::HttpNetworkSession* main_network_session =
536 main_http_factory_->GetSession();
537 net::HttpCache* app_http_cache =
538 new net::HttpCache(main_network_session, app_backend);
540 scoped_refptr<net::CookieStore> cookie_store = NULL;
541 if (partition_descriptor.in_memory) {
542 cookie_store = new net::CookieMonster(NULL, NULL);
543 } else if (record_mode || playback_mode) {
544 // Don't use existing cookies and use an in-memory store.
545 // TODO(creis): We should have a cookie delegate for notifying the cookie
546 // extensions API, but we need to update it to understand isolated apps
547 // first.
548 cookie_store = new net::CookieMonster(NULL, NULL);
549 app_http_cache->set_mode(
550 record_mode ? net::HttpCache::RECORD : net::HttpCache::PLAYBACK);
553 // Use an app-specific cookie store.
554 if (!cookie_store) {
555 DCHECK(!cookie_path.empty());
557 // TODO(creis): We should have a cookie delegate for notifying the cookie
558 // extensions API, but we need to update it to understand isolated apps
559 // first.
560 cookie_store = content::CreatePersistentCookieStore(
561 cookie_path,
562 false,
563 NULL,
564 NULL);
567 // Transfer ownership of the cookies and cache to AppRequestContext.
568 context->SetCookieStore(cookie_store);
569 context->SetHttpTransactionFactory(
570 scoped_ptr<net::HttpTransactionFactory>(app_http_cache));
572 scoped_ptr<net::URLRequestJobFactoryImpl> job_factory(
573 new net::URLRequestJobFactoryImpl());
574 InstallProtocolHandlers(job_factory.get(), protocol_handlers);
575 scoped_ptr<net::URLRequestJobFactory> top_job_factory;
576 // Overwrite the job factory that we inherit from the main context so
577 // that we can later provide our own handlers for storage related protocols.
578 // Install all the usual protocol handlers unless we are in a browser plugin
579 // guest process, in which case only web-safe schemes are allowed.
580 if (!partition_descriptor.in_memory) {
581 top_job_factory = SetUpJobFactoryDefaults(
582 job_factory.Pass(), protocol_handler_interceptor.Pass(),
583 network_delegate(),
584 ftp_factory_.get());
585 } else {
586 top_job_factory = job_factory.PassAs<net::URLRequestJobFactory>();
588 context->SetJobFactory(top_job_factory.Pass());
590 return context;
593 ChromeURLRequestContext*
594 ProfileImplIOData::InitializeMediaRequestContext(
595 ChromeURLRequestContext* original_context,
596 const StoragePartitionDescriptor& partition_descriptor) const {
597 // If this is for a in_memory partition, we can simply use the original
598 // context (like off-the-record mode).
599 if (partition_descriptor.in_memory)
600 return original_context;
602 // Copy most state from the original context.
603 MediaRequestContext* context = new MediaRequestContext(load_time_stats());
604 context->CopyFrom(original_context);
606 using content::StoragePartition;
607 base::FilePath cache_path;
608 int cache_max_size = app_media_cache_max_size_;
609 if (partition_descriptor.path == profile_path_) {
610 // lazy_params_ is only valid for the default media context creation.
611 cache_path = lazy_params_->media_cache_path;
612 cache_max_size = lazy_params_->media_cache_max_size;
613 } else {
614 cache_path = partition_descriptor.path.Append(chrome::kMediaCacheDirname);
617 // Use a separate HTTP disk cache for isolated apps.
618 net::HttpCache::BackendFactory* media_backend =
619 new net::HttpCache::DefaultBackend(
620 net::MEDIA_CACHE,
621 ChooseCacheBackendType(),
622 cache_path,
623 cache_max_size,
624 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
625 net::HttpNetworkSession* main_network_session =
626 main_http_factory_->GetSession();
627 scoped_ptr<net::HttpTransactionFactory> media_http_cache(
628 new net::HttpCache(main_network_session, media_backend));
630 // Transfer ownership of the cache to MediaRequestContext.
631 context->SetHttpTransactionFactory(media_http_cache.Pass());
633 // Note that we do not create a new URLRequestJobFactory because
634 // the media context should behave exactly like its parent context
635 // in all respects except for cache behavior on media subresources.
636 // The CopyFrom() step above means that our media context will use
637 // the same URLRequestJobFactory instance that our parent context does.
639 return context;
642 ChromeURLRequestContext*
643 ProfileImplIOData::AcquireMediaRequestContext() const {
644 DCHECK(media_request_context_);
645 return media_request_context_.get();
648 ChromeURLRequestContext*
649 ProfileImplIOData::AcquireIsolatedAppRequestContext(
650 ChromeURLRequestContext* main_context,
651 const StoragePartitionDescriptor& partition_descriptor,
652 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
653 protocol_handler_interceptor,
654 content::ProtocolHandlerMap* protocol_handlers) const {
655 // We create per-app contexts on demand, unlike the others above.
656 ChromeURLRequestContext* app_request_context =
657 InitializeAppRequestContext(main_context, partition_descriptor,
658 protocol_handler_interceptor.Pass(),
659 protocol_handlers);
660 DCHECK(app_request_context);
661 return app_request_context;
664 ChromeURLRequestContext*
665 ProfileImplIOData::AcquireIsolatedMediaRequestContext(
666 ChromeURLRequestContext* app_context,
667 const StoragePartitionDescriptor& partition_descriptor) const {
668 // We create per-app media contexts on demand, unlike the others above.
669 ChromeURLRequestContext* media_request_context =
670 InitializeMediaRequestContext(app_context, partition_descriptor);
671 DCHECK(media_request_context);
672 return media_request_context;
675 chrome_browser_net::LoadTimeStats* ProfileImplIOData::GetLoadTimeStats(
676 IOThread::Globals* io_thread_globals) const {
677 return io_thread_globals->load_time_stats.get();
680 void ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread(
681 base::Time time,
682 const base::Closure& completion) {
683 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
684 DCHECK(initialized());
686 DCHECK(transport_security_state());
687 // Completes synchronously.
688 transport_security_state()->DeleteAllDynamicDataSince(time);
689 DCHECK(http_server_properties_manager_);
690 http_server_properties_manager_->Clear(completion);