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 CONTENT_BROWSER_APPCACHE_APPCACHE_H_
6 #define CONTENT_BROWSER_APPCACHE_APPCACHE_H_
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/time/time.h"
15 #include "content/browser/appcache/appcache_database.h"
16 #include "content/browser/appcache/appcache_entry.h"
17 #include "content/browser/appcache/appcache_manifest_parser.h"
18 #include "content/common/content_export.h"
26 FORWARD_DECLARE_TEST(AppCacheTest
, InitializeWithManifest
);
27 FORWARD_DECLARE_TEST(AppCacheTest
, ToFromDatabaseRecords
);
28 class AppCacheExecutableHandler
;
31 class AppCacheStorage
;
33 class AppCacheStorageImplTest
;
34 class AppCacheUpdateJobTest
;
36 // Set of cached resources for an application. A cache exists as long as a
37 // host is associated with it, the cache is in an appcache group or the
38 // cache is being created during an appcache upate.
39 class CONTENT_EXPORT AppCache
40 : public base::RefCounted
<AppCache
> {
42 typedef std::map
<GURL
, AppCacheEntry
> EntryMap
;
43 typedef std::set
<AppCacheHost
*> AppCacheHosts
;
45 AppCache(AppCacheStorage
* storage
, int64 cache_id
);
47 int64
cache_id() const { return cache_id_
; }
49 AppCacheGroup
* owning_group() const { return owning_group_
.get(); }
51 bool is_complete() const { return is_complete_
; }
52 void set_complete(bool value
) { is_complete_
= value
; }
54 // Adds a new entry. Entry must not already be in cache.
55 void AddEntry(const GURL
& url
, const AppCacheEntry
& entry
);
57 // Adds a new entry or modifies an existing entry by merging the types
58 // of the new entry with the existing entry. Returns true if a new entry
59 // is added, false if the flags are merged into an existing entry.
60 bool AddOrModifyEntry(const GURL
& url
, const AppCacheEntry
& entry
);
62 // Removes an entry from the EntryMap, the URL must be in the set.
63 void RemoveEntry(const GURL
& url
);
65 // Do not store or delete the returned ptr, they're owned by 'this'.
66 AppCacheEntry
* GetEntry(const GURL
& url
);
67 const AppCacheEntry
* GetEntryWithResponseId(int64 response_id
) {
68 return GetEntryAndUrlWithResponseId(response_id
, NULL
);
70 const AppCacheEntry
* GetEntryAndUrlWithResponseId(
71 int64 response_id
, GURL
* optional_url
);
72 const EntryMap
& entries() const { return entries_
; }
74 // The AppCache owns the collection of executable handlers that have
75 // been started for this instance. The getter looks up an existing
76 // handler returning null if not found, the GetOrCreate method will
77 // cons one up if not found.
78 // Do not store the returned ptrs, they're owned by 'this'.
79 AppCacheExecutableHandler
* GetExecutableHandler(int64 response_id
);
80 AppCacheExecutableHandler
* GetOrCreateExecutableHandler(
81 int64 response_id
, net::IOBuffer
* handler_source
);
83 // Returns the URL of the resource used as entry for 'namespace_url'.
84 GURL
GetFallbackEntryUrl(const GURL
& namespace_url
) const {
85 return GetNamespaceEntryUrl(fallback_namespaces_
, namespace_url
);
87 GURL
GetInterceptEntryUrl(const GURL
& namespace_url
) const {
88 return GetNamespaceEntryUrl(intercept_namespaces_
, namespace_url
);
91 AppCacheHosts
& associated_hosts() { return associated_hosts_
; }
93 bool IsNewerThan(AppCache
* cache
) const {
94 // TODO(michaeln): revisit, the system clock can be set
95 // back in time which would confuse this logic.
96 if (update_time_
> cache
->update_time_
)
99 // Tie breaker. Newer caches have a larger cache ID.
100 if (update_time_
== cache
->update_time_
)
101 return cache_id_
> cache
->cache_id_
;
106 base::Time
update_time() const { return update_time_
; }
108 int64
cache_size() const { return cache_size_
; }
110 void set_update_time(base::Time ticks
) { update_time_
= ticks
; }
112 // Initializes the cache with information in the manifest.
113 // Do not use the manifest after this call.
114 void InitializeWithManifest(AppCacheManifest
* manifest
);
116 // Initializes the cache with the information in the database records.
117 void InitializeWithDatabaseRecords(
118 const AppCacheDatabase::CacheRecord
& cache_record
,
119 const std::vector
<AppCacheDatabase::EntryRecord
>& entries
,
120 const std::vector
<AppCacheDatabase::NamespaceRecord
>& intercepts
,
121 const std::vector
<AppCacheDatabase::NamespaceRecord
>& fallbacks
,
122 const std::vector
<AppCacheDatabase::OnlineWhiteListRecord
>& whitelists
);
124 // Returns the database records to be stored in the AppCacheDatabase
125 // to represent this cache.
126 void ToDatabaseRecords(
127 const AppCacheGroup
* group
,
128 AppCacheDatabase::CacheRecord
* cache_record
,
129 std::vector
<AppCacheDatabase::EntryRecord
>* entries
,
130 std::vector
<AppCacheDatabase::NamespaceRecord
>* intercepts
,
131 std::vector
<AppCacheDatabase::NamespaceRecord
>* fallbacks
,
132 std::vector
<AppCacheDatabase::OnlineWhiteListRecord
>* whitelists
);
134 bool FindResponseForRequest(const GURL
& url
,
135 AppCacheEntry
* found_entry
, GURL
* found_intercept_namespace
,
136 AppCacheEntry
* found_fallback_entry
, GURL
* found_fallback_namespace
,
137 bool* found_network_namespace
);
139 // Populates the 'infos' vector with an element per entry in the appcache.
140 void ToResourceInfoVector(AppCacheResourceInfoVector
* infos
) const;
142 static const AppCacheNamespace
* FindNamespace(
143 const AppCacheNamespaceVector
& namespaces
,
147 friend class AppCacheGroup
;
148 friend class AppCacheHost
;
149 friend class content::AppCacheTest
;
150 friend class content::AppCacheStorageImplTest
;
151 friend class content::AppCacheUpdateJobTest
;
152 friend class base::RefCounted
<AppCache
>;
156 // Use AppCacheGroup::Add/RemoveCache() to manipulate owning group.
157 void set_owning_group(AppCacheGroup
* group
) { owning_group_
= group
; }
159 // FindResponseForRequest helpers
160 const AppCacheNamespace
* FindInterceptNamespace(const GURL
& url
) {
161 return FindNamespace(intercept_namespaces_
, url
);
163 const AppCacheNamespace
* FindFallbackNamespace(const GURL
& url
) {
164 return FindNamespace(fallback_namespaces_
, url
);
166 bool IsInNetworkNamespace(const GURL
& url
) {
167 return FindNamespace(online_whitelist_namespaces_
, url
) != NULL
;
170 GURL
GetNamespaceEntryUrl(const AppCacheNamespaceVector
& namespaces
,
171 const GURL
& namespace_url
) const;
173 // Use AppCacheHost::Associate*Cache() to manipulate host association.
174 void AssociateHost(AppCacheHost
* host
) {
175 associated_hosts_
.insert(host
);
177 void UnassociateHost(AppCacheHost
* host
);
179 const int64 cache_id_
;
180 scoped_refptr
<AppCacheGroup
> owning_group_
;
181 AppCacheHosts associated_hosts_
;
183 EntryMap entries_
; // contains entries of all types
185 AppCacheNamespaceVector intercept_namespaces_
;
186 AppCacheNamespaceVector fallback_namespaces_
;
187 AppCacheNamespaceVector online_whitelist_namespaces_
;
188 bool online_whitelist_all_
;
192 // when this cache was last updated
193 base::Time update_time_
;
197 typedef std::map
<int64
, AppCacheExecutableHandler
*> HandlerMap
;
198 HandlerMap executable_handlers_
;
200 // to notify storage when cache is deleted
201 AppCacheStorage
* storage_
;
203 FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest
, InitializeWithManifest
);
204 FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest
, ToFromDatabaseRecords
);
205 DISALLOW_COPY_AND_ASSIGN(AppCache
);
208 } // namespace content
210 #endif // CONTENT_BROWSER_APPCACHE_APPCACHE_H_