| 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 "content/browser/appcache/chrome_appcache_service.h" | 7 #include "content/browser/appcache/chrome_appcache_service.h" |
| 8 #include "webkit/database/database_tracker.h" |
| 8 #include "content/browser/dom_storage/dom_storage_context_impl.h" | 9 #include "content/browser/dom_storage/dom_storage_context_impl.h" |
| 9 #include "content/browser/download/download_file_manager.h" | 10 #include "content/browser/download/download_file_manager.h" |
| 10 #include "content/browser/download/download_manager_impl.h" | 11 #include "content/browser/download/download_manager_impl.h" |
| 11 #include "content/browser/fileapi/browser_file_system_helper.h" | |
| 12 #include "content/browser/in_process_webkit/indexed_db_context_impl.h" | 12 #include "content/browser/in_process_webkit/indexed_db_context_impl.h" |
| 13 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" | 13 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" |
| 14 #include "content/browser/resource_context_impl.h" | 14 #include "content/public/browser/resource_context.h" |
| 15 #include "content/browser/storage_partition.h" |
| 16 #include "content/browser/storage_partition_map.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" | |
| 18 #include "net/base/server_bound_cert_service.h" | 20 #include "net/base/server_bound_cert_service.h" |
| 19 #include "net/base/server_bound_cert_store.h" | 21 #include "net/base/server_bound_cert_store.h" |
| 20 #include "net/cookies/cookie_monster.h" | 22 #include "net/cookies/cookie_monster.h" |
| 21 #include "net/cookies/cookie_store.h" | 23 #include "net/cookies/cookie_store.h" |
| 22 #include "net/url_request/url_request_context.h" | 24 #include "net/url_request/url_request_context.h" |
| 23 #include "webkit/database/database_tracker.h" | |
| 24 #include "webkit/quota/quota_manager.h" | |
| 25 | 25 |
| 26 using appcache::AppCacheService; | |
| 27 using base::UserDataAdapter; | 26 using base::UserDataAdapter; |
| 28 using content::BrowserThread; | |
| 29 using fileapi::FileSystemContext; | |
| 30 using quota::QuotaManager; | |
| 31 using webkit_database::DatabaseTracker; | |
| 32 | 27 |
| 33 // Key names on BrowserContext. | 28 // 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"; | 29 static const char* kDownloadManagerKeyName = "download_manager"; |
| 38 static const char* kFileSystemContextKeyName = "content_file_system_context"; | 30 static const char* kStorageParitionMapKeyName = "content_storage_partition_map"; |
| 39 static const char* kIndexedDBContextKeyName = "content_indexed_db_context"; | |
| 40 static const char* kQuotaManagerKeyName = "content_quota_manager"; | |
| 41 | 31 |
| 42 namespace content { | 32 namespace content { |
| 43 | 33 |
| 44 namespace { | 34 namespace { |
| 45 | 35 |
| 46 void CreateQuotaManagerAndClients(BrowserContext* context) { | 36 StoragePartition* GetStoragePartition(BrowserContext* browser_context, |
| 47 // Ensure that these methods are called on the UI thread, except for unittests | 37 int renderer_child_id) { |
| 48 // where a UI thread might not have been created. | 38 StoragePartitionMap* partition_map = static_cast<StoragePartitionMap*>( |
| 49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || | 39 browser_context->GetUserData(kStorageParitionMapKeyName)); |
| 50 !BrowserThread::IsMessageLoopValid(BrowserThread::UI)); | 40 if (!partition_map) { |
| 51 if (context->GetUserData(kQuotaManagerKeyName)) { | 41 partition_map = new StoragePartitionMap(browser_context); |
| 52 DCHECK(context->GetUserData(kDatabaseTrackerKeyName)); | 42 browser_context->SetUserData(kStorageParitionMapKeyName, partition_map); |
| 53 DCHECK(context->GetUserData(kDOMStorageContextKeyName)); | 43 } |
| 54 DCHECK(context->GetUserData(kFileSystemContextKeyName)); | 44 |
| 55 DCHECK(context->GetUserData(kIndexedDBContextKeyName)); | 45 const std::string& partition_id = |
| 46 GetContentClient()->browser()->GetStoragePartitionIdForChildProcess( |
| 47 browser_context, |
| 48 renderer_child_id); |
| 49 |
| 50 return partition_map->Get(partition_id); |
| 51 } |
| 52 |
| 53 // Run |callback| on each storage partition in |browser_context|. |
| 54 void ForEachStoragePartition( |
| 55 BrowserContext* browser_context, |
| 56 const base::Callback<void(StoragePartition*)>& callback) { |
| 57 StoragePartitionMap* partition_map = static_cast<StoragePartitionMap*>( |
| 58 browser_context->GetUserData(kStorageParitionMapKeyName)); |
| 59 if (!partition_map) { |
| 56 return; | 60 return; |
| 57 } | 61 } |
| 58 | 62 |
| 59 // All of the clients have to be created and registered with the | 63 partition_map->ForEach(callback); |
| 60 // QuotaManager prior to the QuotaManger being used. So we do them | 64 } |
| 61 // all together here prior to handing out a reference to anything | |
| 62 // that utlizes the QuotaManager. | |
| 63 scoped_refptr<QuotaManager> quota_manager = new quota::QuotaManager( | |
| 64 context->IsOffTheRecord(), context->GetPath(), | |
| 65 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), | |
| 66 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB), | |
| 67 context->GetSpecialStoragePolicy()); | |
| 68 context->SetUserData(kQuotaManagerKeyName, | |
| 69 new UserDataAdapter<QuotaManager>(quota_manager)); | |
| 70 | 65 |
| 71 // Each consumer is responsible for registering its QuotaClient during | 66 // Used to convert a callback meant to take a DOMStorageContextImpl* into one |
| 72 // its construction. | 67 // that can take a StoragePartition*. |
| 73 scoped_refptr<FileSystemContext> filesystem_context = CreateFileSystemContext( | 68 void ProcessDOMStorageContext( |
| 74 context->GetPath(), context->IsOffTheRecord(), | 69 const base::Callback<void(DOMStorageContextImpl*)>& callback, |
| 75 context->GetSpecialStoragePolicy(), quota_manager->proxy()); | 70 StoragePartition* partition) { |
| 76 context->SetUserData( | 71 callback.Run(partition->dom_storage_context()); |
| 77 kFileSystemContextKeyName, | 72 } |
| 78 new UserDataAdapter<FileSystemContext>(filesystem_context)); | |
| 79 | 73 |
| 80 scoped_refptr<DatabaseTracker> db_tracker = new DatabaseTracker( | 74 // Run |callback| on each DOMStorageContextImpl in |browser_context|. |
| 81 context->GetPath(), context->IsOffTheRecord(), | 75 void ForEachDOMStorageContext( |
| 82 context->GetSpecialStoragePolicy(), quota_manager->proxy(), | 76 BrowserContext* browser_context, |
| 83 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); | 77 const base::Callback<void(DOMStorageContextImpl*)>& callback) { |
| 84 context->SetUserData(kDatabaseTrackerKeyName, | 78 ForEachStoragePartition(browser_context, |
| 85 new UserDataAdapter<DatabaseTracker>(db_tracker)); | 79 base::Bind(&ProcessDOMStorageContext, callback)); |
| 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 } | 80 } |
| 122 | 81 |
| 123 void SaveSessionStateOnIOThread(ResourceContext* resource_context) { | 82 void SaveSessionStateOnIOThread(ResourceContext* resource_context) { |
| 124 resource_context->GetRequestContext()->cookie_store()->GetCookieMonster()-> | 83 resource_context->GetRequestContext()->cookie_store()->GetCookieMonster()-> |
| 125 SetForceKeepSessionState(); | 84 SetForceKeepSessionState(); |
| 126 resource_context->GetRequestContext()->server_bound_cert_service()-> | 85 resource_context->GetRequestContext()->server_bound_cert_service()-> |
| 127 GetCertStore()->SetForceKeepSessionState(); | 86 GetCertStore()->SetForceKeepSessionState(); |
| 128 ResourceContext::GetAppCacheService(resource_context)-> | 87 ResourceContext::GetAppCacheService(resource_context)-> |
| 129 set_force_keep_session_state(); | 88 set_force_keep_session_state(); |
| 130 } | 89 } |
| 131 | 90 |
| 132 void SaveSessionStateOnWebkitThread( | 91 void SaveSessionStateOnWebkitThread( |
| 133 scoped_refptr<IndexedDBContextImpl> indexed_db_context) { | 92 scoped_refptr<IndexedDBContextImpl> indexed_db_context) { |
| 134 indexed_db_context->SetForceKeepSessionState(); | 93 indexed_db_context->SetForceKeepSessionState(); |
| 135 } | 94 } |
| 136 | 95 |
| 137 void PurgeMemoryOnIOThread(ResourceContext* resource_context) { | 96 void PurgeMemoryOnIOThread(ResourceContext* resource_context) { |
| 138 ResourceContext::GetAppCacheService(resource_context)->PurgeMemory(); | 97 ResourceContext::GetAppCacheService(resource_context)->PurgeMemory(); |
| 139 } | 98 } |
| 140 | 99 |
| 141 DOMStorageContextImpl* GetDOMStorageContextImpl(BrowserContext* context) { | 100 DOMStorageContextImpl* GetDefaultDOMStorageContextImpl( |
| 101 BrowserContext* context) { |
| 142 return static_cast<DOMStorageContextImpl*>( | 102 return static_cast<DOMStorageContextImpl*>( |
| 143 BrowserContext::GetDOMStorageContext(context)); | 103 BrowserContext::GetDefaultDOMStorageContext(context)); |
| 144 } | 104 } |
| 145 | 105 |
| 146 } // namespace | 106 } // namespace |
| 147 | 107 |
| 148 DownloadManager* BrowserContext::GetDownloadManager( | 108 DownloadManager* BrowserContext::GetDownloadManager( |
| 149 BrowserContext* context) { | 109 BrowserContext* context) { |
| 150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 151 if (!context->GetUserData(kDownloadManagerKeyName)) { | 111 if (!context->GetUserData(kDownloadManagerKeyName)) { |
| 152 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); | 112 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); |
| 153 DCHECK(rdh); | 113 DCHECK(rdh); |
| 154 DownloadFileManager* file_manager = rdh->download_file_manager(); | 114 DownloadFileManager* file_manager = rdh->download_file_manager(); |
| 155 DCHECK(file_manager); | 115 DCHECK(file_manager); |
| 156 scoped_refptr<DownloadManager> download_manager = | 116 scoped_refptr<DownloadManager> download_manager = |
| 157 new DownloadManagerImpl( | 117 new DownloadManagerImpl( |
| 158 file_manager, | 118 file_manager, |
| 159 scoped_ptr<DownloadItemFactory>(), | 119 scoped_ptr<DownloadItemFactory>(), |
| 160 GetContentClient()->browser()->GetNetLog()); | 120 GetContentClient()->browser()->GetNetLog()); |
| 161 | 121 |
| 162 context->SetUserData( | 122 context->SetUserData( |
| 163 kDownloadManagerKeyName, | 123 kDownloadManagerKeyName, |
| 164 new UserDataAdapter<DownloadManager>(download_manager)); | 124 new UserDataAdapter<DownloadManager>(download_manager)); |
| 165 download_manager->SetDelegate(context->GetDownloadManagerDelegate()); | 125 download_manager->SetDelegate(context->GetDownloadManagerDelegate()); |
| 166 download_manager->Init(context); | 126 download_manager->Init(context); |
| 167 } | 127 } |
| 168 | 128 |
| 169 return UserDataAdapter<DownloadManager>::Get( | 129 return UserDataAdapter<DownloadManager>::Get( |
| 170 context, kDownloadManagerKeyName); | 130 context, kDownloadManagerKeyName); |
| 171 } | 131 } |
| 172 | 132 |
| 173 QuotaManager* BrowserContext::GetQuotaManager(BrowserContext* context) { | 133 quota::QuotaManager* BrowserContext::GetQuotaManager( |
| 174 CreateQuotaManagerAndClients(context); | 134 BrowserContext* browser_context) { |
| 175 return UserDataAdapter<QuotaManager>::Get(context, kQuotaManagerKeyName); | 135 // TODO(ajwong): Change this API to require a process id instead of using |
| 136 // kInvalidChildProcessId. |
| 137 StoragePartition* partition = |
| 138 GetStoragePartition(browser_context, |
| 139 ChildProcessHostImpl::kInvalidChildProcessId); |
| 140 return partition->quota_manager(); |
| 141 } |
| 142 |
| 143 DOMStorageContext* BrowserContext::GetDefaultDOMStorageContext( |
| 144 BrowserContext* browser_context) { |
| 145 // TODO(ajwong): Force all users to know which process id they are performing |
| 146 // actions on behalf of, migrate them to GetDOMStorageContext(), and then |
| 147 // delete this function. |
| 148 return GetDOMStorageContext(browser_context, |
| 149 ChildProcessHostImpl::kInvalidChildProcessId); |
| 176 } | 150 } |
| 177 | 151 |
| 178 DOMStorageContext* BrowserContext::GetDOMStorageContext( | 152 DOMStorageContext* BrowserContext::GetDOMStorageContext( |
| 179 BrowserContext* context) { | 153 BrowserContext* browser_context, |
| 180 CreateQuotaManagerAndClients(context); | 154 int render_child_id) { |
| 181 return UserDataAdapter<DOMStorageContextImpl>::Get( | 155 StoragePartition* partition = |
| 182 context, kDOMStorageContextKeyName); | 156 GetStoragePartition(browser_context, render_child_id); |
| 157 return partition->dom_storage_context(); |
| 183 } | 158 } |
| 184 | 159 |
| 185 IndexedDBContext* BrowserContext::GetIndexedDBContext(BrowserContext* context) { | 160 IndexedDBContext* BrowserContext::GetIndexedDBContext( |
| 186 CreateQuotaManagerAndClients(context); | 161 BrowserContext* browser_context) { |
| 187 return UserDataAdapter<IndexedDBContext>::Get( | 162 // TODO(ajwong): Change this API to require a process id instead of using |
| 188 context, kIndexedDBContextKeyName); | 163 // kInvalidChildProcessId. |
| 164 StoragePartition* partition = |
| 165 GetStoragePartition(browser_context, |
| 166 ChildProcessHostImpl::kInvalidChildProcessId); |
| 167 return partition->indexed_db_context(); |
| 189 } | 168 } |
| 190 | 169 |
| 191 DatabaseTracker* BrowserContext::GetDatabaseTracker(BrowserContext* context) { | 170 webkit_database::DatabaseTracker* BrowserContext::GetDatabaseTracker( |
| 192 CreateQuotaManagerAndClients(context); | 171 BrowserContext* browser_context) { |
| 193 return UserDataAdapter<DatabaseTracker>::Get( | 172 // TODO(ajwong): Change this API to require a process id instead of using |
| 194 context, kDatabaseTrackerKeyName); | 173 // kInvalidChildProcessId. |
| 174 StoragePartition* partition = |
| 175 GetStoragePartition(browser_context, |
| 176 ChildProcessHostImpl::kInvalidChildProcessId); |
| 177 return partition->database_tracker(); |
| 195 } | 178 } |
| 196 | 179 |
| 197 AppCacheService* BrowserContext::GetAppCacheService( | 180 appcache::AppCacheService* BrowserContext::GetAppCacheService( |
| 198 BrowserContext* browser_context) { | 181 BrowserContext* browser_context) { |
| 199 CreateQuotaManagerAndClients(browser_context); | 182 // TODO(ajwong): Change this API to require a process id instead of using |
| 200 return UserDataAdapter<ChromeAppCacheService>::Get( | 183 // kInvalidChildProcessId. |
| 201 browser_context, kAppCacheServicKeyName); | 184 StoragePartition* partition = |
| 185 GetStoragePartition(browser_context, |
| 186 ChildProcessHostImpl::kInvalidChildProcessId); |
| 187 return partition->appcache_service(); |
| 202 } | 188 } |
| 203 | 189 |
| 204 FileSystemContext* BrowserContext::GetFileSystemContext( | 190 fileapi::FileSystemContext* BrowserContext::GetFileSystemContext( |
| 205 BrowserContext* browser_context) { | 191 BrowserContext* browser_context) { |
| 206 CreateQuotaManagerAndClients(browser_context); | 192 // TODO(ajwong): Change this API to require a process id instead of using |
| 207 return UserDataAdapter<FileSystemContext>::Get( | 193 // kInvalidChildProcessId. |
| 208 browser_context, kFileSystemContextKeyName); | 194 StoragePartition* partition = |
| 195 GetStoragePartition(browser_context, |
| 196 ChildProcessHostImpl::kInvalidChildProcessId); |
| 197 return partition->filesystem_context(); |
| 209 } | 198 } |
| 210 | 199 |
| 211 void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) { | 200 void BrowserContext::EnsureResourceContextInitialized(BrowserContext* context) { |
| 212 // This will be enough to tickle initialization of BrowserContext if | 201 // This will be enough to tickle initialization of BrowserContext if |
| 213 // necessary, which initializes ResourceContext. The reason we don't call | 202 // necessary, which initializes ResourceContext. The reason we don't call |
| 214 // ResourceContext::InitializeResourceContext directly here is that if | 203 // ResourceContext::InitializeResourceContext directly here is that if |
| 215 // ResourceContext ends up initializing it will call back into BrowserContext | 204 // 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 | 205 // 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. | 206 // same value) but this causes a race condition. See http://crbug.com/115678. |
| 218 CreateQuotaManagerAndClients(context); | 207 GetStoragePartition(context, ChildProcessHostImpl::kInvalidChildProcessId); |
| 219 } | 208 } |
| 220 | 209 |
| 221 void BrowserContext::SaveSessionState(BrowserContext* browser_context) { | 210 void BrowserContext::SaveSessionState(BrowserContext* browser_context) { |
| 222 GetDatabaseTracker(browser_context)->SetForceKeepSessionState(); | 211 GetDatabaseTracker(browser_context)->SetForceKeepSessionState(); |
| 223 | 212 |
| 224 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { | 213 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { |
| 225 BrowserThread::PostTask( | 214 BrowserThread::PostTask( |
| 226 BrowserThread::IO, FROM_HERE, | 215 BrowserThread::IO, FROM_HERE, |
| 227 base::Bind(&SaveSessionStateOnIOThread, | 216 base::Bind(&SaveSessionStateOnIOThread, |
| 228 browser_context->GetResourceContext())); | 217 browser_context->GetResourceContext())); |
| 229 } | 218 } |
| 230 | 219 |
| 231 GetDOMStorageContextImpl(browser_context)->SetForceKeepSessionState(); | 220 // TODO(ajwong): This is the only usage of GetDefaultDOMStorageContextImpl(). |
| 221 // After we migrate this to support multiple DOMStorageContexts, don't forget |
| 222 // to remove the GetDefaultDOMStorageContextImpl() function as well. |
| 223 GetDefaultDOMStorageContextImpl(browser_context)->SetForceKeepSessionState(); |
| 232 | 224 |
| 233 if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) { | 225 if (BrowserThread::IsMessageLoopValid(BrowserThread::WEBKIT_DEPRECATED)) { |
| 234 IndexedDBContextImpl* indexed_db = static_cast<IndexedDBContextImpl*>( | 226 IndexedDBContextImpl* indexed_db = static_cast<IndexedDBContextImpl*>( |
| 235 GetIndexedDBContext(browser_context)); | 227 GetIndexedDBContext(browser_context)); |
| 236 BrowserThread::PostTask( | 228 BrowserThread::PostTask( |
| 237 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, | 229 BrowserThread::WEBKIT_DEPRECATED, FROM_HERE, |
| 238 base::Bind(&SaveSessionStateOnWebkitThread, | 230 base::Bind(&SaveSessionStateOnWebkitThread, |
| 239 make_scoped_refptr(indexed_db))); | 231 make_scoped_refptr(indexed_db))); |
| 240 } | 232 } |
| 241 } | 233 } |
| 242 | 234 |
| 243 void BrowserContext::PurgeMemory(BrowserContext* browser_context) { | 235 void BrowserContext::PurgeMemory(BrowserContext* browser_context) { |
| 244 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { | 236 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { |
| 245 BrowserThread::PostTask( | 237 BrowserThread::PostTask( |
| 246 BrowserThread::IO, FROM_HERE, | 238 BrowserThread::IO, FROM_HERE, |
| 247 base::Bind(&PurgeMemoryOnIOThread, | 239 base::Bind(&PurgeMemoryOnIOThread, |
| 248 browser_context->GetResourceContext())); | 240 browser_context->GetResourceContext())); |
| 249 } | 241 } |
| 250 | 242 |
| 251 GetDOMStorageContextImpl(browser_context)->PurgeMemory(); | 243 ForEachDOMStorageContext(browser_context, |
| 244 base::Bind(&DOMStorageContextImpl::PurgeMemory)); |
| 252 } | 245 } |
| 253 | 246 |
| 254 BrowserContext::~BrowserContext() { | 247 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)) | 248 if (GetUserData(kDownloadManagerKeyName)) |
| 268 GetDownloadManager(this)->Shutdown(); | 249 GetDownloadManager(this)->Shutdown(); |
| 269 } | 250 } |
| 270 | 251 |
| 271 } // namespace content | 252 } // namespace content |
| OLD | NEW |