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 3 // found in the LICENSE file. 4 5 #ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_H_ 6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_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 "net/base/completion_callback.h" 15 #include "net/base/net_errors.h" 16 #include "webkit/browser/appcache/appcache_storage.h" 17 #include "webkit/browser/webkit_storage_browser_export.h" 18 #include "webkit/common/appcache/appcache_interfaces.h" 19 20 namespace net { 21 class URLRequestContext; 22 } // namespace net 23 24 namespace base { 25 class FilePath; 26 class MessageLoopProxy; 27 } 28 29 namespace quota { 30 class QuotaManagerProxy; 31 class SpecialStoragePolicy; 32 } 33 34 namespace appcache { 35 36 class AppCacheBackendImpl; 37 class AppCacheExecutableHandlerFactory; 38 class AppCacheQuotaClient; 39 class AppCachePolicy; 40 41 // Refcounted container to avoid copying the collection in callbacks. 42 struct WEBKIT_STORAGE_BROWSER_EXPORT AppCacheInfoCollection 43 : public base::RefCountedThreadSafe<AppCacheInfoCollection> { 44 AppCacheInfoCollection(); 45 46 std::map<GURL, AppCacheInfoVector> infos_by_origin; 47 48 private: 49 friend class base::RefCountedThreadSafe<AppCacheInfoCollection>; 50 virtual ~AppCacheInfoCollection(); 51 }; 52 53 // Class that manages the application cache service. Sends notifications 54 // to many frontends. One instance per user-profile. Each instance has 55 // exclusive access to its cache_directory on disk. 56 class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheService { 57 public: 58 // If not using quota management, the proxy may be NULL. 59 explicit AppCacheService(quota::QuotaManagerProxy* quota_manager_proxy); 60 virtual ~AppCacheService(); 61 62 void Initialize(const base::FilePath& cache_directory, 63 base::MessageLoopProxy* db_thread, 64 base::MessageLoopProxy* cache_thread); 65 66 // Purges any memory not needed. 67 void PurgeMemory() { 68 if (storage_) 69 storage_->PurgeMemory(); 70 } 71 72 // Determines if a request for 'url' can be satisfied while offline. 73 // This method always completes asynchronously. 74 void CanHandleMainResourceOffline(const GURL& url, 75 const GURL& first_party, 76 const net::CompletionCallback& callback); 77 78 // Populates 'collection' with info about all of the appcaches stored 79 // within the service, 'callback' is invoked upon completion. The service 80 // acquires a reference to the 'collection' until until completion. 81 // This method always completes asynchronously. 82 void GetAllAppCacheInfo(AppCacheInfoCollection* collection, 83 const net::CompletionCallback& callback); 84 85 // Deletes the group identified by 'manifest_url', 'callback' is 86 // invoked upon completion. Upon completion, the cache group and 87 // any resources within the group are no longer loadable and all 88 // subresource loads for pages associated with a deleted group 89 // will fail. This method always completes asynchronously. 90 void DeleteAppCacheGroup(const GURL& manifest_url, 91 const net::CompletionCallback& callback); 92 93 // Deletes all appcaches for the origin, 'callback' is invoked upon 94 // completion. This method always completes asynchronously. 95 // (virtual for unit testing) 96 virtual void DeleteAppCachesForOrigin( 97 const GURL& origin, const net::CompletionCallback& callback); 98 99 // Checks the integrity of 'response_id' by reading the headers and data. 100 // If it cannot be read, the cache group for 'manifest_url' is deleted. 101 void CheckAppCacheResponse(const GURL& manifest_url, int64 cache_id, 102 int64 response_id); 103 104 // Context for use during cache updates, should only be accessed 105 // on the IO thread. We do NOT add a reference to the request context, 106 // it is the callers responsibility to ensure that the pointer 107 // remains valid while set. 108 net::URLRequestContext* request_context() const { return request_context_; } 109 void set_request_context(net::URLRequestContext* context) { 110 request_context_ = context; 111 } 112 113 // The appcache policy, may be null, in which case access is always allowed. 114 // The service does NOT assume ownership of the policy, it is the callers 115 // responsibility to ensure that the pointer remains valid while set. 116 AppCachePolicy* appcache_policy() const { return appcache_policy_; } 117 void set_appcache_policy(AppCachePolicy* policy) { 118 appcache_policy_ = policy; 119 } 120 121 // The factory may be null, in which case invocations of exe handlers 122 // will result in an error response. 123 // The service does NOT assume ownership of the factory, it is the callers 124 // responsibility to ensure that the pointer remains valid while set. 125 AppCacheExecutableHandlerFactory* handler_factory() const { 126 return handler_factory_; 127 } 128 void set_handler_factory( 129 AppCacheExecutableHandlerFactory* factory) { 130 handler_factory_ = factory; 131 } 132 133 quota::SpecialStoragePolicy* special_storage_policy() const { 134 return special_storage_policy_.get(); 135 } 136 void set_special_storage_policy(quota::SpecialStoragePolicy* policy); 137 138 quota::QuotaManagerProxy* quota_manager_proxy() const { 139 return quota_manager_proxy_.get(); 140 } 141 142 AppCacheQuotaClient* quota_client() const { 143 return quota_client_; 144 } 145 146 // Each child process in chrome uses a distinct backend instance. 147 // See chrome/browser/AppCacheDispatcherHost. 148 void RegisterBackend(AppCacheBackendImpl* backend_impl); 149 void UnregisterBackend(AppCacheBackendImpl* backend_impl); 150 AppCacheBackendImpl* GetBackend(int id) const { 151 BackendMap::const_iterator it = backends_.find(id); 152 return (it != backends_.end()) ? it->second : NULL; 153 } 154 155 AppCacheStorage* storage() const { return storage_.get(); } 156 157 // Disables the exit-time deletion of session-only data. 158 void set_force_keep_session_state() { force_keep_session_state_ = true; } 159 bool force_keep_session_state() const { return force_keep_session_state_; } 160 161 protected: 162 friend class AppCacheStorageImplTest; 163 friend class AppCacheServiceTest; 164 165 class AsyncHelper; 166 class CanHandleOfflineHelper; 167 class DeleteHelper; 168 class DeleteOriginHelper; 169 class GetInfoHelper; 170 class CheckResponseHelper; 171 172 typedef std::set<AsyncHelper*> PendingAsyncHelpers; 173 typedef std::map<int, AppCacheBackendImpl*> BackendMap; 174 175 AppCachePolicy* appcache_policy_; 176 AppCacheQuotaClient* quota_client_; 177 AppCacheExecutableHandlerFactory* handler_factory_; 178 scoped_ptr<AppCacheStorage> storage_; 179 scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_; 180 scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_; 181 PendingAsyncHelpers pending_helpers_; 182 BackendMap backends_; // One 'backend' per child process. 183 // Context for use during cache updates. 184 net::URLRequestContext* request_context_; 185 // If true, nothing (not even session-only data) should be deleted on exit. 186 bool force_keep_session_state_; 187 188 DISALLOW_COPY_AND_ASSIGN(AppCacheService); 189 }; 190 191 } // namespace appcache 192 193 #endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_H_ 194