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.
5 #ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_IMPL_H_
6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_IMPL_H_
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"
25 class URLRequestContext
;
30 class MessageLoopProxy
;
34 FORWARD_DECLARE_TEST(AppCacheServiceImplTest
, ScheduleReinitialize
);
35 class AppCacheServiceImplTest
;
36 class AppCacheStorageImplTest
;
40 class SpecialStoragePolicy
;
45 class AppCacheBackendImpl
;
46 class AppCacheExecutableHandlerFactory
;
47 class AppCacheQuotaClient
;
49 class AppCacheStorage
;
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
> {
56 AppCacheStorage
* storage() const { return storage_
.get(); }
58 friend class AppCacheServiceImpl
;
59 friend class base::RefCounted
<AppCacheStorageReference
>;
60 AppCacheStorageReference(scoped_ptr
<AppCacheStorage
> storage
);
61 ~AppCacheStorageReference();
63 scoped_ptr
<AppCacheStorage
> storage_
;
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
{
73 class WEBKIT_STORAGE_BROWSER_EXPORT Observer
{
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
79 virtual void OnServiceReinitialized(
80 AppCacheStorageReference
* old_storage_ref
) = 0;
81 virtual ~Observer() {}
84 // If not using quota management, the proxy may be NULL.
85 explicit AppCacheServiceImpl(quota::QuotaManagerProxy
* quota_manager_proxy
);
86 virtual ~AppCacheServiceImpl();
88 void Initialize(const base::FilePath
& cache_directory
,
89 base::MessageLoopProxy
* db_thread
,
90 base::MessageLoopProxy
* cache_thread
);
92 void AddObserver(Observer
* observer
) {
93 observers_
.AddObserver(observer
);
96 void RemoveObserver(Observer
* observer
) {
97 observers_
.RemoveObserver(observer
);
100 // For use in catastrophic failure modes to reboot the appcache system
101 // without relaunching the browser.
102 void ScheduleReinitialize();
104 // AppCacheService implementation:
105 virtual void CanHandleMainResourceOffline(
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
;
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
);
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
,
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.
131 net::URLRequestContext
* request_context() const { return request_context_
; }
132 void set_request_context(net::URLRequestContext
* context
) {
133 request_context_
= context
;
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.
139 AppCachePolicy
* appcache_policy() const { return appcache_policy_
; }
140 void set_appcache_policy(AppCachePolicy
* policy
) {
141 appcache_policy_
= policy
;
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.
148 AppCacheExecutableHandlerFactory
* handler_factory() const {
149 return handler_factory_
;
151 void set_handler_factory(
152 AppCacheExecutableHandlerFactory
* factory
) {
153 handler_factory_
= factory
;
156 quota::SpecialStoragePolicy
* special_storage_policy() const {
157 return special_storage_policy_
.get();
159 void set_special_storage_policy(quota::SpecialStoragePolicy
* policy
);
161 quota::QuotaManagerProxy
* quota_manager_proxy() const {
162 return quota_manager_proxy_
.get();
165 AppCacheQuotaClient
* quota_client() const {
166 return quota_client_
;
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
);
173 AppCacheBackendImpl
* GetBackend(int id
) const {
174 BackendMap::const_iterator it
= backends_
.find(id
);
175 return (it
!= backends_
.end()) ? it
->second
: NULL
;
178 AppCacheStorage
* storage() const { return storage_
.get(); }
180 // Disables the exit-time deletion of session-only data.
181 void set_force_keep_session_state() { force_keep_session_state_
= true; }
182 bool force_keep_session_state() const { return force_keep_session_state_
; }
185 friend class content::AppCacheServiceImplTest
;
186 friend class content::AppCacheStorageImplTest
;
187 FRIEND_TEST_ALL_PREFIXES(content::AppCacheServiceImplTest
,
188 ScheduleReinitialize
);
191 class CanHandleOfflineHelper
;
193 class DeleteOriginHelper
;
195 class CheckResponseHelper
;
197 typedef std::set
<AsyncHelper
*> PendingAsyncHelpers
;
198 typedef std::map
<int, AppCacheBackendImpl
*> BackendMap
;
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_
;
222 DISALLOW_COPY_AND_ASSIGN(AppCacheServiceImpl
);
225 } // namespace appcache
227 #endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_IMPL_H_