Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: content/browser/browser_context.cc

Issue 10600009: Support partitioning of storage contexts based on render_id. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: rebased on jam@'s chromeos fixes. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/public/browser/browser_context.h" 5 #include "content/public/browser/browser_context.h"
6 6
7 #include "base/file_path.h"
8 #include "base/stl_util.h"
7 #include "content/browser/appcache/chrome_appcache_service.h" 9 #include "content/browser/appcache/chrome_appcache_service.h"
8 #include "content/browser/dom_storage/dom_storage_context_impl.h" 10 #include "content/browser/dom_storage/dom_storage_context_impl.h"
9 #include "content/browser/download/download_file_manager.h" 11 #include "content/browser/download/download_file_manager.h"
10 #include "content/browser/download/download_manager_impl.h" 12 #include "content/browser/download/download_manager_impl.h"
11 #include "content/browser/fileapi/browser_file_system_helper.h" 13 #include "content/browser/fileapi/browser_file_system_helper.h"
12 #include "content/browser/in_process_webkit/indexed_db_context_impl.h" 14 #include "content/browser/in_process_webkit/indexed_db_context_impl.h"
13 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" 15 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
14 #include "content/browser/resource_context_impl.h" 16 #include "content/browser/resource_context_impl.h"
17 #include "content/common/child_process_host_impl.h"
15 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/content_browser_client.h" 19 #include "content/public/browser/content_browser_client.h"
17 #include "content/public/common/content_constants.h" 20 #include "content/public/common/content_constants.h"
18 #include "net/base/server_bound_cert_service.h" 21 #include "net/base/server_bound_cert_service.h"
19 #include "net/base/server_bound_cert_store.h" 22 #include "net/base/server_bound_cert_store.h"
20 #include "net/cookies/cookie_monster.h" 23 #include "net/cookies/cookie_monster.h"
21 #include "net/cookies/cookie_store.h" 24 #include "net/cookies/cookie_store.h"
22 #include "net/url_request/url_request_context.h" 25 #include "net/url_request/url_request_context.h"
23 #include "webkit/database/database_tracker.h" 26 #include "webkit/database/database_tracker.h"
24 #include "webkit/quota/quota_manager.h" 27 #include "webkit/quota/quota_manager.h"
25 28
26 using appcache::AppCacheService; 29 using appcache::AppCacheService;
27 using base::UserDataAdapter; 30 using base::UserDataAdapter;
28 using content::BrowserThread; 31 using content::BrowserThread;
29 using fileapi::FileSystemContext; 32 using fileapi::FileSystemContext;
30 using quota::QuotaManager; 33 using quota::QuotaManager;
31 using webkit_database::DatabaseTracker; 34 using webkit_database::DatabaseTracker;
32 35
33 // Key names on BrowserContext. 36 // Key names on BrowserContext.
34 static const char* kAppCacheServicKeyName = "content_appcache_service_tracker";
35 static const char* kDatabaseTrackerKeyName = "content_database_tracker";
36 static const char* kDOMStorageContextKeyName = "content_dom_storage_context";
37 static const char* kDownloadManagerKeyName = "download_manager"; 37 static const char* kDownloadManagerKeyName = "download_manager";
38 static const char* kFileSystemContextKeyName = "content_file_system_context"; 38 static const char* kStorageParitionMapKeyName = "content_storage_partition_map";
39 static const char* kIndexedDBContextKeyName = "content_indexed_db_context"; 39
40 static const char* kQuotaManagerKeyName = "content_quota_manager"; 40 // Dirname for storing persistent data for renderers with isolated storage.
41 const FilePath::CharType kStoragePartitionDirName[] =
42 FILE_PATH_LITERAL("Storage Partitions");
41 43
42 namespace content { 44 namespace content {
43 45
44 namespace { 46 namespace {
45 47
46 void CreateQuotaManagerAndClients(BrowserContext* context) { 48 // Defines the what persistent state a child process can access.
47 // Ensure that these methods are called on the UI thread, except for unittests 49 //
48 // where a UI thread might not have been created. 50 // The StoragePartition defines the view each child process has of the
49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || 51 // persistent state inside the BrowserContext. This is used to implement
50 !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); 52 // isolated storage where a renderer with isolated storage cannot see
51 if (context->GetUserData(kQuotaManagerKeyName)) { 53 // the cookies, localStorage, etc., that normal web renderers have access to.
52 DCHECK(context->GetUserData(kDatabaseTrackerKeyName)); 54 class StoragePartition {
53 DCHECK(context->GetUserData(kDOMStorageContextKeyName)); 55 public:
54 DCHECK(context->GetUserData(kFileSystemContextKeyName)); 56 ~StoragePartition() {
55 DCHECK(context->GetUserData(kIndexedDBContextKeyName)); 57 // These message loop checks are just to avoid leaks in unittests.
58 if (database_tracker() &&
59 BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) {
60 BrowserThread::PostTask(
61 BrowserThread::FILE, FROM_HERE,
62 base::Bind(&webkit_database::DatabaseTracker::Shutdown,
63 database_tracker()));
64 }
65
66 if (dom_storage_context())
67 dom_storage_context()->Shutdown();
68 }
69
70 // TODO(ajwong): Break the direct dependency on |context|. We only
71 // need 3 pieces of info from it.
72 static StoragePartition* Create(BrowserContext* context,
73 FilePath partition_path) {
74 // Ensure that these methods are called on the UI thread, except for
75 // unittests where a UI thread might not have been created.
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
77 !BrowserThread::IsMessageLoopValid(BrowserThread::UI));
78
79 // All of the clients have to be created and registered with the
80 // QuotaManager prior to the QuotaManger being used. We do them
81 // all together here prior to handing out a reference to anything
82 // that utilizes the QuotaManager.
83 scoped_refptr<QuotaManager> quota_manager = new quota::QuotaManager(
84 context->IsOffTheRecord(), partition_path,
85 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
86 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB),
87 context->GetSpecialStoragePolicy());
88
89 // Each consumer is responsible for registering its QuotaClient during
90 // its construction.
91 scoped_refptr<FileSystemContext> filesystem_context =
92 CreateFileSystemContext(partition_path, context->IsOffTheRecord(),
93 context->GetSpecialStoragePolicy(),
94 quota_manager->proxy());
95
96 scoped_refptr<DatabaseTracker> database_tracker = new DatabaseTracker(
97 partition_path, context->IsOffTheRecord(),
98 context->GetSpecialStoragePolicy(), quota_manager->proxy(),
99 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
100
101 FilePath path = context->IsOffTheRecord() ? FilePath() : partition_path;
102 scoped_refptr<DOMStorageContextImpl> dom_storage_context =
103 new DOMStorageContextImpl(path, context->GetSpecialStoragePolicy());
104
105 scoped_refptr<IndexedDBContextImpl> indexed_db_context =
106 new IndexedDBContextImpl(path, context->GetSpecialStoragePolicy(),
107 quota_manager->proxy(),
108 BrowserThread::GetMessageLoopProxyForThread(
109 BrowserThread::WEBKIT_DEPRECATED));
110
111 scoped_refptr<ChromeAppCacheService> appcache_service =
112 new ChromeAppCacheService(quota_manager->proxy());
113
114 return new StoragePartition(partition_path,
115 quota_manager,
116 appcache_service,
117 filesystem_context,
118 database_tracker,
119 dom_storage_context,
120 indexed_db_context);
121 }
122
123 quota::QuotaManager* quota_manager() {
124 return quota_manager_;
jam 2012/07/11 02:09:25 nit: fit on one line where you can for readability
awong 2012/07/11 21:17:17 Done.
125 }
126 ChromeAppCacheService* appcache_service() {
127 return appcache_service_;
128 }
129 fileapi::FileSystemContext* filesystem_context() {
130 return filesystem_context_;
131 }
132 webkit_database::DatabaseTracker* database_tracker() {
133 return database_tracker_;
134 }
135 DOMStorageContextImpl* dom_storage_context() {
136 return dom_storage_context_;
137 }
138 IndexedDBContext* indexed_db_context() {
139 return indexed_db_context_;
140 }
141
142 private:
143 StoragePartition(const FilePath& partition_path,
144 quota::QuotaManager* quota_manager,
145 ChromeAppCacheService* appcache_service,
146 fileapi::FileSystemContext* filesystem_context,
147 webkit_database::DatabaseTracker* database_tracker,
148 DOMStorageContextImpl* dom_storage_context,
149 IndexedDBContext* indexed_db_context)
150 : partition_path_(partition_path),
151 quota_manager_(quota_manager),
152 appcache_service_(appcache_service),
153 filesystem_context_(filesystem_context),
154 database_tracker_(database_tracker),
155 dom_storage_context_(dom_storage_context),
156 indexed_db_context_(indexed_db_context) {
157 }
158
159 FilePath partition_path_;
160 scoped_refptr<quota::QuotaManager> quota_manager_;
161 scoped_refptr<ChromeAppCacheService> appcache_service_;
162 scoped_refptr<fileapi::FileSystemContext> filesystem_context_;
163 scoped_refptr<webkit_database::DatabaseTracker> database_tracker_;
164 scoped_refptr<DOMStorageContextImpl> dom_storage_context_;
165 scoped_refptr<IndexedDBContext> indexed_db_context_;
166 };
167
168 // A std::string to StoragePartition map for use with SupportsUserData APIs.
169 class StoragePartitionMap : public base::SupportsUserData::Data {
170 public:
171 explicit StoragePartitionMap(BrowserContext* browser_context)
172 : browser_context_(browser_context) {
173 }
174
175 virtual ~StoragePartitionMap() {
176 STLDeleteContainerPairSecondPointers(partitions_.begin(),
177 partitions_.end());
178 }
179
180 // This map retains ownership of the returned StoragePartition objects.
181 StoragePartition* Get(const std::string& partition_id) {
182 // Find the previously created partition if it's available.
183 std::map<std::string, StoragePartition*>::const_iterator it =
184 partitions_.find(partition_id);
185 if (it != partitions_.end())
186 return it->second;
187
188 // There was no previous partition, so let's make a new one.
189 FilePath partition_path = browser_context_->GetPath();
190 if (!partition_id.empty()) {
191 CHECK(IsStringASCII(partition_id));
192 partition_path = partition_path.Append(kStoragePartitionDirName)
193 .AppendASCII(partition_id);
194 }
195
196 StoragePartition* storage_partition =
197 StoragePartition::Create(browser_context_, partition_path);
198 partitions_[partition_id] = storage_partition;
199
200 PostCreateInitialization(storage_partition, partition_path);
201
202 // TODO(ajwong): We need to remove this conditional by making
203 // InitializeResourceContext() understand having different partition data
204 // based on the renderer_id.
205 if (partition_id.empty()) {
206 InitializeResourceContext(browser_context_);
207 }
208
209 return storage_partition;
210 }
211
212 void ForEach(const base::Callback<void(StoragePartition*)>& callback) {
213 for (std::map<std::string, StoragePartition*>::const_iterator it =
214 partitions_.begin();
215 it != partitions_.end();
216 ++it) {
217 callback.Run(it->second);
218 }
219 }
220
221 private:
222 // TODO(ajwong): This must always be called *after* it's been added to the
223 // partition map. This feels dangerous. Should this not be in this class?
224 void PostCreateInitialization(StoragePartition* partition,
225 const FilePath& partition_path) {
226 // Check first to avoid memory leak in unittests.
227 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
228 BrowserThread::PostTask(
229 BrowserThread::IO, FROM_HERE,
230 base::Bind(&ChromeAppCacheService::InitializeOnIOThread,
231 partition->appcache_service(),
232 browser_context_->IsOffTheRecord() ? FilePath() :
233 partition_path.Append(content::kAppCacheDirname),
234 browser_context_->GetResourceContext(),
235 make_scoped_refptr(
236 browser_context_->GetSpecialStoragePolicy())));
237 }
238 }
239
240 BrowserContext* browser_context_;
241 std::map<std::string, StoragePartition*> partitions_;
242 };
243
244 StoragePartition* GetStoragePartition(BrowserContext* browser_context,
245 int renderer_child_id) {
246 StoragePartitionMap* partition_map = static_cast<StoragePartitionMap*>(
247 browser_context->GetUserData(kStorageParitionMapKeyName));
248 if (!partition_map) {
249 partition_map = new StoragePartitionMap(browser_context);
250 browser_context->SetUserData(kStorageParitionMapKeyName, partition_map);
251 }
252
253 const std::string& partition_id =
254 GetContentClient()->browser()->GetStoragePartitionIdForChildProcess(
255 browser_context,
256 renderer_child_id);
257
258 return partition_map->Get(partition_id);
259 }
260
261 // Run |callback| on each storage partition in |browser_context|.
262 void ForEachStoragePartition(
263 BrowserContext* browser_context,
264 const base::Callback<void(StoragePartition*)>& callback) {
265 StoragePartitionMap* partition_map = static_cast<StoragePartitionMap*>(
266 browser_context->GetUserData(kStorageParitionMapKeyName));
267 if (!partition_map) {
56 return; 268 return;
57 } 269 }
58 270
59 // All of the clients have to be created and registered with the 271 partition_map->ForEach(callback);
60 // QuotaManager prior to the QuotaManger being used. So we do them 272 }
61 // all together here prior to handing out a reference to anything 273
62 // that utlizes the QuotaManager. 274 // Used to convert a callback meant to take a DOMStorageContextImpl* into one
63 scoped_refptr<QuotaManager> quota_manager = new quota::QuotaManager( 275 // that can take a StoragePartition*.
64 context->IsOffTheRecord(), context->GetPath(), 276 void ProcessDOMStorageContext(
65 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 277 const base::Callback<void(DOMStorageContextImpl*)>& callback,
66 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB), 278 StoragePartition* partition) {
67 context->GetSpecialStoragePolicy()); 279 callback.Run(partition->dom_storage_context());
68 context->SetUserData(kQuotaManagerKeyName, 280 }
69 new UserDataAdapter<QuotaManager>(quota_manager)); 281
70 282 // Run |callback| on each DOMStorageContextImpl in |browser_context|.
71 // Each consumer is responsible for registering its QuotaClient during 283 void ForEachDOMStorageContext(
72 // its construction. 284 BrowserContext* browser_context,
73 scoped_refptr<FileSystemContext> filesystem_context = CreateFileSystemContext( 285 const base::Callback<void(DOMStorageContextImpl*)>& callback) {
74 context->GetPath(), context->IsOffTheRecord(), 286 ForEachStoragePartition(browser_context,
75 context->GetSpecialStoragePolicy(), quota_manager->proxy()); 287 base::Bind(&ProcessDOMStorageContext, callback));
76 context->SetUserData(
77 kFileSystemContextKeyName,
78 new UserDataAdapter<FileSystemContext>(filesystem_context));
79
80 scoped_refptr<DatabaseTracker> db_tracker = new DatabaseTracker(
81 context->GetPath(), context->IsOffTheRecord(),
82 context->GetSpecialStoragePolicy(), quota_manager->proxy(),
83 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
84 context->SetUserData(kDatabaseTrackerKeyName,
85 new UserDataAdapter<DatabaseTracker>(db_tracker));
86
87 FilePath path = context->IsOffTheRecord() ? FilePath() : context->GetPath();
88 scoped_refptr<DOMStorageContextImpl> dom_storage_context =
89 new DOMStorageContextImpl(path, context->GetSpecialStoragePolicy());
90 context->SetUserData(
91 kDOMStorageContextKeyName,
92 new UserDataAdapter<DOMStorageContextImpl>(dom_storage_context));
93
94 scoped_refptr<IndexedDBContext> indexed_db_context = new IndexedDBContextImpl(
95 path, context->GetSpecialStoragePolicy(), quota_manager->proxy(),
96 BrowserThread::GetMessageLoopProxyForThread(
97 BrowserThread::WEBKIT_DEPRECATED));
98 context->SetUserData(
99 kIndexedDBContextKeyName,
100 new UserDataAdapter<IndexedDBContext>(indexed_db_context));
101
102 scoped_refptr<ChromeAppCacheService> appcache_service =
103 new ChromeAppCacheService(quota_manager->proxy());
104 context->SetUserData(
105 kAppCacheServicKeyName,
106 new UserDataAdapter<ChromeAppCacheService>(appcache_service));
107
108 InitializeResourceContext(context);
109
110 // Check first to avoid memory leak in unittests.
111 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
112 BrowserThread::PostTask(
113 BrowserThread::IO, FROM_HERE,
114 base::Bind(&ChromeAppCacheService::InitializeOnIOThread,
115 appcache_service,
116 context->IsOffTheRecord() ? FilePath() :
117 context->GetPath().Append(content::kAppCacheDirname),
118 context->GetResourceContext(),
119 make_scoped_refptr(context->GetSpecialStoragePolicy())));
120 }
121 } 288 }
122 289
123 void SaveSessionStateOnIOThread(ResourceContext* resource_context) { 290 void SaveSessionStateOnIOThread(ResourceContext* resource_context) {
124 resource_context->GetRequestContext()->cookie_store()->GetCookieMonster()-> 291 resource_context->GetRequestContext()->cookie_store()->GetCookieMonster()->
125 SetForceKeepSessionState(); 292 SetForceKeepSessionState();
126 resource_context->GetRequestContext()->server_bound_cert_service()-> 293 resource_context->GetRequestContext()->server_bound_cert_service()->
127 GetCertStore()->SetForceKeepSessionState(); 294 GetCertStore()->SetForceKeepSessionState();
128 ResourceContext::GetAppCacheService(resource_context)-> 295 ResourceContext::GetAppCacheService(resource_context)->
129 set_force_keep_session_state(); 296 set_force_keep_session_state();
130 } 297 }
131 298
132 void SaveSessionStateOnWebkitThread( 299 void SaveSessionStateOnWebkitThread(
133 scoped_refptr<IndexedDBContextImpl> indexed_db_context) { 300 scoped_refptr<IndexedDBContextImpl> indexed_db_context) {
134 indexed_db_context->SetForceKeepSessionState(); 301 indexed_db_context->SetForceKeepSessionState();
135 } 302 }
136 303
137 void PurgeMemoryOnIOThread(ResourceContext* resource_context) { 304 void PurgeMemoryOnIOThread(ResourceContext* resource_context) {
138 ResourceContext::GetAppCacheService(resource_context)->PurgeMemory(); 305 ResourceContext::GetAppCacheService(resource_context)->PurgeMemory();
139 } 306 }
140 307
141 DOMStorageContextImpl* GetDOMStorageContextImpl(BrowserContext* context) { 308 DOMStorageContextImpl* GetDefaultDOMStorageContextImpl(
309 BrowserContext* context) {
142 return static_cast<DOMStorageContextImpl*>( 310 return static_cast<DOMStorageContextImpl*>(
143 BrowserContext::GetDOMStorageContext(context)); 311 BrowserContext::GetDefaultDOMStorageContext(context));
144 } 312 }
145 313
146 } // namespace 314 } // namespace
147 315
148 DownloadManager* BrowserContext::GetDownloadManager( 316 DownloadManager* BrowserContext::GetDownloadManager(
149 BrowserContext* context) { 317 BrowserContext* context) {
150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 318 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
151 if (!context->GetUserData(kDownloadManagerKeyName)) { 319 if (!context->GetUserData(kDownloadManagerKeyName)) {
152 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); 320 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
153 DCHECK(rdh); 321 DCHECK(rdh);
154 DownloadFileManager* file_manager = rdh->download_file_manager(); 322 DownloadFileManager* file_manager = rdh->download_file_manager();
155 DCHECK(file_manager); 323 DCHECK(file_manager);
156 scoped_refptr<DownloadManager> download_manager = 324 scoped_refptr<DownloadManager> download_manager =
157 new DownloadManagerImpl( 325 new DownloadManagerImpl(
158 file_manager, 326 file_manager,
159 scoped_ptr<DownloadItemFactory>(), 327 scoped_ptr<DownloadItemFactory>(),
160 GetContentClient()->browser()->GetNetLog()); 328 GetContentClient()->browser()->GetNetLog());
161 329
162 context->SetUserData( 330 context->SetUserData(
163 kDownloadManagerKeyName, 331 kDownloadManagerKeyName,
164 new UserDataAdapter<DownloadManager>(download_manager)); 332 new UserDataAdapter<DownloadManager>(download_manager));
165 download_manager->SetDelegate(context->GetDownloadManagerDelegate()); 333 download_manager->SetDelegate(context->GetDownloadManagerDelegate());
166 download_manager->Init(context); 334 download_manager->Init(context);
167 } 335 }
168 336
169 return UserDataAdapter<DownloadManager>::Get( 337 return UserDataAdapter<DownloadManager>::Get(
170 context, kDownloadManagerKeyName); 338 context, kDownloadManagerKeyName);
171 } 339 }
172 340
173 QuotaManager* BrowserContext::GetQuotaManager(BrowserContext* context) { 341 QuotaManager* BrowserContext::GetQuotaManager(BrowserContext* browser_context) {
174 CreateQuotaManagerAndClients(context); 342 // TODO(ajwong): Change this API to require a process id instead of using
175 return UserDataAdapter<QuotaManager>::Get(context, kQuotaManagerKeyName); 343 // kInvalidChildProcessId.
344 StoragePartition* partition =
345 GetStoragePartition(browser_context,
346 ChildProcessHostImpl::kInvalidChildProcessId);
347 return partition->quota_manager();
348 }
349
350 DOMStorageContext* BrowserContext::GetDefaultDOMStorageContext(
351 BrowserContext* browser_context) {
352 // TODO(ajwong): Force all users to know which process id they are performing
353 // actions on behalf of, migrate them to GetDOMStorageContext(), and then
354 // delete this function.
355 return GetDOMStorageContext(browser_context,
356 ChildProcessHostImpl::kInvalidChildProcessId);
176 } 357 }
177 358
178 DOMStorageContext* BrowserContext::GetDOMStorageContext( 359 DOMStorageContext* BrowserContext::GetDOMStorageContext(
179 BrowserContext* context) { 360 BrowserContext* browser_context,
180 CreateQuotaManagerAndClients(context); 361 int render_child_id) {
181 return UserDataAdapter<DOMStorageContextImpl>::Get( 362 StoragePartition* partition =
182 context, kDOMStorageContextKeyName); 363 GetStoragePartition(browser_context, render_child_id);
364 return partition->dom_storage_context();
183 } 365 }
184 366
185 IndexedDBContext* BrowserContext::GetIndexedDBContext(BrowserContext* context) { 367 IndexedDBContext* BrowserContext::GetIndexedDBContext(
186 CreateQuotaManagerAndClients(context); 368 BrowserContext* browser_context) {
187 return UserDataAdapter<IndexedDBContext>::Get( 369 // TODO(ajwong): Change this API to require a process id instead of using
188 context, kIndexedDBContextKeyName); 370 // kInvalidChildProcessId.
371 StoragePartition* partition =
372 GetStoragePartition(browser_context,
373 ChildProcessHostImpl::kInvalidChildProcessId);
374 return partition->indexed_db_context();
189 } 375 }
190 376
191 DatabaseTracker* BrowserContext::GetDatabaseTracker(BrowserContext* context) { 377 DatabaseTracker* BrowserContext::GetDatabaseTracker(
192 CreateQuotaManagerAndClients(context); 378 BrowserContext* browser_context) {
193 return UserDataAdapter<DatabaseTracker>::Get( 379 // TODO(ajwong): Change this API to require a process id instead of using
194 context, kDatabaseTrackerKeyName); 380 // kInvalidChildProcessId.
381 StoragePartition* partition =
382 GetStoragePartition(browser_context,
383 ChildProcessHostImpl::kInvalidChildProcessId);
384 return partition->database_tracker();
195 } 385 }
196 386
197 AppCacheService* BrowserContext::GetAppCacheService( 387 AppCacheService* BrowserContext::GetAppCacheService(
198 BrowserContext* browser_context) { 388 BrowserContext* browser_context) {
199 CreateQuotaManagerAndClients(browser_context); 389 // TODO(ajwong): Change this API to require a process id instead of using
200 return UserDataAdapter<ChromeAppCacheService>::Get( 390 // kInvalidChildProcessId.
201 browser_context, kAppCacheServicKeyName); 391 StoragePartition* partition =
392 GetStoragePartition(browser_context,
393 ChildProcessHostImpl::kInvalidChildProcessId);
394 return partition->appcache_service();
202 } 395 }
203 396
204 FileSystemContext* BrowserContext::GetFileSystemContext( 397 FileSystemContext* BrowserContext::GetFileSystemContext(
205 BrowserContext* browser_context) { 398 BrowserContext* browser_context) {
206 CreateQuotaManagerAndClients(browser_context); 399 // TODO(ajwong): Change this API to require a process id instead of using
207 return UserDataAdapter<FileSystemContext>::Get( 400 // kInvalidChildProcessId.
208 browser_context, kFileSystemContextKeyName); 401 StoragePartition* partition =
402 GetStoragePartition(browser_context,
403 ChildProcessHostImpl::kInvalidChildProcessId);
404 return partition->filesystem_context();
209 } 405 }
210 406
211 void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) { 407 void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) {
212 // This will be enough to tickle initialization of BrowserContext if 408 // This will be enough to tickle initialization of BrowserContext if
213 // necessary, which initializes ResourceContext. The reason we don't call 409 // necessary, which initializes ResourceContext. The reason we don't call
214 // ResourceContext::InitializeResourceContext directly here is that if 410 // ResourceContext::InitializeResourceContext directly here is that if
215 // ResourceContext ends up initializing it will call back into BrowserContext 411 // ResourceContext ends up initializing it will call back into BrowserContext
216 // and when that call return it'll end rewriting its UserData map (with the 412 // and when that call returns it'll end rewriting its UserData map (with the
217 // same value) but this causes a race condition. See http://crbug.com/115678. 413 // same value) but this causes a race condition. See http://crbug.com/115678.
218 CreateQuotaManagerAndClients(context); 414 GetStoragePartition(context, ChildProcessHostImpl::kInvalidChildProcessId);
219 } 415 }
220 416
221 void BrowserContext::SaveSessionState(BrowserContext* browser_context) { 417 void BrowserContext::SaveSessionState(BrowserContext* browser_context) {
222 GetDatabaseTracker(browser_context)->SetForceKeepSessionState(); 418 GetDatabaseTracker(browser_context)->SetForceKeepSessionState();
223 419
224 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { 420 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
225 BrowserThread::PostTask( 421 BrowserThread::PostTask(
226 BrowserThread::IO, FROM_HERE, 422 BrowserThread::IO, FROM_HERE,
227 base::Bind(&SaveSessionStateOnIOThread, 423 base::Bind(&SaveSessionStateOnIOThread,
228 browser_context->GetResourceContext())); 424 browser_context->GetResourceContext()));
229 } 425 }
230 426
231 GetDOMStorageContextImpl(browser_context)->SetForceKeepSessionState(); 427 // TODO(ajwong): This is the only usage of GetDefaultDOMStorageContextImpl().
428 // After we migrate this to support multiple DOMStorageContexts, don't forget
429 // to remove the GetDefaultDOMStorageContextImpl() function as well.
430 GetDefaultDOMStorageContextImpl(browser_context)->SetForceKeepSessionState();
232 431
233 if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) { 432 if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) {
234 IndexedDBContextImpl* indexed_db = static_cast<IndexedDBContextImpl*>( 433 IndexedDBContextImpl* indexed_db = static_cast<IndexedDBContextImpl*>(
235 GetIndexedDBContext(browser_context)); 434 GetIndexedDBContext(browser_context));
236 BrowserThread::PostTask( 435 BrowserThread::PostTask(
237 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, 436 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE,
238 base::Bind(&SaveSessionStateOnWebkitThread, 437 base::Bind(&SaveSessionStateOnWebkitThread,
239 make_scoped_refptr(indexed_db))); 438 make_scoped_refptr(indexed_db)));
240 } 439 }
241 } 440 }
242 441
243 void BrowserContext::PurgeMemory(BrowserContext* browser_context) { 442 void BrowserContext::PurgeMemory(BrowserContext* browser_context) {
244 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { 443 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
245 BrowserThread::PostTask( 444 BrowserThread::PostTask(
246 BrowserThread::IO, FROM_HERE, 445 BrowserThread::IO, FROM_HERE,
247 base::Bind(&PurgeMemoryOnIOThread, 446 base::Bind(&PurgeMemoryOnIOThread,
248 browser_context->GetResourceContext())); 447 browser_context->GetResourceContext()));
249 } 448 }
250 449
251 GetDOMStorageContextImpl(browser_context)->PurgeMemory(); 450 ForEachDOMStorageContext(browser_context,
451 base::Bind(&DOMStorageContextImpl::PurgeMemory));
252 } 452 }
253 453
254 BrowserContext::~BrowserContext() { 454 BrowserContext::~BrowserContext() {
255 // These message loop checks are just to avoid leaks in unittests.
256 if (GetUserData(kDatabaseTrackerKeyName) &&
257 BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) {
258 BrowserThread::PostTask(
259 BrowserThread::FILE, FROM_HERE,
260 base::Bind(&webkit_database::DatabaseTracker::Shutdown,
261 GetDatabaseTracker(this)));
262 }
263
264 if (GetUserData(kDOMStorageContextKeyName))
265 GetDOMStorageContextImpl(this)->Shutdown();
266
267 if (GetUserData(kDownloadManagerKeyName)) 455 if (GetUserData(kDownloadManagerKeyName))
268 GetDownloadManager(this)->Shutdown(); 456 GetDownloadManager(this)->Shutdown();
269 } 457 }
270 458
271 } // namespace content 459 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698