1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_IMPL_H_ 6 #define CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_IMPL_H_ 7 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <utility> 12 #include <vector> 13 14 #include "base/callback.h" 15 #include "base/files/file_path.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/memory/weak_ptr.h" 18 #include "content/browser/appcache/appcache_database.h" 19 #include "content/browser/appcache/appcache_disk_cache.h" 20 #include "content/browser/appcache/appcache_storage.h" 21 #include "content/common/content_export.h" 22 23 namespace base { 24 class SingleThreadTaskRunner; 25 } // namespace base 26 27 namespace content { 28 class AppCacheStorageImplTest; 29 class ChromeAppCacheServiceTest; 30 31 class AppCacheStorageImpl : public AppCacheStorage { 32 public: 33 explicit AppCacheStorageImpl(AppCacheServiceImpl* service); 34 virtual ~AppCacheStorageImpl(); 35 36 void Initialize( 37 const base::FilePath& cache_directory, 38 const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, 39 const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread); 40 void Disable(); 41 bool is_disabled() const { return is_disabled_; } 42 43 // AppCacheStorage methods, see the base class for doc comments. 44 virtual void GetAllInfo(Delegate* delegate) OVERRIDE; 45 virtual void LoadCache(int64 id, Delegate* delegate) OVERRIDE; 46 virtual void LoadOrCreateGroup(const GURL& manifest_url, 47 Delegate* delegate) OVERRIDE; 48 virtual void StoreGroupAndNewestCache(AppCacheGroup* group, 49 AppCache* newest_cache, 50 Delegate* delegate) OVERRIDE; 51 virtual void FindResponseForMainRequest(const GURL& url, 52 const GURL& preferred_manifest_url, 53 Delegate* delegate) OVERRIDE; 54 virtual void FindResponseForSubRequest( 55 AppCache* cache, const GURL& url, 56 AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry, 57 bool* found_network_namespace) OVERRIDE; 58 virtual void MarkEntryAsForeign(const GURL& entry_url, 59 int64 cache_id) OVERRIDE; 60 virtual void MakeGroupObsolete(AppCacheGroup* group, 61 Delegate* delegate, 62 int response_code) OVERRIDE; 63 virtual AppCacheResponseReader* CreateResponseReader( 64 const GURL& manifest_url, int64 group_id, int64 response_id) OVERRIDE; 65 virtual AppCacheResponseWriter* CreateResponseWriter( 66 const GURL& manifest_url, int64 group_id) OVERRIDE; 67 virtual void DoomResponses(const GURL& manifest_url, 68 const std::vector<int64>& response_ids) OVERRIDE; 69 virtual void DeleteResponses(const GURL& manifest_url, 70 const std::vector<int64>& response_ids) OVERRIDE; 71 72 private: 73 // The AppCacheStorageImpl class methods and datamembers may only be 74 // accessed on the IO thread. This class manufactures seperate DatabaseTasks 75 // which access the DB on a seperate background thread. 76 class DatabaseTask; 77 class InitTask; 78 class DisableDatabaseTask; 79 class GetAllInfoTask; 80 class StoreOrLoadTask; 81 class CacheLoadTask; 82 class GroupLoadTask; 83 class StoreGroupAndCacheTask; 84 class FindMainResponseTask; 85 class MarkEntryAsForeignTask; 86 class MakeGroupObsoleteTask; 87 class GetDeletableResponseIdsTask; 88 class InsertDeletableResponseIdsTask; 89 class DeleteDeletableResponseIdsTask; 90 class UpdateGroupLastAccessTimeTask; 91 92 typedef std::deque<DatabaseTask*> DatabaseTaskQueue; 93 typedef std::map<int64, CacheLoadTask*> PendingCacheLoads; 94 typedef std::map<GURL, GroupLoadTask*> PendingGroupLoads; 95 typedef std::deque<std::pair<GURL, int64> > PendingForeignMarkings; 96 typedef std::set<StoreGroupAndCacheTask*> PendingQuotaQueries; 97 98 bool IsInitTaskComplete() { 99 return last_cache_id_ != AppCacheStorage::kUnitializedId; 100 } 101 102 CacheLoadTask* GetPendingCacheLoadTask(int64 cache_id); 103 GroupLoadTask* GetPendingGroupLoadTask(const GURL& manifest_url); 104 void GetPendingForeignMarkingsForCache( 105 int64 cache_id, std::vector<GURL>* urls); 106 107 void ScheduleSimpleTask(const base::Closure& task); 108 void RunOnePendingSimpleTask(); 109 110 void DelayedStartDeletingUnusedResponses(); 111 void StartDeletingResponses(const std::vector<int64>& response_ids); 112 void ScheduleDeleteOneResponse(); 113 void DeleteOneResponse(); 114 115 void OnDeletedOneResponse(int rv); 116 void OnDiskCacheInitialized(int rv); 117 void DeleteAndStartOver(); 118 void DeleteAndStartOverPart2(); 119 void CallScheduleReinitialize(); 120 121 // Sometimes we can respond without having to query the database. 122 bool FindResponseForMainRequestInGroup( 123 AppCacheGroup* group, const GURL& url, Delegate* delegate); 124 void DeliverShortCircuitedFindMainResponse( 125 const GURL& url, 126 const AppCacheEntry& found_entry, 127 scoped_refptr<AppCacheGroup> group, 128 scoped_refptr<AppCache> newest_cache, 129 scoped_refptr<DelegateReference> delegate_ref); 130 131 void CallOnMainResponseFound( 132 DelegateReferenceVector* delegates, 133 const GURL& url, const AppCacheEntry& entry, 134 const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry, 135 int64 cache_id, int64 group_id, const GURL& manifest_url); 136 137 CONTENT_EXPORT AppCacheDiskCache* disk_cache(); 138 139 // The directory in which we place files in the file system. 140 base::FilePath cache_directory_; 141 bool is_incognito_; 142 143 // This class operates primarily on the IO thread, but schedules 144 // its DatabaseTasks on the db thread. Separately, the disk_cache uses 145 // the cache thread. 146 scoped_refptr<base::SingleThreadTaskRunner> db_thread_; 147 scoped_refptr<base::SingleThreadTaskRunner> cache_thread_; 148 149 // Structures to keep track of DatabaseTasks that are in-flight. 150 DatabaseTaskQueue scheduled_database_tasks_; 151 PendingCacheLoads pending_cache_loads_; 152 PendingGroupLoads pending_group_loads_; 153 PendingForeignMarkings pending_foreign_markings_; 154 PendingQuotaQueries pending_quota_queries_; 155 156 // Structures to keep track of lazy response deletion. 157 std::deque<int64> deletable_response_ids_; 158 std::vector<int64> deleted_response_ids_; 159 bool is_response_deletion_scheduled_; 160 bool did_start_deleting_responses_; 161 int64 last_deletable_response_rowid_; 162 163 // Created on the IO thread, but only used on the DB thread. 164 AppCacheDatabase* database_; 165 166 // Set if we discover a fatal error like a corrupt SQL database or 167 // disk cache and cannot continue. 168 bool is_disabled_; 169 170 scoped_ptr<AppCacheDiskCache> disk_cache_; 171 172 // Used to short-circuit certain operations without having to schedule 173 // any tasks on the background database thread. 174 std::deque<base::Closure> pending_simple_tasks_; 175 base::WeakPtrFactory<AppCacheStorageImpl> weak_factory_; 176 177 friend class content::AppCacheStorageImplTest; 178 friend class content::ChromeAppCacheServiceTest; 179 }; 180 181 } // namespace content 182 183 #endif // CONTENT_BROWSER_APPCACHE_APPCACHE_STORAGE_IMPL_H_ 184