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

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

Powered by Google App Engine
This is Rietveld 408576698