OLD | NEW |
---|---|
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 |
OLD | NEW |