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 "content/public/browser/browser_context.h"
8 #include "content/browser/download/download_manager_impl.h"
9 #include "content/browser/indexed_db/indexed_db_context_impl.h"
10 #include "content/browser/loader/resource_dispatcher_host_impl.h"
11 #include "content/browser/storage_partition_impl_map.h"
12 #include "content/common/child_process_host_impl.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/content_browser_client.h"
15 #include "content/public/browser/site_instance.h"
16 #include "net/cookies/cookie_monster.h"
17 #include "net/cookies/cookie_store.h"
18 #include "net/ssl/server_bound_cert_service.h"
19 #include "net/ssl/server_bound_cert_store.h"
20 #include "net/url_request/url_request_context.h"
21 #include "net/url_request/url_request_context_getter.h"
22 #include "webkit/browser/database/database_tracker.h"
23 #include "webkit/browser/fileapi/external_mount_points.h"
26 using base::UserDataAdapter
;
30 // Only ~BrowserContext() is needed on iOS.
34 // Key names on BrowserContext.
35 const char kDownloadManagerKeyName
[] = "download_manager";
36 const char kStorageParitionMapKeyName
[] = "content_storage_partition_map";
38 #if defined(OS_CHROMEOS)
39 const char kMountPointsKey
[] = "mount_points";
40 #endif // defined(OS_CHROMEOS)
42 StoragePartitionImplMap
* GetStoragePartitionMap(
43 BrowserContext
* browser_context
) {
44 StoragePartitionImplMap
* partition_map
=
45 static_cast<StoragePartitionImplMap
*>(
46 browser_context
->GetUserData(kStorageParitionMapKeyName
));
48 partition_map
= new StoragePartitionImplMap(browser_context
);
49 browser_context
->SetUserData(kStorageParitionMapKeyName
, partition_map
);
54 StoragePartition
* GetStoragePartitionFromConfig(
55 BrowserContext
* browser_context
,
56 const std::string
& partition_domain
,
57 const std::string
& partition_name
,
59 StoragePartitionImplMap
* partition_map
=
60 GetStoragePartitionMap(browser_context
);
62 if (browser_context
->IsOffTheRecord())
65 return partition_map
->Get(partition_domain
, partition_name
, in_memory
);
68 void SaveSessionStateOnIOThread(
69 const scoped_refptr
<net::URLRequestContextGetter
>& context_getter
,
70 appcache::AppCacheService
* appcache_service
) {
71 net::URLRequestContext
* context
= context_getter
->GetURLRequestContext();
72 context
->cookie_store()->GetCookieMonster()->
73 SetForceKeepSessionState();
74 context
->server_bound_cert_service()->GetCertStore()->
75 SetForceKeepSessionState();
76 appcache_service
->set_force_keep_session_state();
79 void SaveSessionStateOnIndexedDBThread(
80 scoped_refptr
<IndexedDBContextImpl
> indexed_db_context
) {
81 indexed_db_context
->SetForceKeepSessionState();
87 void BrowserContext::AsyncObliterateStoragePartition(
88 BrowserContext
* browser_context
,
90 const base::Closure
& on_gc_required
) {
91 GetStoragePartitionMap(browser_context
)->AsyncObliterate(site
,
96 void BrowserContext::GarbageCollectStoragePartitions(
97 BrowserContext
* browser_context
,
98 scoped_ptr
<base::hash_set
<base::FilePath
> > active_paths
,
99 const base::Closure
& done
) {
100 GetStoragePartitionMap(browser_context
)->GarbageCollect(
101 active_paths
.Pass(), done
);
104 DownloadManager
* BrowserContext::GetDownloadManager(
105 BrowserContext
* context
) {
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
107 if (!context
->GetUserData(kDownloadManagerKeyName
)) {
108 ResourceDispatcherHostImpl
* rdh
= ResourceDispatcherHostImpl::Get();
110 DownloadManager
* download_manager
=
111 new DownloadManagerImpl(
112 GetContentClient()->browser()->GetNetLog(), context
);
114 context
->SetUserData(
115 kDownloadManagerKeyName
,
117 download_manager
->SetDelegate(context
->GetDownloadManagerDelegate());
120 return static_cast<DownloadManager
*>(
121 context
->GetUserData(kDownloadManagerKeyName
));
125 fileapi::ExternalMountPoints
* BrowserContext::GetMountPoints(
126 BrowserContext
* context
) {
127 // Ensure that these methods are called on the UI thread, except for
128 // unittests where a UI thread might not have been created.
129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
) ||
130 !BrowserThread::IsMessageLoopValid(BrowserThread::UI
));
132 #if defined(OS_CHROMEOS)
133 if (!context
->GetUserData(kMountPointsKey
)) {
134 scoped_refptr
<fileapi::ExternalMountPoints
> mount_points
=
135 fileapi::ExternalMountPoints::CreateRefCounted();
136 context
->SetUserData(
138 new UserDataAdapter
<fileapi::ExternalMountPoints
>(mount_points
.get()));
141 return UserDataAdapter
<fileapi::ExternalMountPoints
>::Get(
142 context
, kMountPointsKey
);
148 StoragePartition
* BrowserContext::GetStoragePartition(
149 BrowserContext
* browser_context
,
150 SiteInstance
* site_instance
) {
151 std::string partition_domain
;
152 std::string partition_name
;
153 bool in_memory
= false;
155 // TODO(ajwong): After GetDefaultStoragePartition() is removed, get rid of
156 // this conditional and require that |site_instance| is non-NULL.
158 GetContentClient()->browser()->GetStoragePartitionConfigForSite(
159 browser_context
, site_instance
->GetSiteURL(), true,
160 &partition_domain
, &partition_name
, &in_memory
);
163 return GetStoragePartitionFromConfig(
164 browser_context
, partition_domain
, partition_name
, in_memory
);
167 StoragePartition
* BrowserContext::GetStoragePartitionForSite(
168 BrowserContext
* browser_context
,
170 std::string partition_domain
;
171 std::string partition_name
;
174 GetContentClient()->browser()->GetStoragePartitionConfigForSite(
175 browser_context
, site
, true, &partition_domain
, &partition_name
,
178 return GetStoragePartitionFromConfig(
179 browser_context
, partition_domain
, partition_name
, in_memory
);
182 void BrowserContext::ForEachStoragePartition(
183 BrowserContext
* browser_context
,
184 const StoragePartitionCallback
& callback
) {
185 StoragePartitionImplMap
* partition_map
=
186 static_cast<StoragePartitionImplMap
*>(
187 browser_context
->GetUserData(kStorageParitionMapKeyName
));
191 partition_map
->ForEach(callback
);
194 StoragePartition
* BrowserContext::GetDefaultStoragePartition(
195 BrowserContext
* browser_context
) {
196 return GetStoragePartition(browser_context
, NULL
);
199 void BrowserContext::EnsureResourceContextInitialized(BrowserContext
* context
) {
200 // This will be enough to tickle initialization of BrowserContext if
201 // necessary, which initializes ResourceContext. The reason we don't call
202 // ResourceContext::InitializeResourceContext() directly here is that
203 // ResourceContext initialization may call back into BrowserContext
204 // and when that call returns it'll end rewriting its UserData map. It will
205 // end up rewriting the same value but this still causes a race condition.
207 // See http://crbug.com/115678.
208 GetDefaultStoragePartition(context
);
211 void BrowserContext::SaveSessionState(BrowserContext
* browser_context
) {
212 GetDefaultStoragePartition(browser_context
)->GetDatabaseTracker()->
213 SetForceKeepSessionState();
214 StoragePartition
* storage_partition
=
215 BrowserContext::GetDefaultStoragePartition(browser_context
);
217 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO
)) {
218 BrowserThread::PostTask(
219 BrowserThread::IO
, FROM_HERE
,
221 &SaveSessionStateOnIOThread
,
222 make_scoped_refptr(browser_context
->GetRequestContext()),
223 storage_partition
->GetAppCacheService()));
226 DOMStorageContextWrapper
* dom_storage_context_proxy
=
227 static_cast<DOMStorageContextWrapper
*>(
228 storage_partition
->GetDOMStorageContext());
229 dom_storage_context_proxy
->SetForceKeepSessionState();
231 IndexedDBContextImpl
* indexed_db_context_impl
=
232 static_cast<IndexedDBContextImpl
*>(
233 storage_partition
->GetIndexedDBContext());
234 // No task runner in unit tests.
235 if (indexed_db_context_impl
->TaskRunner()) {
236 indexed_db_context_impl
->TaskRunner()->PostTask(
238 base::Bind(&SaveSessionStateOnIndexedDBThread
,
239 make_scoped_refptr(indexed_db_context_impl
)));
245 BrowserContext::~BrowserContext() {
247 if (GetUserData(kDownloadManagerKeyName
))
248 GetDownloadManager(this)->Shutdown();
252 } // namespace content