OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/appcache/appcache_host.h" | 5 #include "webkit/appcache/appcache_host.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "webkit/appcache/appcache.h" | 8 #include "webkit/appcache/appcache.h" |
9 #include "webkit/appcache/appcache_group.h" | 9 #include "webkit/appcache/appcache_group.h" |
10 #include "webkit/appcache/appcache_interfaces.h" | 10 #include "webkit/appcache/appcache_interfaces.h" |
11 #include "webkit/appcache/appcache_request_handler.h" | 11 #include "webkit/appcache/appcache_request_handler.h" |
12 #include "webkit/appcache/appcache_service.h" | 12 #include "webkit/appcache/appcache_service.h" |
13 | 13 |
14 namespace appcache { | 14 namespace appcache { |
15 | 15 |
16 AppCacheHost::AppCacheHost(int host_id, AppCacheFrontend* frontend, | 16 AppCacheHost::AppCacheHost(int host_id, AppCacheFrontend* frontend, |
17 AppCacheService* service) | 17 AppCacheService* service) |
18 : host_id_(host_id), pending_selected_cache_id_(kNoCacheId), | 18 : host_id_(host_id), pending_selected_cache_id_(kNoCacheId), |
19 frontend_(frontend), service_(service), | 19 frontend_(frontend), service_(service), |
20 pending_get_status_callback_(NULL), pending_start_update_callback_(NULL), | 20 pending_get_status_callback_(NULL), pending_start_update_callback_(NULL), |
21 pending_swap_cache_callback_(NULL), pending_callback_param_(NULL) { | 21 pending_swap_cache_callback_(NULL), pending_callback_param_(NULL) { |
22 } | 22 } |
23 | 23 |
24 AppCacheHost::~AppCacheHost() { | 24 AppCacheHost::~AppCacheHost() { |
| 25 FOR_EACH_OBSERVER(Observer, observers_, OnDestructionImminent(this)); |
25 if (associated_cache_.get()) | 26 if (associated_cache_.get()) |
26 associated_cache_->UnassociateHost(this); | 27 associated_cache_->UnassociateHost(this); |
27 service_->CancelLoads(this); | 28 service_->CancelLoads(this); |
28 } | 29 } |
29 | 30 |
| 31 void AppCacheHost::AddObserver(Observer* observer) { |
| 32 observers_.AddObserver(observer); |
| 33 } |
| 34 |
| 35 void AppCacheHost::RemoveObserver(Observer* observer) { |
| 36 observers_.RemoveObserver(observer); |
| 37 } |
| 38 |
30 void AppCacheHost::SelectCache(const GURL& document_url, | 39 void AppCacheHost::SelectCache(const GURL& document_url, |
31 const int64 cache_document_was_loaded_from, | 40 const int64 cache_document_was_loaded_from, |
32 const GURL& manifest_url) { | 41 const GURL& manifest_url) { |
33 DCHECK(!pending_start_update_callback_ && | 42 DCHECK(!pending_start_update_callback_ && |
34 !pending_swap_cache_callback_ && | 43 !pending_swap_cache_callback_ && |
35 !pending_get_status_callback_); | 44 !pending_get_status_callback_); |
36 | 45 |
37 // First we handle an unusual case of SelectCache being called a second | 46 // First we handle an unusual case of SelectCache being called a second |
38 // time. Generally this shouldn't happen, but with bad content I think | 47 // time. Generally this shouldn't happen, but with bad content I think |
39 // this can occur... <html manifest=foo> <html manifest=bar></html></html> | 48 // this can occur... <html manifest=foo> <html manifest=bar></html></html> |
40 // We handle this by killing whatever loading we have initiated, and by | 49 // We handle this by killing whatever loading we have initiated, and by |
41 // unassociating any hosts we currently have associated... and starting | 50 // unassociating any hosts we currently have associated... and starting |
42 // anew with the inputs to this SelectCache call. | 51 // anew with the inputs to this SelectCache call. |
43 // TODO(michaeln): at some point determine what behavior the algorithms | 52 // TODO(michaeln): at some point determine what behavior the algorithms |
44 // described in the HTML5 draft produce and have our impl produce those | 53 // described in the HTML5 draft produce and have our impl produce those |
45 // results (or suggest changes to the algorihtms described in the spec | 54 // results (or suggest changes to the algorihtms described in the spec |
46 // if the resulting behavior is just too insane). | 55 // if the resulting behavior is just too insane). |
47 if (is_selection_pending()) { | 56 if (is_selection_pending()) { |
48 service_->CancelLoads(this); | 57 service_->CancelLoads(this); |
49 pending_selected_manifest_url_ = GURL::EmptyGURL(); | 58 pending_selected_manifest_url_ = GURL::EmptyGURL(); |
50 pending_selected_cache_id_ = kNoCacheId; | 59 pending_selected_cache_id_ = kNoCacheId; |
51 } else if (associated_cache()) { | 60 } else if (associated_cache()) { |
52 AssociateCache(NULL); | 61 AssociateCache(NULL); |
53 } | 62 } |
54 new_master_entry_url_ = GURL::EmptyGURL(); | 63 new_master_entry_url_ = GURL::EmptyGURL(); |
55 | 64 |
56 // 6.9.6 The application cache selection algorithm. | 65 // 6.9.6 The application cache selection algorithm. |
57 // The algorithm is started here and continues in FinishCacheSelection, | 66 // The algorithm is started here and continues in FinishCacheSelection, |
58 // after cache or group loading is complete. | 67 // after cache or group loading is complete. |
59 // Note: foriegn entries are detected on the client side and | 68 // Note: Foreign entries are detected on the client side and |
60 // MarkAsForeignEntry is called in that case, so that detection | 69 // MarkAsForeignEntry is called in that case, so that detection |
61 // step is skipped here. | 70 // step is skipped here. See WebApplicationCacheHostImpl.cc |
62 | 71 |
63 if (cache_document_was_loaded_from != kNoCacheId) { | 72 if (cache_document_was_loaded_from != kNoCacheId) { |
64 LoadCache(cache_document_was_loaded_from); | 73 LoadCache(cache_document_was_loaded_from); |
65 return; | 74 return; |
66 } | 75 } |
67 | 76 |
68 if (!manifest_url.is_empty() && | 77 if (!manifest_url.is_empty() && |
69 (manifest_url.GetOrigin() == document_url.GetOrigin())) { | 78 (manifest_url.GetOrigin() == document_url.GetOrigin())) { |
| 79 // Note: The client detects if the document was not loaded using HTTP GET |
| 80 // and invokes SelectCache without a manifest url, so that detection step |
| 81 // is also skipped here. See WebApplicationCacheHostImpl.cc |
70 new_master_entry_url_ = document_url; | 82 new_master_entry_url_ = document_url; |
71 LoadOrCreateGroup(manifest_url); | 83 LoadOrCreateGroup(manifest_url); |
72 return; | 84 return; |
73 } | 85 } |
74 | 86 |
75 // TODO(michaeln): If there was a manifest URL, the user agent may report | 87 // TODO(michaeln): If there was a manifest URL, the user agent may report |
76 // to the user that it was ignored, to aid in application development. | 88 // to the user that it was ignored, to aid in application development. |
77 FinishCacheSelection(NULL, NULL); | 89 FinishCacheSelection(NULL, NULL); |
78 } | 90 } |
79 | 91 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 false, pending_callback_param_); | 166 false, pending_callback_param_); |
155 | 167 |
156 pending_swap_cache_callback_ = NULL; | 168 pending_swap_cache_callback_ = NULL; |
157 pending_callback_param_ = NULL; | 169 pending_callback_param_ = NULL; |
158 } | 170 } |
159 | 171 |
160 AppCacheRequestHandler* AppCacheHost::CreateRequestHandler( | 172 AppCacheRequestHandler* AppCacheHost::CreateRequestHandler( |
161 URLRequest* request, | 173 URLRequest* request, |
162 bool is_main_request) { | 174 bool is_main_request) { |
163 if (is_main_request) | 175 if (is_main_request) |
164 return new AppCacheRequestHandler(this); | 176 return new AppCacheRequestHandler(this, true); |
165 | 177 |
166 if (associated_cache() && associated_cache()->is_complete()) | 178 if ((associated_cache() && associated_cache()->is_complete()) || |
167 return new AppCacheRequestHandler(associated_cache()); | 179 is_selection_pending()) |
| 180 return new AppCacheRequestHandler(this, false); |
168 | 181 |
169 return NULL; | 182 return NULL; |
170 } | 183 } |
171 | 184 |
172 Status AppCacheHost::GetStatus() { | 185 Status AppCacheHost::GetStatus() { |
173 // TODO(michaeln): determine a real status value | 186 // TODO(michaeln): determine a real status value |
174 Status status = associated_cache() ? IDLE : UNCACHED; | 187 Status status = associated_cache() ? IDLE : UNCACHED; |
175 return status; | 188 return status; |
176 } | 189 } |
177 | 190 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 AssociateCache(NULL); | 246 AssociateCache(NULL); |
234 } | 247 } |
235 | 248 |
236 // Respond to pending callbacks now that we have a selection. | 249 // Respond to pending callbacks now that we have a selection. |
237 if (pending_get_status_callback_) | 250 if (pending_get_status_callback_) |
238 DoPendingGetStatus(); | 251 DoPendingGetStatus(); |
239 else if (pending_start_update_callback_) | 252 else if (pending_start_update_callback_) |
240 DoPendingStartUpdate(); | 253 DoPendingStartUpdate(); |
241 else if (pending_swap_cache_callback_) | 254 else if (pending_swap_cache_callback_) |
242 DoPendingSwapCache(); | 255 DoPendingSwapCache(); |
| 256 |
| 257 FOR_EACH_OBSERVER(Observer, observers_, OnCacheSelectionComplete(this)); |
243 } | 258 } |
244 | 259 |
245 void AppCacheHost::AssociateCache(AppCache* cache) { | 260 void AppCacheHost::AssociateCache(AppCache* cache) { |
246 if (associated_cache_.get()) { | 261 if (associated_cache_.get()) { |
247 associated_cache_->UnassociateHost(this); | 262 associated_cache_->UnassociateHost(this); |
248 group_ = NULL; | 263 group_ = NULL; |
249 } | 264 } |
250 | 265 |
251 associated_cache_ = cache; | 266 associated_cache_ = cache; |
252 | 267 |
253 if (cache) { | 268 if (cache) { |
254 cache->AssociateHost(this); | 269 cache->AssociateHost(this); |
255 group_ = cache->owning_group(); | 270 group_ = cache->owning_group(); |
256 frontend_->OnCacheSelected(host_id_, cache->cache_id(), GetStatus()); | 271 frontend_->OnCacheSelected(host_id_, cache->cache_id(), GetStatus()); |
257 } else { | 272 } else { |
258 frontend_->OnCacheSelected(host_id_, kNoCacheId, UNCACHED); | 273 frontend_->OnCacheSelected(host_id_, kNoCacheId, UNCACHED); |
259 } | 274 } |
260 } | 275 } |
261 | 276 |
262 } // namespace appcache | 277 } // namespace appcache |
OLD | NEW |