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)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_H_
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define WEBKIT_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"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_database.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_entry.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/manifest_parser.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/browser/webkit_storage_browser_export.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace net {
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class IOBuffer;
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace appcache {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class AppCacheExecutableHandler;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheGroup;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheHost;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AppCacheStorage;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Set of cached resources for an application. A cache exists as long as a
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// host is associated with it, the cache is in an appcache group or the
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache is being created during an appcache upate.
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class WEBKIT_STORAGE_BROWSER_EXPORT AppCache
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public base::RefCounted<AppCache> {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<GURL, AppCacheEntry> EntryMap;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<AppCacheHost*> AppCacheHosts;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppCache(AppCacheStorage* storage, int64 cache_id);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 cache_id() const { return cache_id_; }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  AppCacheGroup* owning_group() const { return owning_group_.get(); }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_complete() const { return is_complete_; }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_complete(bool value) { is_complete_ = value; }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds a new entry. Entry must not already be in cache.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddEntry(const GURL& url, const AppCacheEntry& entry);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds a new entry or modifies an existing entry by merging the types
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the new entry with the existing entry. Returns true if a new entry
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is added, false if the flags are merged into an existing entry.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AddOrModifyEntry(const GURL& url, const AppCacheEntry& entry);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes an entry from the EntryMap, the URL must be in the set.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RemoveEntry(const GURL& url);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Do not store or delete the returned ptr, they're owned by 'this'.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheEntry* GetEntry(const GURL& url);
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const AppCacheEntry* GetEntryWithResponseId(int64 response_id) {
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return GetEntryAndUrlWithResponseId(response_id, NULL);
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const AppCacheEntry* GetEntryAndUrlWithResponseId(
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      int64 response_id, GURL* optional_url);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const EntryMap& entries() const { return entries_; }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The AppCache owns the collection of executable handlers that have
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // been started for this instance. The getter looks up an existing
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // handler returning null if not found, the GetOrCreate method will
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // cons one up if not found.
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Do not store the returned ptrs, they're owned by 'this'.
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppCacheExecutableHandler* GetExecutableHandler(int64 response_id);
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AppCacheExecutableHandler* GetOrCreateExecutableHandler(
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      int64 response_id, net::IOBuffer* handler_source);
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the URL of the resource used as entry for 'namespace_url'.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL GetFallbackEntryUrl(const GURL& namespace_url) const {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetNamespaceEntryUrl(fallback_namespaces_, namespace_url);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL GetInterceptEntryUrl(const GURL& namespace_url) const {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetNamespaceEntryUrl(intercept_namespaces_, namespace_url);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHosts& associated_hosts() { return associated_hosts_; }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsNewerThan(AppCache* cache) const {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(michaeln): revisit, the system clock can be set
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // back in time which would confuse this logic.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (update_time_ > cache->update_time_)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tie breaker. Newer caches have a larger cache ID.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (update_time_ == cache->update_time_)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return cache_id_ > cache->cache_id_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time update_time() const { return update_time_; }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 cache_size() const { return cache_size_; }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_update_time(base::Time ticks) { update_time_ = ticks; }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the cache with information in the manifest.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not use the manifest after this call.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeWithManifest(Manifest* manifest);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the cache with the information in the database records.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeWithDatabaseRecords(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const AppCacheDatabase::CacheRecord& cache_record,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<AppCacheDatabase::EntryRecord>& entries,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<AppCacheDatabase::NamespaceRecord>& intercepts,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<AppCacheDatabase::NamespaceRecord>& fallbacks,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<AppCacheDatabase::OnlineWhiteListRecord>& whitelists);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the database records to be stored in the AppCacheDatabase
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to represent this cache.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ToDatabaseRecords(
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const AppCacheGroup* group,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AppCacheDatabase::CacheRecord* cache_record,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<AppCacheDatabase::EntryRecord>* entries,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<AppCacheDatabase::NamespaceRecord>* intercepts,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<AppCacheDatabase::NamespaceRecord>* fallbacks,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::vector<AppCacheDatabase::OnlineWhiteListRecord>* whitelists);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool FindResponseForRequest(const GURL& url,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AppCacheEntry* found_entry, GURL* found_intercept_namespace,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AppCacheEntry* found_fallback_entry, GURL* found_fallback_namespace,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool* found_network_namespace);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Populates the 'infos' vector with an element per entry in the appcache.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ToResourceInfoVector(AppCacheResourceInfoVector* infos) const;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const Namespace* FindNamespace(
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const NamespaceVector& namespaces,
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const GURL& url);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AppCacheGroup;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AppCacheHost;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AppCacheStorageImplTest;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AppCacheUpdateJobTest;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCounted<AppCache>;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~AppCache();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use AppCacheGroup::Add/RemoveCache() to manipulate owning group.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_owning_group(AppCacheGroup* group) { owning_group_ = group; }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FindResponseForRequest helpers
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Namespace* FindInterceptNamespace(const GURL& url) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FindNamespace(intercept_namespaces_, url);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Namespace* FindFallbackNamespace(const GURL& url) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return FindNamespace(fallback_namespaces_, url);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool IsInNetworkNamespace(const GURL& url) {
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return FindNamespace(online_whitelist_namespaces_, url) != NULL;
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL GetNamespaceEntryUrl(const NamespaceVector& namespaces,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const GURL& namespace_url) const;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use AppCacheHost::Associate*Cache() to manipulate host association.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AssociateHost(AppCacheHost* host) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    associated_hosts_.insert(host);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UnassociateHost(AppCacheHost* host);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 cache_id_;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<AppCacheGroup> owning_group_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheHosts associated_hosts_;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EntryMap entries_;    // contains entries of all types
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NamespaceVector intercept_namespaces_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NamespaceVector fallback_namespaces_;
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NamespaceVector online_whitelist_namespaces_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool online_whitelist_all_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_complete_;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when this cache was last updated
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Time update_time_;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 cache_size_;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef std::map<int64, AppCacheExecutableHandler*> HandlerMap;
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HandlerMap executable_handlers_;
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to notify storage when cache is deleted
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppCacheStorage* storage_;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(AppCacheTest, InitializeWithManifest);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(AppCacheTest, ToFromDatabaseRecords);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AppCache);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace appcache
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif  // WEBKIT_BROWSER_APPCACHE_APPCACHE_H_
206