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