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_H_
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CONTENT_BROWSER_APPCACHE_APPCACHE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_database.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_entry.h"
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/browser/appcache/appcache_manifest_parser.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/content_export.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace net {
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class IOBuffer;
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace content {
26a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochFORWARD_DECLARE_TEST(AppCacheTest, InitializeWithManifest);
27a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochFORWARD_DECLARE_TEST(AppCacheTest, ToFromDatabaseRecords);
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class AppCacheExecutableHandler;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheGroup;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheHost;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AppCacheStorage;
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass AppCacheTest;
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass AppCacheStorageImplTest;
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass AppCacheUpdateJobTest;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Set of cached resources for an application. A cache exists as long as a
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// host is associated with it, the cache is in an appcache group or the
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache is being created during an appcache upate.
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass CONTENT_EXPORT AppCache
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public base::RefCounted<AppCache> {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<GURL, AppCacheEntry> EntryMap;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<AppCacheHost*> AppCacheHosts;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppCache(AppCacheStorage* storage, int64 cache_id);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 cache_id() const { return cache_id_; }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AppCacheGroup* owning_group() const { return owning_group_.get(); }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_complete() const { return is_complete_; }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_complete(bool value) { is_complete_ = value; }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds a new entry. Entry must not already be in cache.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddEntry(const GURL& url, const AppCacheEntry& entry);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds a new entry or modifies an existing entry by merging the types
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the new entry with the existing entry. Returns true if a new entry
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is added, false if the flags are merged into an existing entry.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AddOrModifyEntry(const GURL& url, const AppCacheEntry& entry);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes an entry from the EntryMap, the URL must be in the set.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveEntry(const GURL& url);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Do not store or delete the returned ptr, they're owned by 'this'.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheEntry* GetEntry(const GURL& url);
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const AppCacheEntry* GetEntryWithResponseId(int64 response_id) {
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return GetEntryAndUrlWithResponseId(response_id, NULL);
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const AppCacheEntry* GetEntryAndUrlWithResponseId(
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      int64 response_id, GURL* optional_url);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EntryMap& entries() const { return entries_; }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The AppCache owns the collection of executable handlers that have
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // been started for this instance. The getter looks up an existing
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // handler returning null if not found, the GetOrCreate method will
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // cons one up if not found.
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Do not store the returned ptrs, they're owned by 'this'.
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppCacheExecutableHandler* GetExecutableHandler(int64 response_id);
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppCacheExecutableHandler* GetOrCreateExecutableHandler(
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      int64 response_id, net::IOBuffer* handler_source);
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the URL of the resource used as entry for 'namespace_url'.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL GetFallbackEntryUrl(const GURL& namespace_url) const {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetNamespaceEntryUrl(fallback_namespaces_, namespace_url);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL GetInterceptEntryUrl(const GURL& namespace_url) const {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetNamespaceEntryUrl(intercept_namespaces_, namespace_url);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHosts& associated_hosts() { return associated_hosts_; }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsNewerThan(AppCache* cache) const {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(michaeln): revisit, the system clock can be set
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // back in time which would confuse this logic.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (update_time_ > cache->update_time_)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tie breaker. Newer caches have a larger cache ID.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (update_time_ == cache->update_time_)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return cache_id_ > cache->cache_id_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time update_time() const { return update_time_; }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 cache_size() const { return cache_size_; }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_update_time(base::Time ticks) { update_time_ = ticks; }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the cache with information in the manifest.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not use the manifest after this call.
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void InitializeWithManifest(AppCacheManifest* manifest);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the cache with the information in the database records.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeWithDatabaseRecords(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const AppCacheDatabase::CacheRecord& cache_record,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<AppCacheDatabase::EntryRecord>& entries,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<AppCacheDatabase::NamespaceRecord>& intercepts,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<AppCacheDatabase::NamespaceRecord>& fallbacks,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<AppCacheDatabase::OnlineWhiteListRecord>& whitelists);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the database records to be stored in the AppCacheDatabase
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to represent this cache.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ToDatabaseRecords(
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const AppCacheGroup* group,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AppCacheDatabase::CacheRecord* cache_record,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<AppCacheDatabase::EntryRecord>* entries,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<AppCacheDatabase::NamespaceRecord>* intercepts,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<AppCacheDatabase::NamespaceRecord>* fallbacks,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<AppCacheDatabase::OnlineWhiteListRecord>* whitelists);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool FindResponseForRequest(const GURL& url,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AppCacheEntry* found_entry, GURL* found_intercept_namespace,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AppCacheEntry* found_fallback_entry, GURL* found_fallback_namespace,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool* found_network_namespace);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Populates the 'infos' vector with an element per entry in the appcache.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ToResourceInfoVector(AppCacheResourceInfoVector* infos) const;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static const AppCacheNamespace* FindNamespace(
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const AppCacheNamespaceVector& namespaces,
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const GURL& url);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AppCacheGroup;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AppCacheHost;
149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  friend class content::AppCacheTest;
150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  friend class content::AppCacheStorageImplTest;
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  friend class content::AppCacheUpdateJobTest;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCounted<AppCache>;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~AppCache();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use AppCacheGroup::Add/RemoveCache() to manipulate owning group.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_owning_group(AppCacheGroup* group) { owning_group_ = group; }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FindResponseForRequest helpers
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AppCacheNamespace* FindInterceptNamespace(const GURL& url) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FindNamespace(intercept_namespaces_, url);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AppCacheNamespace* FindFallbackNamespace(const GURL& url) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FindNamespace(fallback_namespaces_, url);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool IsInNetworkNamespace(const GURL& url) {
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return FindNamespace(online_whitelist_namespaces_, url) != NULL;
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GURL GetNamespaceEntryUrl(const AppCacheNamespaceVector& namespaces,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const GURL& namespace_url) const;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use AppCacheHost::Associate*Cache() to manipulate host association.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AssociateHost(AppCacheHost* host) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    associated_hosts_.insert(host);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UnassociateHost(AppCacheHost* host);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 cache_id_;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AppCacheGroup> owning_group_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHosts associated_hosts_;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EntryMap entries_;    // contains entries of all types
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppCacheNamespaceVector intercept_namespaces_;
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppCacheNamespaceVector fallback_namespaces_;
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AppCacheNamespaceVector online_whitelist_namespaces_;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool online_whitelist_all_;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_complete_;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when this cache was last updated
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time update_time_;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 cache_size_;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef std::map<int64, AppCacheExecutableHandler*> HandlerMap;
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HandlerMap executable_handlers_;
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to notify storage when cache is deleted
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppCacheStorage* storage_;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
203a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest, InitializeWithManifest);
204a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest, ToFromDatabaseRecords);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AppCache);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace content
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // CONTENT_BROWSER_APPCACHE_APPCACHE_H_
211