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"
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"
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
;
71 using content::BrowserThread
;
73 ProfileImplIOData::Handle::Handle(Profile
* profile
)
74 : io_data_(new ProfileImplIOData
),
77 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
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
,
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_
);
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
));
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
));
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(),
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
));
181 if (!media_request_context_getter_
) {
182 media_request_context_getter_
=
183 ChromeURLRequestContextGetter::CreateOriginalForMedia(
186 return media_request_context_getter_
;
189 scoped_refptr
<ChromeURLRequestContextGetter
>
190 ProfileImplIOData::Handle::GetExtensionsRequestContextGetter() const {
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
193 if (!extensions_request_context_getter_
) {
194 extensions_request_context_getter_
=
195 ChromeURLRequestContextGetter::CreateOriginalForExtensions(
198 return extensions_request_context_getter_
;
201 scoped_refptr
<ChromeURLRequestContextGetter
>
202 ProfileImplIOData::Handle::CreateIsolatedAppRequestContextGetter(
203 const base::FilePath
& partition_path
,
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());
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())
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(),
228 app_request_context_getter_map_
[descriptor
] = 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
240 CHECK(partition_path
!= profile_
->GetPath());
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())
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
;
264 void ProfileImplIOData::Handle::ClearNetworkingHistorySince(
266 const base::Closure
& completion
) {
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
270 BrowserThread::PostTask(
271 BrowserThread::IO
, FROM_HERE
,
273 &ProfileImplIOData::ClearNetworkingHistorySinceOnIOThread
,
274 base::Unretained(io_data_
),
279 void ProfileImplIOData::Handle::LazyInitialize() const {
283 // Set initialized_ to true at the beginning in case any of the objects
284 // below try to get the ResourceContext pointer.
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
,
298 io_data_
->safe_browsing_enabled()->MoveToThread(
299 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
));
301 io_data_
->InitializeOnUIThread(profile_
);
304 ProfileImplIOData::LazyParams::LazyParams()
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
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(
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)
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(),
442 main_context
->set_job_factory(main_job_factory_
.get());
444 #if defined(ENABLE_EXTENSIONS)
445 InitializeExtensionsRequestContext(profile_params
);
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
,
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
,
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
),
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);
528 app_backend
= new net::HttpCache::DefaultBackend(
530 ChooseCacheBackendType(),
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
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.
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
560 cookie_store
= content::CreatePersistentCookieStore(
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(),
586 top_job_factory
= job_factory
.PassAs
<net::URLRequestJobFactory
>();
588 context
->SetJobFactory(top_job_factory
.Pass());
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
;
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(
621 ChooseCacheBackendType(),
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.
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(),
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(
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
);