15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_IMPL_H_ 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_IMPL_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/memory/ref_counted.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_database.h" 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_disk_cache.h" 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_storage.h" 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/content_export.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace base { 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class SingleThreadTaskRunner; 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace base 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 28e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass AppCacheStorageImplTest; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChromeAppCacheServiceTest; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheStorageImpl : public AppCacheStorage { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) explicit AppCacheStorageImpl(AppCacheServiceImpl* service); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AppCacheStorageImpl(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void Initialize( 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const base::FilePath& cache_directory, 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Disable(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_disabled() const { return is_disabled_; } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AppCacheStorage methods, see the base class for doc comments. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetAllInfo(Delegate* delegate) OVERRIDE; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void LoadCache(int64 id, Delegate* delegate) OVERRIDE; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void LoadOrCreateGroup(const GURL& manifest_url, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate) OVERRIDE; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StoreGroupAndNewestCache(AppCacheGroup* group, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCache* newest_cache, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate) OVERRIDE; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void FindResponseForMainRequest(const GURL& url, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& preferred_manifest_url, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate) OVERRIDE; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void FindResponseForSubRequest( 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCache* cache, const GURL& url, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* found_network_namespace) OVERRIDE; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void MarkEntryAsForeign(const GURL& entry_url, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 cache_id) OVERRIDE; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void MakeGroupObsolete(AppCacheGroup* group, 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Delegate* delegate, 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch int response_code) OVERRIDE; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual AppCacheResponseReader* CreateResponseReader( 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, int64 group_id, int64 response_id) OVERRIDE; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual AppCacheResponseWriter* CreateResponseWriter( 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, int64 group_id) OVERRIDE; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DoomResponses(const GURL& manifest_url, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int64>& response_ids) OVERRIDE; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DeleteResponses(const GURL& manifest_url, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int64>& response_ids) OVERRIDE; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The AppCacheStorageImpl class methods and datamembers may only be 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // accessed on the IO thread. This class manufactures seperate DatabaseTasks 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which access the DB on a seperate background thread. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DatabaseTask; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class InitTask; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DisableDatabaseTask; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class GetAllInfoTask; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StoreOrLoadTask; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class CacheLoadTask; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class GroupLoadTask; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class StoreGroupAndCacheTask; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class FindMainResponseTask; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class MarkEntryAsForeignTask; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class MakeGroupObsoleteTask; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class GetDeletableResponseIdsTask; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class InsertDeletableResponseIdsTask; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class DeleteDeletableResponseIdsTask; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class UpdateGroupLastAccessTimeTask; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::deque<DatabaseTask*> DatabaseTaskQueue; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<int64, CacheLoadTask*> PendingCacheLoads; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<GURL, GroupLoadTask*> PendingGroupLoads; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::deque<std::pair<GURL, int64> > PendingForeignMarkings; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::set<StoreGroupAndCacheTask*> PendingQuotaQueries; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsInitTaskComplete() { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return last_cache_id_ != AppCacheStorage::kUnitializedId; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CacheLoadTask* GetPendingCacheLoadTask(int64 cache_id); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GroupLoadTask* GetPendingGroupLoadTask(const GURL& manifest_url); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetPendingForeignMarkingsForCache( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 cache_id, std::vector<GURL>* urls); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScheduleSimpleTask(const base::Closure& task); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunOnePendingSimpleTask(); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DelayedStartDeletingUnusedResponses(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartDeletingResponses(const std::vector<int64>& response_ids); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScheduleDeleteOneResponse(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteOneResponse(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnDeletedOneResponse(int rv); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnDiskCacheInitialized(int rv); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DeleteAndStartOver(); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DeleteAndStartOverPart2(); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CallScheduleReinitialize(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sometimes we can respond without having to query the database. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool FindResponseForMainRequestInGroup( 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheGroup* group, const GURL& url, Delegate* delegate); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeliverShortCircuitedFindMainResponse( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AppCacheEntry& found_entry, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AppCacheGroup> group, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AppCache> newest_cache, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<DelegateReference> delegate_ref); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CallOnMainResponseFound( 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReferenceVector* delegates, 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, const AppCacheEntry& entry, 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 cache_id, int64 group_id, const GURL& manifest_url); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CONTENT_EXPORT AppCacheDiskCache* disk_cache(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The directory in which we place files in the file system. 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath cache_directory_; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_incognito_; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This class operates primarily on the IO thread, but schedules 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its DatabaseTasks on the db thread. Separately, the disk_cache uses 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // the cache thread. 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> db_thread_; 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> cache_thread_; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Structures to keep track of DatabaseTasks that are in-flight. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DatabaseTaskQueue scheduled_database_tasks_; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingCacheLoads pending_cache_loads_; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingGroupLoads pending_group_loads_; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingForeignMarkings pending_foreign_markings_; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingQuotaQueries pending_quota_queries_; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Structures to keep track of lazy response deletion. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<int64> deletable_response_ids_; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<int64> deleted_response_ids_; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_response_deletion_scheduled_; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool did_start_deleting_responses_; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 last_deletable_response_rowid_; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Created on the IO thread, but only used on the DB thread. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheDatabase* database_; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set if we discover a fatal error like a corrupt SQL database or 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disk cache and cannot continue. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_disabled_; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AppCacheDiskCache> disk_cache_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to short-circuit certain operations without having to schedule 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any tasks on the background database thread. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<base::Closure> pending_simple_tasks_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<AppCacheStorageImpl> weak_factory_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch friend class content::AppCacheStorageImplTest; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class content::ChromeAppCacheServiceTest; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace content 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif // CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_IMPL_H_ 184