Dismiss autofill popup on screen orientation change.
[chromium-blink-merge.git] / webkit / browser / appcache / appcache_update_job.h
blob61b88271c6a5dbecf010fbd18eed956087881890
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.
5 #ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
8 #include <deque>
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <vector>
14 #include "base/gtest_prod_util.h"
15 #include "base/memory/ref_counted.h"
16 #include "net/base/completion_callback.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/url_request/url_request.h"
19 #include "url/gurl.h"
20 #include "webkit/browser/appcache/appcache.h"
21 #include "webkit/browser/appcache/appcache_host.h"
22 #include "webkit/browser/appcache/appcache_response.h"
23 #include "webkit/browser/appcache/appcache_storage.h"
24 #include "webkit/browser/webkit_storage_browser_export.h"
25 #include "webkit/common/appcache/appcache_interfaces.h"
27 namespace appcache {
29 class HostNotifier;
31 // Application cache Update algorithm and state.
32 class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheUpdateJob
33 : public AppCacheStorage::Delegate,
34 public AppCacheHost::Observer {
35 public:
36 AppCacheUpdateJob(AppCacheService* service, AppCacheGroup* group);
37 virtual ~AppCacheUpdateJob();
39 // Triggers the update process or adds more info if this update is already
40 // in progress.
41 void StartUpdate(AppCacheHost* host, const GURL& new_master_resource);
43 private:
44 friend class AppCacheUpdateJobTest;
45 class URLFetcher;
47 // Master entries have multiple hosts, for example, the same page is opened
48 // in different tabs.
49 typedef std::vector<AppCacheHost*> PendingHosts;
50 typedef std::map<GURL, PendingHosts> PendingMasters;
51 typedef std::map<GURL, URLFetcher*> PendingUrlFetches;
52 typedef std::map<int64, GURL> LoadingResponses;
54 static const int kRerunDelayMs = 1000;
56 // TODO(michaeln): Rework the set of states vs update types vs stored states.
57 // The NO_UPDATE state is really more of an update type. For all update types
58 // storing the results is relevant.
60 enum UpdateType {
61 UNKNOWN_TYPE,
62 UPGRADE_ATTEMPT,
63 CACHE_ATTEMPT,
66 enum InternalUpdateState {
67 FETCH_MANIFEST,
68 NO_UPDATE,
69 DOWNLOADING,
71 // Every state after this comment indicates the update is terminating.
72 REFETCH_MANIFEST,
73 CACHE_FAILURE,
74 CANCELLED,
75 COMPLETED,
78 enum StoredState {
79 UNSTORED,
80 STORING,
81 STORED,
84 struct UrlToFetch {
85 UrlToFetch(const GURL& url, bool checked, AppCacheResponseInfo* info);
86 ~UrlToFetch();
88 GURL url;
89 bool storage_checked;
90 scoped_refptr<AppCacheResponseInfo> existing_response_info;
93 class URLFetcher : public net::URLRequest::Delegate {
94 public:
95 enum FetchType {
96 MANIFEST_FETCH,
97 URL_FETCH,
98 MASTER_ENTRY_FETCH,
99 MANIFEST_REFETCH,
101 URLFetcher(const GURL& url,
102 FetchType fetch_type,
103 AppCacheUpdateJob* job);
104 virtual ~URLFetcher();
105 void Start();
106 FetchType fetch_type() const { return fetch_type_; }
107 net::URLRequest* request() const { return request_.get(); }
108 const AppCacheEntry& existing_entry() const { return existing_entry_; }
109 const std::string& manifest_data() const { return manifest_data_; }
110 AppCacheResponseWriter* response_writer() const {
111 return response_writer_.get();
113 void set_existing_response_headers(net::HttpResponseHeaders* headers) {
114 existing_response_headers_ = headers;
116 void set_existing_entry(const AppCacheEntry& entry) {
117 existing_entry_ = entry;
120 private:
121 // URLRequest::Delegate overrides
122 virtual void OnReceivedRedirect(net::URLRequest* request,
123 const GURL& new_url,
124 bool* defer_redirect) OVERRIDE;
125 virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
126 virtual void OnReadCompleted(net::URLRequest* request,
127 int bytes_read) OVERRIDE;
129 void AddConditionalHeaders(const net::HttpResponseHeaders* headers);
130 void OnWriteComplete(int result);
131 void ReadResponseData();
132 bool ConsumeResponseData(int bytes_read);
133 void OnResponseCompleted();
134 bool MaybeRetryRequest();
136 GURL url_;
137 AppCacheUpdateJob* job_;
138 FetchType fetch_type_;
139 int retry_503_attempts_;
140 scoped_refptr<net::IOBuffer> buffer_;
141 scoped_ptr<net::URLRequest> request_;
142 AppCacheEntry existing_entry_;
143 scoped_refptr<net::HttpResponseHeaders> existing_response_headers_;
144 std::string manifest_data_;
145 scoped_ptr<AppCacheResponseWriter> response_writer_;
146 }; // class URLFetcher
148 AppCacheResponseWriter* CreateResponseWriter();
150 // Methods for AppCacheStorage::Delegate.
151 virtual void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
152 int64 response_id) OVERRIDE;
153 virtual void OnGroupAndNewestCacheStored(AppCacheGroup* group,
154 AppCache* newest_cache,
155 bool success,
156 bool would_exceed_quota) OVERRIDE;
157 virtual void OnGroupMadeObsolete(AppCacheGroup* group, bool success) OVERRIDE;
159 // Methods for AppCacheHost::Observer.
160 virtual void OnCacheSelectionComplete(AppCacheHost* host) OVERRIDE {} // N/A
161 virtual void OnDestructionImminent(AppCacheHost* host) OVERRIDE;
163 void HandleCacheFailure(const std::string& error_message);
165 void FetchManifest(bool is_first_fetch);
166 void HandleManifestFetchCompleted(URLFetcher* fetcher);
167 void ContinueHandleManifestFetchCompleted(bool changed);
169 void HandleUrlFetchCompleted(URLFetcher* fetcher);
170 void HandleMasterEntryFetchCompleted(URLFetcher* fetcher);
172 void HandleManifestRefetchCompleted(URLFetcher* fetcher);
173 void OnManifestInfoWriteComplete(int result);
174 void OnManifestDataWriteComplete(int result);
176 void StoreGroupAndCache();
178 void NotifySingleHost(AppCacheHost* host, EventID event_id);
179 void NotifyAllAssociatedHosts(EventID event_id);
180 void NotifyAllProgress(const GURL& url);
181 void NotifyAllFinalProgress();
182 void NotifyAllError(const std::string& error_message);
183 void AddAllAssociatedHostsToNotifier(HostNotifier* notifier);
185 // Checks if manifest is byte for byte identical with the manifest
186 // in the newest application cache.
187 void CheckIfManifestChanged();
188 void OnManifestDataReadComplete(int result);
190 // Creates the list of files that may need to be fetched and initiates
191 // fetches. Section 6.9.4 steps 12-17
192 void BuildUrlFileList(const Manifest& manifest);
193 void AddUrlToFileList(const GURL& url, int type);
194 void FetchUrls();
195 void CancelAllUrlFetches();
196 bool ShouldSkipUrlFetch(const AppCacheEntry& entry);
198 // If entry already exists in the cache currently being updated, merge
199 // the entry type information with the existing entry.
200 // Returns true if entry exists in cache currently being updated.
201 bool AlreadyFetchedEntry(const GURL& url, int entry_type);
203 // TODO(jennb): Delete when update no longer fetches master entries directly.
204 // Creates the list of master entries that need to be fetched and initiates
205 // fetches.
206 void AddMasterEntryToFetchList(AppCacheHost* host, const GURL& url,
207 bool is_new);
208 void FetchMasterEntries();
209 void CancelAllMasterEntryFetches(const std::string& error_message);
211 // Asynchronously loads the entry from the newest complete cache if the
212 // HTTP caching semantics allow.
213 // Returns false if immediately obvious that data cannot be loaded from
214 // newest complete cache.
215 bool MaybeLoadFromNewestCache(const GURL& url, AppCacheEntry& entry);
216 void LoadFromNewestCacheFailed(const GURL& url,
217 AppCacheResponseInfo* newest_response_info);
219 // Does nothing if update process is still waiting for pending master
220 // entries or URL fetches to complete downloading. Otherwise, completes
221 // the update process.
222 void MaybeCompleteUpdate();
224 // Schedules a rerun of the entire update with the same parameters as
225 // this update job after a short delay.
226 void ScheduleUpdateRetry(int delay_ms);
228 void Cancel();
229 void ClearPendingMasterEntries();
230 void DiscardInprogressCache();
231 void DiscardDuplicateResponses();
233 // Deletes this object after letting the stack unwind.
234 void DeleteSoon();
236 bool IsTerminating() { return internal_state_ >= REFETCH_MANIFEST ||
237 stored_state_ != UNSTORED; }
239 AppCacheService* service_;
240 const GURL manifest_url_; // here for easier access
242 scoped_refptr<AppCache> inprogress_cache_;
244 AppCacheGroup* group_;
246 UpdateType update_type_;
247 InternalUpdateState internal_state_;
249 PendingMasters pending_master_entries_;
250 size_t master_entries_completed_;
252 // TODO(jennb): Delete when update no longer fetches master entries directly.
253 // Helper containers to track which pending master entries have yet to be
254 // fetched and which are currently being fetched. Master entries that
255 // are listed in the manifest may be fetched as a regular URL instead of
256 // as a separate master entry fetch to optimize against duplicate fetches.
257 std::set<GURL> master_entries_to_fetch_;
258 PendingUrlFetches master_entry_fetches_;
260 // URLs of files to fetch along with their flags.
261 AppCache::EntryMap url_file_list_;
262 size_t url_fetches_completed_;
264 // Helper container to track which urls have not been fetched yet. URLs are
265 // removed when the fetch is initiated. Flag indicates whether an attempt
266 // to load the URL from storage has already been tried and failed.
267 std::deque<UrlToFetch> urls_to_fetch_;
269 // Helper container to track which urls are being loaded from response
270 // storage.
271 LoadingResponses loading_responses_;
273 // Keep track of pending URL requests so we can cancel them if necessary.
274 URLFetcher* manifest_fetcher_;
275 PendingUrlFetches pending_url_fetches_;
277 // Temporary storage of manifest response data for parsing and comparison.
278 std::string manifest_data_;
279 scoped_ptr<net::HttpResponseInfo> manifest_response_info_;
280 scoped_ptr<AppCacheResponseWriter> manifest_response_writer_;
281 scoped_refptr<net::IOBuffer> read_manifest_buffer_;
282 std::string loaded_manifest_data_;
283 scoped_ptr<AppCacheResponseReader> manifest_response_reader_;
285 // New master entries added to the cache by this job, used to cleanup
286 // in error conditions.
287 std::vector<GURL> added_master_entries_;
289 // Response ids stored by this update job, used to cleanup in
290 // error conditions.
291 std::vector<int64> stored_response_ids_;
293 // In some cases we fetch the same resource multiple times, and then
294 // have to delete the duplicates upon successful update. These ids
295 // are also in the stored_response_ids_ collection so we only schedule
296 // these for deletion on success.
297 // TODO(michaeln): Rework when we no longer fetches master entries directly.
298 std::vector<int64> duplicate_response_ids_;
300 // Whether we've stored the resulting group/cache yet.
301 StoredState stored_state_;
303 FRIEND_TEST_ALL_PREFIXES(AppCacheGroupTest, QueueUpdate);
305 DISALLOW_COPY_AND_ASSIGN(AppCacheUpdateJob);
308 } // namespace appcache
310 #endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_