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_STORAGE_H_ 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define WEBKIT_BROWSER_APPCACHE_APPCACHE_STORAGE_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/appcache/appcache_working_set.h" 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/browser/webkit_storage_browser_export.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GURL; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace appcache { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCache; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheEntry; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheGroup; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheResponseReader; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheResponseWriter; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheService; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AppCacheInfoCollection; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct HttpResponseInfoIOBuffer; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheStorage { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<GURL, int64> UsageMap; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) class WEBKIT_STORAGE_BROWSER_EXPORT Delegate { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If retrieval fails, 'collection' will be NULL. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnAllInfo(AppCacheInfoCollection* collection) {} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a load fails the 'cache' will be NULL. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnCacheLoaded(AppCache* cache, int64 cache_id) {} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a load fails the 'group' will be NULL. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnGroupLoaded( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheGroup* group, const GURL& manifest_url) {} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If successfully stored 'success' will be true. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnGroupAndNewestCacheStored( 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheGroup* group, AppCache* newest_cache, bool success, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool would_exceed_quota) {} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the operation fails, success will be false. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnGroupMadeObsolete(AppCacheGroup* group, bool success) {} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a load fails the 'response_info' will be NULL. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnResponseInfoLoaded( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheResponseInfo* response_info, int64 response_id) {} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If no response is found, entry.response_id() and 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fallback_entry.response_id() will be kNoResponseId. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the response is the entry for an intercept or fallback 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // namespace, the url of the namespece entry is returned. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a response is found, the cache id and manifest url of the 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // containing cache and group are also returned. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnMainResponseFound( 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, const AppCacheEntry& entry, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& namespace_entry_url, const AppCacheEntry& fallback_entry, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 cache_id, int64 group_id, const GURL& mainfest_url) {} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Delegate() {} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit AppCacheStorage(AppCacheService* service); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AppCacheStorage(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules a task to retrieve basic info about all groups and caches 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stored in the system. Upon completion the delegate will be called 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with the results. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetAllInfo(Delegate* delegate) = 0; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules a cache to be loaded from storage. Upon load completion 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the delegate will be called back. If the cache already resides in 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // memory, the delegate will be called back immediately without returning 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the message loop. If the load fails, the delegate will be called 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // back with a NULL cache pointer. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void LoadCache(int64 id, Delegate* delegate) = 0; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules a group and its newest cache, if any, to be loaded from storage. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Upon load completion the delegate will be called back. If the group 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and newest cache already reside in memory, the delegate will be called 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // back immediately without returning to the message loop. If the load fails, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the delegate will be called back with a NULL group pointer. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void LoadOrCreateGroup( 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, Delegate* delegate) = 0; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules response info to be loaded from storage. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Upon load completion the delegate will be called back. If the data 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already resides in memory, the delegate will be called back 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // immediately without returning to the message loop. If the load fails, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the delegate will be called back with a NULL pointer. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void LoadResponseInfo( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, int64 group_id, int64 response_id, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules a group and its newest complete cache to be initially stored or 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // incrementally updated with new changes. Upon completion the delegate 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be called back. A group without a newest cache cannot be stored. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's a programming error to call this method without a newest cache. A 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // side effect of storing a new newest cache is the removal of the group's 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // old caches and responses from persistent storage (although they may still 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // linger in the in-memory working set until no longer needed). The new 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cache will be added as the group's newest complete cache only if storage 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // succeeds. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void StoreGroupAndNewestCache( 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheGroup* group, AppCache* newest_cache, Delegate* delegate) = 0; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules a query to identify a response for a main request. Upon 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // completion the delegate will be called back. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void FindResponseForMainRequest( 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& preferred_manifest_url, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate) = 0; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs an immediate lookup of the in-memory cache to 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // identify a response for a sub resource request. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void FindResponseForSubRequest( 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCache* cache, const GURL& url, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* found_network_namespace) = 0; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Immediately updates in-memory storage, if the cache is in memory, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and schedules a task to update persistent storage. If the cache is 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already scheduled to be loaded, upon loading completion the entry 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be marked. There is no delegate completion callback. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void MarkEntryAsForeign(const GURL& entry_url, int64 cache_id) = 0; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules a task to update persistent storage and doom the group and all 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // related caches and responses for deletion. Upon completion the in-memory 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instance is marked as obsolete and the delegate callback is called. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void MakeGroupObsolete( 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheGroup* group, Delegate* delegate) = 0; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancels all pending callbacks for the delegate. The delegate callbacks 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will not be invoked after, however any scheduled operations will still 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // take place. The callbacks for subsequently scheduled operations are 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unaffected. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelDelegateCallbacks(Delegate* delegate) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReference* delegate_reference = GetDelegateReference(delegate); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate_reference) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_reference->CancelReference(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a reader to read a response from storage. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual AppCacheResponseReader* CreateResponseReader( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, int64 group_id, int64 response_id) = 0; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a writer to write a new response to storage. This call 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // establishes a new response id. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual AppCacheResponseWriter* CreateResponseWriter( 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, int64 group_id) = 0; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules the lazy deletion of responses and saves the ids 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // persistently such that the responses will be deleted upon restart 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if they aren't deleted prior to shutdown. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DoomResponses( 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, const std::vector<int64>& response_ids) = 0; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedules the lazy deletion of responses without persistently saving 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the response ids. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DeleteResponses( 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, const std::vector<int64>& response_ids) = 0; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void PurgeMemory() = 0; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generates unique storage ids for different object types. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 NewCacheId() { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ++last_cache_id_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 NewGroupId() { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ++last_group_id_; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The working set of object instances currently in memory. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheWorkingSet* working_set() { return &working_set_; } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A map of origins to usage. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UsageMap* usage_map() { return &usage_map_; } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simple ptr back to the service object that owns us. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheService* service() { return service_; } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class AppCacheQuotaClientTest; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class AppCacheResponseTest; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class AppCacheStorageTest; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper to call a collection of delegates. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #define FOR_EACH_DELEGATE(delegates, func_and_args) \ 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { \ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (DelegateReferenceVector::iterator it = delegates.begin(); \ 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != delegates.end(); ++it) { \ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->get()->delegate) \ 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it->get()->delegate->func_and_args; \ 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (0) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper used to manage multiple references to a 'delegate' and to 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allow all pending callbacks to that delegate to be easily cancelled. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct DelegateReference : public base::RefCounted<DelegateReference> { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheStorage* storage; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReference(Delegate* delegate, AppCacheStorage* storage); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelReference() { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage->delegate_references_.erase(delegate); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) storage = NULL; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate = NULL; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<DelegateReference>; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DelegateReference(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<Delegate*, DelegateReference*> DelegateReferenceMap; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<scoped_refptr<DelegateReference> > 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReferenceVector; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper used to manage an async LoadResponseInfo calls on behalf of 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // multiple callers. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ResponseInfoLoadTask { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseInfoLoadTask(const GURL& manifest_url, int64 group_id, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 response_id, AppCacheStorage* storage); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ResponseInfoLoadTask(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 response_id() const { return response_id_; } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url() const { return manifest_url_; } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 group_id() const { return group_id_; } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddDelegate(DelegateReference* delegate_reference) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegates_.push_back(delegate_reference); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartIfNeeded(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnReadComplete(int result); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheStorage* storage_; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL manifest_url_; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 group_id_; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 response_id_; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AppCacheResponseReader> reader_; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReferenceVector delegates_; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<int64, ResponseInfoLoadTask*> PendingResponseInfoLoads; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReference* GetDelegateReference(Delegate* delegate) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReferenceMap::iterator iter = 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_references_.find(delegate); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter != delegate_references_.end()) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->second; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReference* GetOrCreateDelegateReference(Delegate* delegate) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReference* reference = GetDelegateReference(delegate); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reference) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reference; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new DelegateReference(delegate, this); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResponseInfoLoadTask* GetOrCreateResponseInfoLoadTask( 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& manifest_url, int64 group_id, int64 response_id) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingResponseInfoLoads::iterator iter = 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_info_loads_.find(response_id); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter != pending_info_loads_.end()) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return iter->second; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new ResponseInfoLoadTask(manifest_url, group_id, response_id, this); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should only be called when creating a new response writer. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 NewResponseId() { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ++last_response_id_; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helpers to query and notify the QuotaManager. 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdateUsageMapAndNotify(const GURL& origin, int64 new_usage); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ClearUsageMapAndNotify(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyStorageAccessed(const GURL& origin); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The last storage id used for different object types. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 last_cache_id_; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 last_group_id_; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 last_response_id_; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UsageMap usage_map_; // maps origin to usage 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheWorkingSet working_set_; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheService* service_; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelegateReferenceMap delegate_references_; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingResponseInfoLoads pending_info_loads_; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The set of last ids must be retrieved from storage prior to being used. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int64 kUnitializedId; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AppCacheStorageTest, DelegateReferences); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AppCacheStorageTest, UsageMap); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AppCacheStorage); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace appcache 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_STORAGE_H_ 322