1 // Copyright 2014 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_SERVICE_IMPL_H_ 6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_IMPL_H_ 7 8 #include <map> 9 #include <set> 10 11 #include "base/gtest_prod_util.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/observer_list.h" 15 #include "base/time/time.h" 16 #include "base/timer/timer.h" 17 #include "net/base/completion_callback.h" 18 #include "net/base/net_errors.h" 19 #include "webkit/browser/appcache/appcache_service.h" 20 #include "webkit/browser/quota/quota_manager_proxy.h" 21 #include "webkit/browser/webkit_storage_browser_export.h" 22 #include "webkit/common/appcache/appcache_interfaces.h" 23 24 namespace net { 25 class URLRequestContext; 26 } // namespace net 27 28 namespace base { 29 class FilePath; 30 class MessageLoopProxy; 31 } 32 33 namespace content { 34 FORWARD_DECLARE_TEST(AppCacheServiceImplTest, ScheduleReinitialize); 35 class AppCacheServiceImplTest; 36 class AppCacheStorageImplTest; 37 } 38 39 namespace quota { 40 class SpecialStoragePolicy; 41 } 42 43 namespace appcache { 44 45 class AppCacheBackendImpl; 46 class AppCacheExecutableHandlerFactory; 47 class AppCacheQuotaClient; 48 class AppCachePolicy; 49 class AppCacheStorage; 50 51 // Refcounted container to manage the lifetime of the old storage instance 52 // during Reinitialization. 53 class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheStorageReference 54 : public base::RefCounted<AppCacheStorageReference> { 55 public: storage()56 AppCacheStorage* storage() const { return storage_.get(); } 57 private: 58 friend class AppCacheServiceImpl; 59 friend class base::RefCounted<AppCacheStorageReference>; 60 AppCacheStorageReference(scoped_ptr<AppCacheStorage> storage); 61 ~AppCacheStorageReference(); 62 63 scoped_ptr<AppCacheStorage> storage_; 64 }; 65 66 // Class that manages the application cache service. Sends notifications 67 // to many frontends. One instance per user-profile. Each instance has 68 // exclusive access to its cache_directory on disk. 69 class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheServiceImpl 70 : public AppCacheService { 71 public: 72 73 class WEBKIT_STORAGE_BROWSER_EXPORT Observer { 74 public: 75 // An observer method to inform consumers of reinitialzation. Managing 76 // the lifetime of the old storage instance is a delicate process. 77 // Consumers can keep the old disabled instance alive by hanging on to the 78 // ref provided. 79 virtual void OnServiceReinitialized( 80 AppCacheStorageReference* old_storage_ref) = 0; ~Observer()81 virtual ~Observer() {} 82 }; 83 84 // If not using quota management, the proxy may be NULL. 85 explicit AppCacheServiceImpl(quota::QuotaManagerProxy* quota_manager_proxy); 86 virtual ~AppCacheServiceImpl(); 87 88 void Initialize(const base::FilePath& cache_directory, 89 base::MessageLoopProxy* db_thread, 90 base::MessageLoopProxy* cache_thread); 91 AddObserver(Observer * observer)92 void AddObserver(Observer* observer) { 93 observers_.AddObserver(observer); 94 } 95 RemoveObserver(Observer * observer)96 void RemoveObserver(Observer* observer) { 97 observers_.RemoveObserver(observer); 98 } 99 100 // For use in catastrophic failure modes to reboot the appcache system 101 // without relaunching the browser. 102 void ScheduleReinitialize(); 103 104 // AppCacheService implementation: 105 virtual void CanHandleMainResourceOffline( 106 const GURL& url, 107 const GURL& first_party, 108 const net::CompletionCallback& callback) OVERRIDE; 109 virtual void GetAllAppCacheInfo( 110 AppCacheInfoCollection* collection, 111 const net::CompletionCallback& callback) OVERRIDE; 112 virtual void DeleteAppCacheGroup( 113 const GURL& manifest_url, 114 const net::CompletionCallback& callback) OVERRIDE; 115 116 // Deletes all appcaches for the origin, 'callback' is invoked upon 117 // completion. This method always completes asynchronously. 118 // (virtual for unit testing) 119 virtual void DeleteAppCachesForOrigin( 120 const GURL& origin, const net::CompletionCallback& callback); 121 122 // Checks the integrity of 'response_id' by reading the headers and data. 123 // If it cannot be read, the cache group for 'manifest_url' is deleted. 124 void CheckAppCacheResponse(const GURL& manifest_url, int64 cache_id, 125 int64 response_id); 126 127 // Context for use during cache updates, should only be accessed 128 // on the IO thread. We do NOT add a reference to the request context, 129 // it is the callers responsibility to ensure that the pointer 130 // remains valid while set. request_context()131 net::URLRequestContext* request_context() const { return request_context_; } set_request_context(net::URLRequestContext * context)132 void set_request_context(net::URLRequestContext* context) { 133 request_context_ = context; 134 } 135 136 // The appcache policy, may be null, in which case access is always allowed. 137 // The service does NOT assume ownership of the policy, it is the callers 138 // responsibility to ensure that the pointer remains valid while set. appcache_policy()139 AppCachePolicy* appcache_policy() const { return appcache_policy_; } set_appcache_policy(AppCachePolicy * policy)140 void set_appcache_policy(AppCachePolicy* policy) { 141 appcache_policy_ = policy; 142 } 143 144 // The factory may be null, in which case invocations of exe handlers 145 // will result in an error response. 146 // The service does NOT assume ownership of the factory, it is the callers 147 // responsibility to ensure that the pointer remains valid while set. handler_factory()148 AppCacheExecutableHandlerFactory* handler_factory() const { 149 return handler_factory_; 150 } set_handler_factory(AppCacheExecutableHandlerFactory * factory)151 void set_handler_factory( 152 AppCacheExecutableHandlerFactory* factory) { 153 handler_factory_ = factory; 154 } 155 special_storage_policy()156 quota::SpecialStoragePolicy* special_storage_policy() const { 157 return special_storage_policy_.get(); 158 } 159 void set_special_storage_policy(quota::SpecialStoragePolicy* policy); 160 quota_manager_proxy()161 quota::QuotaManagerProxy* quota_manager_proxy() const { 162 return quota_manager_proxy_.get(); 163 } 164 quota_client()165 AppCacheQuotaClient* quota_client() const { 166 return quota_client_; 167 } 168 169 // Each child process in chrome uses a distinct backend instance. 170 // See chrome/browser/AppCacheDispatcherHost. 171 void RegisterBackend(AppCacheBackendImpl* backend_impl); 172 void UnregisterBackend(AppCacheBackendImpl* backend_impl); GetBackend(int id)173 AppCacheBackendImpl* GetBackend(int id) const { 174 BackendMap::const_iterator it = backends_.find(id); 175 return (it != backends_.end()) ? it->second : NULL; 176 } 177 storage()178 AppCacheStorage* storage() const { return storage_.get(); } 179 180 // Disables the exit-time deletion of session-only data. set_force_keep_session_state()181 void set_force_keep_session_state() { force_keep_session_state_ = true; } force_keep_session_state()182 bool force_keep_session_state() const { return force_keep_session_state_; } 183 184 protected: 185 friend class content::AppCacheServiceImplTest; 186 friend class content::AppCacheStorageImplTest; 187 FRIEND_TEST_ALL_PREFIXES(content::AppCacheServiceImplTest, 188 ScheduleReinitialize); 189 190 class AsyncHelper; 191 class CanHandleOfflineHelper; 192 class DeleteHelper; 193 class DeleteOriginHelper; 194 class GetInfoHelper; 195 class CheckResponseHelper; 196 197 typedef std::set<AsyncHelper*> PendingAsyncHelpers; 198 typedef std::map<int, AppCacheBackendImpl*> BackendMap; 199 200 void Reinitialize(); 201 202 base::FilePath cache_directory_; 203 scoped_refptr<base::MessageLoopProxy> db_thread_; 204 scoped_refptr<base::MessageLoopProxy> cache_thread_; 205 AppCachePolicy* appcache_policy_; 206 AppCacheQuotaClient* quota_client_; 207 AppCacheExecutableHandlerFactory* handler_factory_; 208 scoped_ptr<AppCacheStorage> storage_; 209 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_; 210 scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_; 211 PendingAsyncHelpers pending_helpers_; 212 BackendMap backends_; // One 'backend' per child process. 213 // Context for use during cache updates. 214 net::URLRequestContext* request_context_; 215 // If true, nothing (not even session-only data) should be deleted on exit. 216 bool force_keep_session_state_; 217 base::Time last_reinit_time_; 218 base::TimeDelta next_reinit_delay_; 219 base::OneShotTimer<AppCacheServiceImpl> reinit_timer_; 220 ObserverList<Observer> observers_; 221 222 DISALLOW_COPY_AND_ASSIGN(AppCacheServiceImpl); 223 }; 224 225 } // namespace appcache 226 227 #endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_IMPL_H_ 228