15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef CONTENT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CONTENT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/time/time.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_host.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_response.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_service_impl.h"
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_storage.h"
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/appcache_interfaces.h"
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/content_export.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace content {
30a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochFORWARD_DECLARE_TEST(AppCacheGroupTest, QueueUpdate);
31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass AppCacheGroupTest;
32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass AppCacheUpdateJobTest;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HostNotifier;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Application cache Update algorithm and state.
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass CONTENT_EXPORT AppCacheUpdateJob
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public AppCacheStorage::Delegate,
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      public AppCacheHost::Observer,
3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      public AppCacheServiceImpl::Observer {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Used for uma stats only for now, so new values are append only.
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  enum ResultType {
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    UPDATE_OK, DB_ERROR, DISKCACHE_ERROR, QUOTA_ERROR, REDIRECT_ERROR,
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MANIFEST_ERROR, NETWORK_ERROR, SERVER_ERROR, CANCELLED_ERROR,
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NUM_UPDATE_JOB_RESULT_TYPES
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AppCacheUpdateJob(AppCacheServiceImpl* service, AppCacheGroup* group);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AppCacheUpdateJob();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Triggers the update process or adds more info if this update is already
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in progress.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartUpdate(AppCacheHost* host, const GURL& new_master_resource);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  friend class content::AppCacheGroupTest;
57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  friend class content::AppCacheUpdateJobTest;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class URLFetcher;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Master entries have multiple hosts, for example, the same page is opened
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in different tabs.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<AppCacheHost*> PendingHosts;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<GURL, PendingHosts> PendingMasters;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<GURL, URLFetcher*> PendingUrlFetches;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<int64, GURL> LoadingResponses;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kRerunDelayMs = 1000;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): Rework the set of states vs update types vs stored states.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The NO_UPDATE state is really more of an update type. For all update types
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // storing the results is relevant.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum UpdateType {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNKNOWN_TYPE,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UPGRADE_ATTEMPT,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CACHE_ATTEMPT,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum InternalUpdateState {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FETCH_MANIFEST,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NO_UPDATE,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DOWNLOADING,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Every state after this comment indicates the update is terminating.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    REFETCH_MANIFEST,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CACHE_FAILURE,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CANCELLED,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    COMPLETED,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum StoredState {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UNSTORED,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STORING,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STORED,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct UrlToFetch {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UrlToFetch(const GURL& url, bool checked, AppCacheResponseInfo* info);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~UrlToFetch();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool storage_checked;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<AppCacheResponseInfo> existing_response_info;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class URLFetcher : public net::URLRequest::Delegate {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum FetchType {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MANIFEST_FETCH,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URL_FETCH,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MASTER_ENTRY_FETCH,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MANIFEST_REFETCH,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLFetcher(const GURL& url,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               FetchType fetch_type,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               AppCacheUpdateJob* job);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~URLFetcher();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Start();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FetchType fetch_type() const { return fetch_type_; }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest* request() const { return request_.get(); }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AppCacheEntry& existing_entry() const { return existing_entry_; }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& manifest_data() const { return manifest_data_; }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheResponseWriter* response_writer() const {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return response_writer_.get();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void set_existing_response_headers(net::HttpResponseHeaders* headers) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      existing_response_headers_ = headers;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void set_existing_entry(const AppCacheEntry& entry) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      existing_entry_ = entry;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResultType result() const { return result_; }
133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    int redirect_response_code() const { return redirect_response_code_; }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // URLRequest::Delegate overrides
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnReceivedRedirect(net::URLRequest* request,
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                    const net::RedirectInfo& redirect_info,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool* defer_redirect) OVERRIDE;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnReadCompleted(net::URLRequest* request,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 int bytes_read) OVERRIDE;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void AddConditionalHeaders(const net::HttpResponseHeaders* headers);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void OnWriteComplete(int result);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void ReadResponseData();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ConsumeResponseData(int bytes_read);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void OnResponseCompleted();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool MaybeRetryRequest();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheUpdateJob* job_;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FetchType fetch_type_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int retry_503_attempts_;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::IOBuffer> buffer_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<net::URLRequest> request_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppCacheEntry existing_entry_;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<net::HttpResponseHeaders> existing_response_headers_;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string manifest_data_;
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResultType result_;
161e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    int redirect_response_code_;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<AppCacheResponseWriter> response_writer_;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };  // class URLFetcher
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheResponseWriter* CreateResponseWriter();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Methods for AppCacheStorage::Delegate.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnResponseInfoLoaded(AppCacheResponseInfo* response_info,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int64 response_id) OVERRIDE;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnGroupAndNewestCacheStored(AppCacheGroup* group,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           AppCache* newest_cache,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool success,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bool would_exceed_quota) OVERRIDE;
174e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual void OnGroupMadeObsolete(AppCacheGroup* group,
175e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                   bool success,
176e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                   int response_code) OVERRIDE;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Methods for AppCacheHost::Observer.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnCacheSelectionComplete(AppCacheHost* host) OVERRIDE {}  // N/A
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnDestructionImminent(AppCacheHost* host) OVERRIDE;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // Methods for AppCacheServiceImpl::Observer.
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void OnServiceReinitialized(
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      AppCacheStorageReference* old_storage) OVERRIDE;
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void HandleCacheFailure(const AppCacheErrorDetails& details,
187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          ResultType result,
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          const GURL& failed_resource_url);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FetchManifest(bool is_first_fetch);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleManifestFetchCompleted(URLFetcher* fetcher);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ContinueHandleManifestFetchCompleted(bool changed);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleUrlFetchCompleted(URLFetcher* fetcher);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleMasterEntryFetchCompleted(URLFetcher* fetcher);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleManifestRefetchCompleted(URLFetcher* fetcher);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnManifestInfoWriteComplete(int result);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnManifestDataWriteComplete(int result);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StoreGroupAndCache();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void NotifySingleHost(AppCacheHost* host, AppCacheEventID event_id);
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void NotifyAllAssociatedHosts(AppCacheEventID event_id);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyAllProgress(const GURL& url);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NotifyAllFinalProgress();
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void NotifyAllError(const AppCacheErrorDetails& detals);
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void LogConsoleMessageToAll(const std::string& message);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddAllAssociatedHostsToNotifier(HostNotifier* notifier);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks if manifest is byte for byte identical with the manifest
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the newest application cache.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckIfManifestChanged();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnManifestDataReadComplete(int result);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates the list of files that may need to be fetched and initiates
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetches. Section 6.9.4 steps 12-17
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void BuildUrlFileList(const AppCacheManifest& manifest);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddUrlToFileList(const GURL& url, int type);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FetchUrls();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelAllUrlFetches();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ShouldSkipUrlFetch(const AppCacheEntry& entry);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If entry already exists in the cache currently being updated, merge
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the entry type information with the existing entry.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if entry exists in cache currently being updated.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AlreadyFetchedEntry(const GURL& url, int entry_type);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jennb): Delete when update no longer fetches master entries directly.
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates the list of master entries that need to be fetched and initiates
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetches.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddMasterEntryToFetchList(AppCacheHost* host, const GURL& url,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 bool is_new);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FetchMasterEntries();
235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void CancelAllMasterEntryFetches(const AppCacheErrorDetails& details);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Asynchronously loads the entry from the newest complete cache if the
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP caching semantics allow.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns false if immediately obvious that data cannot be loaded from
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // newest complete cache.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool MaybeLoadFromNewestCache(const GURL& url, AppCacheEntry& entry);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LoadFromNewestCacheFailed(const GURL& url,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 AppCacheResponseInfo* newest_response_info);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Does nothing if update process is still waiting for pending master
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entries or URL fetches to complete downloading. Otherwise, completes
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the update process.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MaybeCompleteUpdate();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schedules a rerun of the entire update with the same parameters as
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this update job after a short delay.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleUpdateRetry(int delay_ms);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Cancel();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearPendingMasterEntries();
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DiscardInprogressCache();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DiscardDuplicateResponses();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
259effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void LogHistogramStats(ResultType result, const GURL& failed_resource_url);
260effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void MadeProgress() { last_progress_time_ = base::Time::Now(); }
261effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deletes this object after letting the stack unwind.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DeleteSoon();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsTerminating() { return internal_state_ >= REFETCH_MANIFEST ||
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                stored_state_ != UNSTORED; }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  AppCacheServiceImpl* service_;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL manifest_url_;  // here for easier access
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Defined prior to refs to AppCaches and Groups because destruction
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // order matters, the disabled_storage_reference_ must outlive those
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // objects.
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<AppCacheStorageReference> disabled_storage_reference_;
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AppCache> inprogress_cache_;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheGroup* group_;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateType update_type_;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InternalUpdateState internal_state_;
282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  base::Time last_progress_time_;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingMasters pending_master_entries_;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t master_entries_completed_;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jennb): Delete when update no longer fetches master entries directly.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper containers to track which pending master entries have yet to be
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetched and which are currently being fetched. Master entries that
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are listed in the manifest may be fetched as a regular URL instead of
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as a separate master entry fetch to optimize against duplicate fetches.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<GURL> master_entries_to_fetch_;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingUrlFetches master_entry_fetches_;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLs of files to fetch along with their flags.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCache::EntryMap url_file_list_;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t url_fetches_completed_;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper container to track which urls have not been fetched yet. URLs are
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // removed when the fetch is initiated. Flag indicates whether an attempt
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to load the URL from storage has already been tried and failed.
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::deque<UrlToFetch> urls_to_fetch_;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper container to track which urls are being loaded from response
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // storage.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadingResponses loading_responses_;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep track of pending URL requests so we can cancel them if necessary.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLFetcher* manifest_fetcher_;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingUrlFetches pending_url_fetches_;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Temporary storage of manifest response data for parsing and comparison.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string manifest_data_;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::HttpResponseInfo> manifest_response_info_;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheResponseWriter> manifest_response_writer_;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBuffer> read_manifest_buffer_;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string loaded_manifest_data_;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AppCacheResponseReader> manifest_response_reader_;
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool manifest_has_valid_mime_type_;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // New master entries added to the cache by this job, used to cleanup
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in error conditions.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> added_master_entries_;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Response ids stored by this update job, used to cleanup in
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // error conditions.
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int64> stored_response_ids_;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In some cases we fetch the same resource multiple times, and then
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have to delete the duplicates upon successful update. These ids
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are also in the stored_response_ids_ collection so we only schedule
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // these for deletion on success.
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(michaeln): Rework when we no longer fetches master entries directly.
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int64> duplicate_response_ids_;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether we've stored the resulting group/cache yet.
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StoredState stored_state_;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AppCacheStorage* storage_;
3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
341a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  FRIEND_TEST_ALL_PREFIXES(content::AppCacheGroupTest, QueueUpdate);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AppCacheUpdateJob);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace content
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // CONTENT_BROWSER_APPCACHE_APPCACHE_UPDATE_JOB_H_
349