blob: 522ccd108edc29658a73f380f2713a33e3b10a37 [file] [log] [blame]
[email protected]55eb70e762012-02-20 17:38:391// 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.
4
5#include "content/public/browser/browser_context.h"
6
7#include "content/browser/appcache/chrome_appcache_service.h"
[email protected]1ea3c792012-04-17 01:25:048#include "content/browser/dom_storage/dom_storage_context_impl.h"
[email protected]d25fda12012-06-12 17:05:039#include "content/browser/download/download_file_manager.h"
[email protected]b441a8492012-06-06 14:55:5710#include "content/browser/download/download_manager_impl.h"
[email protected]16dd6e22012-03-01 19:08:2011#include "content/browser/fileapi/browser_file_system_helper.h"
[email protected]6e2d3d22012-02-24 18:10:3612#include "content/browser/in_process_webkit/indexed_db_context_impl.h"
[email protected]d25fda12012-06-12 17:05:0313#include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
[email protected]314c3e22012-02-21 03:57:4214#include "content/browser/resource_context_impl.h"
[email protected]55eb70e762012-02-20 17:38:3915#include "content/public/browser/browser_thread.h"
[email protected]b441a8492012-06-06 14:55:5716#include "content/public/browser/content_browser_client.h"
[email protected]55eb70e762012-02-20 17:38:3917#include "content/public/common/content_constants.h"
[email protected]bf510ed2012-06-05 08:31:4318#include "net/base/server_bound_cert_service.h"
19#include "net/base/server_bound_cert_store.h"
[email protected]4d7c4ef2012-03-16 01:47:1220#include "net/cookies/cookie_monster.h"
21#include "net/cookies/cookie_store.h"
[email protected]6e2d3d22012-02-24 18:10:3622#include "net/url_request/url_request_context.h"
[email protected]55eb70e762012-02-20 17:38:3923#include "webkit/database/database_tracker.h"
24#include "webkit/quota/quota_manager.h"
25
[email protected]314c3e22012-02-21 03:57:4226using appcache::AppCacheService;
27using base::UserDataAdapter;
[email protected]55eb70e762012-02-20 17:38:3928using content::BrowserThread;
29using fileapi::FileSystemContext;
30using quota::QuotaManager;
31using webkit_database::DatabaseTracker;
32
[email protected]314c3e22012-02-21 03:57:4233// Key names on BrowserContext.
[email protected]55eb70e762012-02-20 17:38:3934static const char* kAppCacheServicKeyName = "content_appcache_service_tracker";
[email protected]55eb70e762012-02-20 17:38:3935static const char* kDatabaseTrackerKeyName = "content_database_tracker";
[email protected]c1fff072012-02-24 23:38:1236static const char* kDOMStorageContextKeyName = "content_dom_storage_context";
[email protected]b441a8492012-06-06 14:55:5737static const char* kDownloadManagerKeyName = "download_manager";
[email protected]55eb70e762012-02-20 17:38:3938static const char* kFileSystemContextKeyName = "content_file_system_context";
[email protected]c1fff072012-02-24 23:38:1239static const char* kIndexedDBContextKeyName = "content_indexed_db_context";
[email protected]55eb70e762012-02-20 17:38:3940static const char* kQuotaManagerKeyName = "content_quota_manager";
[email protected]55eb70e762012-02-20 17:38:3941
42namespace content {
43
[email protected]735e20c2012-03-20 01:16:5944namespace {
45
[email protected]55eb70e762012-02-20 17:38:3946void CreateQuotaManagerAndClients(BrowserContext* context) {
47 if (context->GetUserData(kQuotaManagerKeyName)) {
48 DCHECK(context->GetUserData(kDatabaseTrackerKeyName));
[email protected]c1fff072012-02-24 23:38:1249 DCHECK(context->GetUserData(kDOMStorageContextKeyName));
[email protected]55eb70e762012-02-20 17:38:3950 DCHECK(context->GetUserData(kFileSystemContextKeyName));
[email protected]c1fff072012-02-24 23:38:1251 DCHECK(context->GetUserData(kIndexedDBContextKeyName));
[email protected]55eb70e762012-02-20 17:38:3952 return;
53 }
54
55 // All of the clients have to be created and registered with the
56 // QuotaManager prior to the QuotaManger being used. So we do them
57 // all together here prior to handing out a reference to anything
58 // that utlizes the QuotaManager.
59 scoped_refptr<QuotaManager> quota_manager = new quota::QuotaManager(
60 context->IsOffTheRecord(), context->GetPath(),
61 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
62 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
63 context->GetSpecialStoragePolicy());
64 context->SetUserData(kQuotaManagerKeyName,
65 new UserDataAdapter<QuotaManager>(quota_manager));
66
67 // Each consumer is responsible for registering its QuotaClient during
68 // its construction.
69 scoped_refptr<FileSystemContext> filesystem_context = CreateFileSystemContext(
70 context->GetPath(), context->IsOffTheRecord(),
71 context->GetSpecialStoragePolicy(), quota_manager->proxy());
72 context->SetUserData(
73 kFileSystemContextKeyName,
74 new UserDataAdapter<FileSystemContext>(filesystem_context));
75
76 scoped_refptr<DatabaseTracker> db_tracker = new DatabaseTracker(
[email protected]142dd752012-02-27 22:27:4177 context->GetPath(), context->IsOffTheRecord(),
[email protected]55eb70e762012-02-20 17:38:3978 context->GetSpecialStoragePolicy(), quota_manager->proxy(),
79 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
[email protected]d25fda12012-06-12 17:05:0380 context->SetUserData(kDatabaseTrackerKeyName,
[email protected]55eb70e762012-02-20 17:38:3981 new UserDataAdapter<DatabaseTracker>(db_tracker));
82
[email protected]c1fff072012-02-24 23:38:1283 FilePath path = context->IsOffTheRecord() ? FilePath() : context->GetPath();
[email protected]5a9e47672012-03-15 04:08:5184 scoped_refptr<DOMStorageContextImpl> dom_storage_context =
[email protected]c1fff072012-02-24 23:38:1285 new DOMStorageContextImpl(path, context->GetSpecialStoragePolicy());
86 context->SetUserData(
87 kDOMStorageContextKeyName,
[email protected]5a9e47672012-03-15 04:08:5188 new UserDataAdapter<DOMStorageContextImpl>(dom_storage_context));
[email protected]c1fff072012-02-24 23:38:1289
90 scoped_refptr<IndexedDBContext> indexed_db_context = new IndexedDBContextImpl(
91 path, context->GetSpecialStoragePolicy(), quota_manager->proxy(),
[email protected]55eb70e762012-02-20 17:38:3992 BrowserThread::GetMessageLoopProxyForThread(
93 BrowserThread::WEBKIT_DEPRECATED));
[email protected]c1fff072012-02-24 23:38:1294 context->SetUserData(
95 kIndexedDBContextKeyName,
96 new UserDataAdapter<IndexedDBContext>(indexed_db_context));
[email protected]55eb70e762012-02-20 17:38:3997
98 scoped_refptr<ChromeAppCacheService> appcache_service =
99 new ChromeAppCacheService(quota_manager->proxy());
100 context->SetUserData(
101 kAppCacheServicKeyName,
102 new UserDataAdapter<ChromeAppCacheService>(appcache_service));
103
[email protected]7e26ac92012-02-27 20:15:05104 InitializeResourceContext(context);
[email protected]314c3e22012-02-21 03:57:42105
[email protected]55eb70e762012-02-20 17:38:39106 // Check first to avoid memory leak in unittests.
107 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
108 BrowserThread::PostTask(
[email protected]314c3e22012-02-21 03:57:42109 BrowserThread::IO, FROM_HERE,
110 base::Bind(&ChromeAppCacheService::InitializeOnIOThread,
111 appcache_service,
112 context->IsOffTheRecord() ? FilePath() :
113 context->GetPath().Append(content::kAppCacheDirname),
114 context->GetResourceContext(),
115 make_scoped_refptr(context->GetSpecialStoragePolicy())));
[email protected]55eb70e762012-02-20 17:38:39116 }
117}
118
[email protected]6e2d3d22012-02-24 18:10:36119void SaveSessionStateOnIOThread(ResourceContext* resource_context) {
120 resource_context->GetRequestContext()->cookie_store()->GetCookieMonster()->
[email protected]bf510ed2012-06-05 08:31:43121 SetForceKeepSessionState();
122 resource_context->GetRequestContext()->server_bound_cert_service()->
123 GetCertStore()->SetForceKeepSessionState();
124 ResourceContext::GetAppCacheService(resource_context)->
125 set_force_keep_session_state();
[email protected]6e2d3d22012-02-24 18:10:36126}
127
128void SaveSessionStateOnWebkitThread(
[email protected]6e2d3d22012-02-24 18:10:36129 scoped_refptr<IndexedDBContextImpl> indexed_db_context) {
[email protected]bf510ed2012-06-05 08:31:43130 indexed_db_context->SetForceKeepSessionState();
[email protected]6e2d3d22012-02-24 18:10:36131}
132
133void PurgeMemoryOnIOThread(ResourceContext* resource_context) {
134 ResourceContext::GetAppCacheService(resource_context)->PurgeMemory();
135}
136
[email protected]735e20c2012-03-20 01:16:59137DOMStorageContextImpl* GetDOMStorageContextImpl(BrowserContext* context) {
138 return static_cast<DOMStorageContextImpl*>(
139 BrowserContext::GetDOMStorageContext(context));
[email protected]6e2d3d22012-02-24 18:10:36140}
141
[email protected]735e20c2012-03-20 01:16:59142} // namespace
143
[email protected]b441a8492012-06-06 14:55:57144DownloadManager* BrowserContext::GetDownloadManager(
145 BrowserContext* context) {
146 if (!context->GetUserData(kDownloadManagerKeyName)) {
[email protected]d25fda12012-06-12 17:05:03147 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
148 DCHECK(rdh);
149 DownloadFileManager* file_manager = rdh->download_file_manager();
150 DCHECK(file_manager);
151 scoped_refptr<DownloadManager> download_manager =
152 new DownloadManagerImpl(
153 file_manager,
154 scoped_ptr<DownloadItemFactory>(),
155 GetContentClient()->browser()->GetNetLog());
156
[email protected]b441a8492012-06-06 14:55:57157 context->SetUserData(
158 kDownloadManagerKeyName,
159 new UserDataAdapter<DownloadManager>(download_manager));
160 download_manager->SetDelegate(context->GetDownloadManagerDelegate());
161 download_manager->Init(context);
162 }
163
164 return UserDataAdapter<DownloadManager>::Get(
165 context, kDownloadManagerKeyName);
166}
167
[email protected]55eb70e762012-02-20 17:38:39168QuotaManager* BrowserContext::GetQuotaManager(BrowserContext* context) {
169 CreateQuotaManagerAndClients(context);
170 return UserDataAdapter<QuotaManager>::Get(context, kQuotaManagerKeyName);
171}
172
[email protected]c1fff072012-02-24 23:38:12173DOMStorageContext* BrowserContext::GetDOMStorageContext(
174 BrowserContext* context) {
[email protected]55eb70e762012-02-20 17:38:39175 CreateQuotaManagerAndClients(context);
[email protected]5a9e47672012-03-15 04:08:51176 return UserDataAdapter<DOMStorageContextImpl>::Get(
[email protected]c1fff072012-02-24 23:38:12177 context, kDOMStorageContextKeyName);
178}
179
180IndexedDBContext* BrowserContext::GetIndexedDBContext(BrowserContext* context) {
181 CreateQuotaManagerAndClients(context);
182 return UserDataAdapter<IndexedDBContext>::Get(
183 context, kIndexedDBContextKeyName);
[email protected]55eb70e762012-02-20 17:38:39184}
185
186DatabaseTracker* BrowserContext::GetDatabaseTracker(BrowserContext* context) {
187 CreateQuotaManagerAndClients(context);
188 return UserDataAdapter<DatabaseTracker>::Get(
189 context, kDatabaseTrackerKeyName);
190}
191
[email protected]314c3e22012-02-21 03:57:42192AppCacheService* BrowserContext::GetAppCacheService(
[email protected]55eb70e762012-02-20 17:38:39193 BrowserContext* browser_context) {
194 CreateQuotaManagerAndClients(browser_context);
195 return UserDataAdapter<ChromeAppCacheService>::Get(
196 browser_context, kAppCacheServicKeyName);
197}
198
199FileSystemContext* BrowserContext::GetFileSystemContext(
200 BrowserContext* browser_context) {
201 CreateQuotaManagerAndClients(browser_context);
202 return UserDataAdapter<FileSystemContext>::Get(
203 browser_context, kFileSystemContextKeyName);
204}
205
[email protected]314c3e22012-02-21 03:57:42206void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) {
[email protected]7e26ac92012-02-27 20:15:05207 // This will be enough to tickle initialization of BrowserContext if
208 // necessary, which initializes ResourceContext. The reason we don't call
209 // ResourceContext::InitializeResourceContext directly here is that if
210 // ResourceContext ends up initializing it will call back into BrowserContext
211 // and when that call return it'll end rewriting its UserData map (with the
212 // same value) but this causes a race condition. See http://crbug.com/115678.
213 CreateQuotaManagerAndClients(context);
[email protected]55eb70e762012-02-20 17:38:39214}
215
[email protected]6e2d3d22012-02-24 18:10:36216void BrowserContext::SaveSessionState(BrowserContext* browser_context) {
[email protected]bf510ed2012-06-05 08:31:43217 GetDatabaseTracker(browser_context)->SetForceKeepSessionState();
[email protected]6e2d3d22012-02-24 18:10:36218
219 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
220 BrowserThread::PostTask(
221 BrowserThread::IO, FROM_HERE,
222 base::Bind(&SaveSessionStateOnIOThread,
223 browser_context->GetResourceContext()));
224 }
225
[email protected]bf510ed2012-06-05 08:31:43226 GetDOMStorageContextImpl(browser_context)->SetForceKeepSessionState();
[email protected]735e20c2012-03-20 01:16:59227
[email protected]6e2d3d22012-02-24 18:10:36228 if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) {
[email protected]6e2d3d22012-02-24 18:10:36229 IndexedDBContextImpl* indexed_db = static_cast<IndexedDBContextImpl*>(
[email protected]c1fff072012-02-24 23:38:12230 GetIndexedDBContext(browser_context));
[email protected]6e2d3d22012-02-24 18:10:36231 BrowserThread::PostTask(
232 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE,
233 base::Bind(&SaveSessionStateOnWebkitThread,
[email protected]6e2d3d22012-02-24 18:10:36234 make_scoped_refptr(indexed_db)));
235 }
236}
237
[email protected]6e2d3d22012-02-24 18:10:36238void BrowserContext::PurgeMemory(BrowserContext* browser_context) {
239 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
240 BrowserThread::PostTask(
241 BrowserThread::IO, FROM_HERE,
242 base::Bind(&PurgeMemoryOnIOThread,
243 browser_context->GetResourceContext()));
244 }
245
[email protected]735e20c2012-03-20 01:16:59246 GetDOMStorageContextImpl(browser_context)->PurgeMemory();
[email protected]6e2d3d22012-02-24 18:10:36247}
248
[email protected]55eb70e762012-02-20 17:38:39249BrowserContext::~BrowserContext() {
[email protected]c1fff072012-02-24 23:38:12250 // These message loop checks are just to avoid leaks in unittests.
[email protected]55eb70e762012-02-20 17:38:39251 if (GetUserData(kDatabaseTrackerKeyName) &&
252 BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) {
253 BrowserThread::PostTask(
254 BrowserThread::FILE, FROM_HERE,
255 base::Bind(&webkit_database::DatabaseTracker::Shutdown,
256 GetDatabaseTracker(this)));
257 }
[email protected]c1fff072012-02-24 23:38:12258
[email protected]735e20c2012-03-20 01:16:59259 if (GetUserData(kDOMStorageContextKeyName))
260 GetDOMStorageContextImpl(this)->Shutdown();
[email protected]b441a8492012-06-06 14:55:57261
262 if (GetUserData(kDownloadManagerKeyName))
263 GetDownloadManager(this)->Shutdown();
[email protected]55eb70e762012-02-20 17:38:39264}
265
266} // namespace content