OLD | NEW |
| (Empty) |
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_HOST_H_ | |
6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_HOST_H_ | |
7 | |
8 #include "base/callback.h" | |
9 #include "base/gtest_prod_util.h" | |
10 #include "base/memory/ref_counted.h" | |
11 #include "base/observer_list.h" | |
12 #include "url/gurl.h" | |
13 #include "webkit/browser/appcache/appcache_group.h" | |
14 #include "webkit/browser/appcache/appcache_service_impl.h" | |
15 #include "webkit/browser/appcache/appcache_storage.h" | |
16 #include "webkit/browser/webkit_storage_browser_export.h" | |
17 #include "webkit/common/appcache/appcache_interfaces.h" | |
18 #include "webkit/common/resource_type.h" | |
19 | |
20 namespace net { | |
21 class URLRequest; | |
22 } // namespace net | |
23 | |
24 namespace content { | |
25 FORWARD_DECLARE_TEST(AppCacheGroupTest, CleanupUnusedGroup); | |
26 FORWARD_DECLARE_TEST(AppCacheGroupTest, QueueUpdate); | |
27 FORWARD_DECLARE_TEST(AppCacheHostTest, Basic); | |
28 FORWARD_DECLARE_TEST(AppCacheHostTest, SelectNoCache); | |
29 FORWARD_DECLARE_TEST(AppCacheHostTest, ForeignEntry); | |
30 FORWARD_DECLARE_TEST(AppCacheHostTest, FailedCacheLoad); | |
31 FORWARD_DECLARE_TEST(AppCacheHostTest, FailedGroupLoad); | |
32 FORWARD_DECLARE_TEST(AppCacheHostTest, SetSwappableCache); | |
33 FORWARD_DECLARE_TEST(AppCacheHostTest, ForDedicatedWorker); | |
34 FORWARD_DECLARE_TEST(AppCacheHostTest, SelectCacheAllowed); | |
35 FORWARD_DECLARE_TEST(AppCacheHostTest, SelectCacheBlocked); | |
36 FORWARD_DECLARE_TEST(AppCacheTest, CleanupUnusedCache); | |
37 class AppCacheTest; | |
38 class AppCacheHostTest; | |
39 class AppCacheGroupTest; | |
40 class AppCacheStorageImplTest; | |
41 class AppCacheRequestHandlerTest; | |
42 class AppCacheUpdateJobTest; | |
43 } | |
44 | |
45 namespace appcache { | |
46 | |
47 class AppCache; | |
48 class AppCacheFrontend; | |
49 class AppCacheRequestHandler; | |
50 | |
51 typedef base::Callback<void(AppCacheStatus, void*)> GetStatusCallback; | |
52 typedef base::Callback<void(bool, void*)> StartUpdateCallback; | |
53 typedef base::Callback<void(bool, void*)> SwapCacheCallback; | |
54 | |
55 // Server-side representation of an application cache host. | |
56 class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheHost | |
57 : public AppCacheStorage::Delegate, | |
58 public AppCacheGroup::UpdateObserver, | |
59 public AppCacheServiceImpl::Observer { | |
60 public: | |
61 | |
62 class WEBKIT_STORAGE_BROWSER_EXPORT Observer { | |
63 public: | |
64 // Called just after the cache selection algorithm completes. | |
65 virtual void OnCacheSelectionComplete(AppCacheHost* host) = 0; | |
66 | |
67 // Called just prior to the instance being deleted. | |
68 virtual void OnDestructionImminent(AppCacheHost* host) = 0; | |
69 | |
70 virtual ~Observer() {} | |
71 }; | |
72 | |
73 AppCacheHost(int host_id, AppCacheFrontend* frontend, | |
74 AppCacheServiceImpl* service); | |
75 virtual ~AppCacheHost(); | |
76 | |
77 // Adds/removes an observer, the AppCacheHost does not take | |
78 // ownership of the observer. | |
79 void AddObserver(Observer* observer); | |
80 void RemoveObserver(Observer* observer); | |
81 | |
82 // Support for cache selection and scriptable method calls. | |
83 void SelectCache(const GURL& document_url, | |
84 const int64 cache_document_was_loaded_from, | |
85 const GURL& manifest_url); | |
86 void SelectCacheForWorker(int parent_process_id, | |
87 int parent_host_id); | |
88 void SelectCacheForSharedWorker(int64 appcache_id); | |
89 void MarkAsForeignEntry(const GURL& document_url, | |
90 int64 cache_document_was_loaded_from); | |
91 void GetStatusWithCallback(const GetStatusCallback& callback, | |
92 void* callback_param); | |
93 void StartUpdateWithCallback(const StartUpdateCallback& callback, | |
94 void* callback_param); | |
95 void SwapCacheWithCallback(const SwapCacheCallback& callback, | |
96 void* callback_param); | |
97 | |
98 // Called prior to the main resource load. When the system contains multiple | |
99 // candidates for a main resource load, the appcache preferred by the host | |
100 // that created this host is used to break ties. | |
101 void SetSpawningHostId(int spawning_process_id, int spawning_host_id); | |
102 | |
103 // May return NULL if the spawning host context has been closed, or if a | |
104 // spawning host context was never identified. | |
105 const AppCacheHost* GetSpawningHost() const; | |
106 | |
107 const GURL& preferred_manifest_url() const { | |
108 return preferred_manifest_url_; | |
109 } | |
110 void set_preferred_manifest_url(const GURL& url) { | |
111 preferred_manifest_url_ = url; | |
112 } | |
113 | |
114 // Support for loading resources out of the appcache. | |
115 // May return NULL if the request isn't subject to retrieval from an appache. | |
116 AppCacheRequestHandler* CreateRequestHandler( | |
117 net::URLRequest* request, ResourceType::Type resource_type); | |
118 | |
119 // Support for devtools inspecting appcache resources. | |
120 void GetResourceList(std::vector<AppCacheResourceInfo>* resource_infos); | |
121 | |
122 // Breaks any existing association between this host and a cache. | |
123 // 'manifest_url' is sent to DevTools as the manifest url that could have | |
124 // been associated before or could be associated later with this host. | |
125 // Associations are broken either thru the cache selection algorithm | |
126 // implemented in this class, or by the update algorithm (see | |
127 // AppCacheUpdateJob). | |
128 void AssociateNoCache(const GURL& manifest_url); | |
129 | |
130 // Establishes an association between this host and an incomplete cache. | |
131 // 'manifest_url' is manifest url of the cache group being updated. | |
132 // Associations with incomplete caches are established by the update algorithm | |
133 // (see AppCacheUpdateJob). | |
134 void AssociateIncompleteCache(AppCache* cache, const GURL& manifest_url); | |
135 | |
136 // Establishes an association between this host and a complete cache. | |
137 // Associations with complete caches are established either thru the cache | |
138 // selection algorithm implemented (in this class), or by the update algorithm | |
139 // (see AppCacheUpdateJob). | |
140 void AssociateCompleteCache(AppCache* cache); | |
141 | |
142 // Adds a reference to the newest complete cache in a group, unless it's the | |
143 // same as the cache that is currently associated with the host. | |
144 void SetSwappableCache(AppCacheGroup* group); | |
145 | |
146 // Used to ensure that a loaded appcache survives a frame navigation. | |
147 void LoadMainResourceCache(int64 cache_id); | |
148 | |
149 // Used to notify the host that a namespace resource is being delivered as | |
150 // the main resource of the page and to provide its url. | |
151 void NotifyMainResourceIsNamespaceEntry(const GURL& namespace_entry_url); | |
152 | |
153 // Used to notify the host that the main resource was blocked by a policy. To | |
154 // work properly, this method needs to by invoked prior to cache selection. | |
155 void NotifyMainResourceBlocked(const GURL& manifest_url); | |
156 | |
157 // Used by the update job to keep track of which hosts are associated | |
158 // with which pending master entries. | |
159 const GURL& pending_master_entry_url() const { | |
160 return new_master_entry_url_; | |
161 } | |
162 | |
163 int host_id() const { return host_id_; } | |
164 AppCacheServiceImpl* service() const { return service_; } | |
165 AppCacheStorage* storage() const { return storage_; } | |
166 AppCacheFrontend* frontend() const { return frontend_; } | |
167 AppCache* associated_cache() const { return associated_cache_.get(); } | |
168 | |
169 bool is_selection_pending() const { | |
170 return pending_selected_cache_id_ != kAppCacheNoCacheId || | |
171 !pending_selected_manifest_url_.is_empty(); | |
172 } | |
173 | |
174 const GURL& first_party_url() const { return first_party_url_; } | |
175 | |
176 // Methods to support cross site navigations. | |
177 void PrepareForTransfer(); | |
178 void CompleteTransfer(int host_id, AppCacheFrontend* frontend); | |
179 | |
180 private: | |
181 friend class content::AppCacheHostTest; | |
182 friend class content::AppCacheStorageImplTest; | |
183 friend class content::AppCacheRequestHandlerTest; | |
184 friend class content::AppCacheUpdateJobTest; | |
185 | |
186 AppCacheStatus GetStatus(); | |
187 void LoadSelectedCache(int64 cache_id); | |
188 void LoadOrCreateGroup(const GURL& manifest_url); | |
189 | |
190 // See public Associate*Host() methods above. | |
191 void AssociateCacheHelper(AppCache* cache, const GURL& manifest_url); | |
192 | |
193 // AppCacheStorage::Delegate impl | |
194 virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) OVERRIDE; | |
195 virtual void OnGroupLoaded(AppCacheGroup* group, | |
196 const GURL& manifest_url) OVERRIDE; | |
197 // AppCacheServiceImpl::Observer impl | |
198 virtual void OnServiceReinitialized( | |
199 AppCacheStorageReference* old_storage_ref) OVERRIDE; | |
200 | |
201 void FinishCacheSelection(AppCache* cache, AppCacheGroup* group); | |
202 void DoPendingGetStatus(); | |
203 void DoPendingStartUpdate(); | |
204 void DoPendingSwapCache(); | |
205 | |
206 void ObserveGroupBeingUpdated(AppCacheGroup* group); | |
207 | |
208 // AppCacheGroup::UpdateObserver methods. | |
209 virtual void OnUpdateComplete(AppCacheGroup* group) OVERRIDE; | |
210 | |
211 // Returns true if this host is for a dedicated worker context. | |
212 bool is_for_dedicated_worker() const { | |
213 return parent_host_id_ != kAppCacheNoHostId; | |
214 } | |
215 | |
216 // Returns the parent context's host instance. This is only valid | |
217 // to call when this instance is_for_dedicated_worker. | |
218 AppCacheHost* GetParentAppCacheHost() const; | |
219 | |
220 // Identifies the corresponding appcache host in the child process. | |
221 int host_id_; | |
222 | |
223 // Information about the host that created this one; the manifest | |
224 // preferred by our creator influences which cache our main resource | |
225 // should be loaded from. | |
226 int spawning_host_id_; | |
227 int spawning_process_id_; | |
228 GURL preferred_manifest_url_; | |
229 | |
230 // Hosts for dedicated workers are special cased to shunt | |
231 // request handling off to the dedicated worker's parent. | |
232 // The scriptable api is not accessible in dedicated workers | |
233 // so the other aspects of this class are not relevant for | |
234 // these special case instances. | |
235 int parent_host_id_; | |
236 int parent_process_id_; | |
237 | |
238 // Defined prior to refs to AppCaches and Groups because destruction | |
239 // order matters, the disabled_storage_reference_ must outlive those | |
240 // objects. See additional comments for the storage_ member. | |
241 scoped_refptr<AppCacheStorageReference> disabled_storage_reference_; | |
242 | |
243 // The cache associated with this host, if any. | |
244 scoped_refptr<AppCache> associated_cache_; | |
245 | |
246 // Hold a reference to the newest complete cache (if associated cache is | |
247 // not the newest) to keep the newest cache in existence while the app cache | |
248 // group is in use. The newest complete cache may have no associated hosts | |
249 // holding any references to it and would otherwise be deleted prematurely. | |
250 scoped_refptr<AppCache> swappable_cache_; | |
251 | |
252 // Keep a reference to the group being updated until the update completes. | |
253 scoped_refptr<AppCacheGroup> group_being_updated_; | |
254 | |
255 // Similarly, keep a reference to the newest cache of the group until the | |
256 // update completes. When adding a new master entry to a cache that is not | |
257 // in use in any other host, this reference keeps the cache in memory. | |
258 scoped_refptr<AppCache> newest_cache_of_group_being_updated_; | |
259 | |
260 // Keep a reference to the cache of the main resource so it survives frame | |
261 // navigations. | |
262 scoped_refptr<AppCache> main_resource_cache_; | |
263 int64 pending_main_resource_cache_id_; | |
264 | |
265 // Cache loading is async, if we're loading a specific cache or group | |
266 // for the purposes of cache selection, one or the other of these will | |
267 // indicate which cache or group is being loaded. | |
268 int64 pending_selected_cache_id_; | |
269 GURL pending_selected_manifest_url_; | |
270 | |
271 // A new master entry to be added to the cache, may be empty. | |
272 GURL new_master_entry_url_; | |
273 | |
274 // The frontend proxy to deliver notifications to the child process. | |
275 AppCacheFrontend* frontend_; | |
276 | |
277 // Our central service object. | |
278 AppCacheServiceImpl* service_; | |
279 | |
280 // And the equally central storage object, with a twist. In some error | |
281 // conditions the storage object gets recreated and reinitialized. The | |
282 // disabled_storage_reference_ (defined earlier) allows for cleanup of an | |
283 // instance that got disabled after we had latched onto it. In normal | |
284 // circumstances, disabled_storage_reference_ is expected to be NULL. | |
285 // When non-NULL both storage_ and disabled_storage_reference_ refer to the | |
286 // same instance. | |
287 AppCacheStorage* storage_; | |
288 | |
289 // Since these are synchronous scriptable API calls in the client, there can | |
290 // only be one type of callback pending. Also, we have to wait until we have a | |
291 // cache selection prior to responding to these calls, as cache selection | |
292 // involves async loading of a cache or a group from storage. | |
293 GetStatusCallback pending_get_status_callback_; | |
294 StartUpdateCallback pending_start_update_callback_; | |
295 SwapCacheCallback pending_swap_cache_callback_; | |
296 void* pending_callback_param_; | |
297 | |
298 // True if an intercept or fallback namespace resource was | |
299 // delivered as the main resource. | |
300 bool main_resource_was_namespace_entry_; | |
301 GURL namespace_entry_url_; | |
302 | |
303 // True if requests for this host were blocked by a policy. | |
304 bool main_resource_blocked_; | |
305 GURL blocked_manifest_url_; | |
306 | |
307 // Tells if info about associated cache is pending. Info is pending | |
308 // when update job has not returned success yet. | |
309 bool associated_cache_info_pending_; | |
310 | |
311 // List of objects observing us. | |
312 ObserverList<Observer> observers_; | |
313 | |
314 // Used to inform the QuotaManager of what origins are currently in use. | |
315 GURL origin_in_use_; | |
316 | |
317 // First party url to be used in policy checks. | |
318 GURL first_party_url_; | |
319 | |
320 FRIEND_TEST_ALL_PREFIXES(content::AppCacheGroupTest, CleanupUnusedGroup); | |
321 FRIEND_TEST_ALL_PREFIXES(content::AppCacheGroupTest, QueueUpdate); | |
322 FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, Basic); | |
323 FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SelectNoCache); | |
324 FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, ForeignEntry); | |
325 FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, FailedCacheLoad); | |
326 FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, FailedGroupLoad); | |
327 FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SetSwappableCache); | |
328 FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, ForDedicatedWorker); | |
329 FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SelectCacheAllowed); | |
330 FRIEND_TEST_ALL_PREFIXES(content::AppCacheHostTest, SelectCacheBlocked); | |
331 FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest, CleanupUnusedCache); | |
332 | |
333 DISALLOW_COPY_AND_ASSIGN(AppCacheHost); | |
334 }; | |
335 | |
336 } // namespace appcache | |
337 | |
338 #endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_HOST_H_ | |
OLD | NEW |