• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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