Home | History | Annotate | Download | only in appcache
      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.
      4 
      5 #ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_H_
      6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_H_
      7 
      8 #include <map>
      9 #include <set>
     10 
     11 #include "base/gtest_prod_util.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/observer_list.h"
     15 #include "net/base/completion_callback.h"
     16 #include "net/base/net_errors.h"
     17 #include "webkit/browser/appcache/appcache_storage.h"
     18 #include "webkit/browser/webkit_storage_browser_export.h"
     19 #include "webkit/common/appcache/appcache_interfaces.h"
     20 
     21 namespace net {
     22 class URLRequestContext;
     23 }  // namespace net
     24 
     25 namespace base {
     26 class FilePath;
     27 class MessageLoopProxy;
     28 }
     29 
     30 namespace quota {
     31 class QuotaManagerProxy;
     32 class SpecialStoragePolicy;
     33 }
     34 
     35 namespace appcache {
     36 
     37 class AppCacheBackendImpl;
     38 class AppCacheExecutableHandlerFactory;
     39 class AppCacheQuotaClient;
     40 class AppCachePolicy;
     41 
     42 // Refcounted container to avoid copying the collection in callbacks.
     43 struct WEBKIT_STORAGE_BROWSER_EXPORT AppCacheInfoCollection
     44     : public base::RefCountedThreadSafe<AppCacheInfoCollection> {
     45   AppCacheInfoCollection();
     46 
     47   std::map<GURL, AppCacheInfoVector> infos_by_origin;
     48 
     49  private:
     50   friend class base::RefCountedThreadSafe<AppCacheInfoCollection>;
     51   virtual ~AppCacheInfoCollection();
     52 };
     53 
     54 // Refcounted container to manage the lifetime of the old storage instance
     55 // during Reinitialization.
     56 class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheStorageReference :
     57     public base::RefCounted<AppCacheStorageReference> {
     58  public:
     59   AppCacheStorage* storage() const { return storage_.get(); }
     60  private:
     61   friend class AppCacheService;
     62   friend class base::RefCounted<AppCacheStorageReference>;
     63   AppCacheStorageReference(scoped_ptr<AppCacheStorage> storage);
     64   ~AppCacheStorageReference();
     65 
     66   scoped_ptr<AppCacheStorage> storage_;
     67 };
     68 
     69 // Class that manages the application cache service. Sends notifications
     70 // to many frontends.  One instance per user-profile. Each instance has
     71 // exclusive access to its cache_directory on disk.
     72 class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheService {
     73  public:
     74 
     75   class WEBKIT_STORAGE_BROWSER_EXPORT Observer {
     76    public:
     77     // An observer method to inform consumers of reinitialzation. Managing
     78     // the lifetime of the old storage instance is a delicate process.
     79     // Consumers can keep the old disabled instance alive by hanging on to the
     80     // ref provided.
     81     virtual void OnServiceReinitialized(
     82         AppCacheStorageReference* old_storage_ref) = 0;
     83     virtual ~Observer() {}
     84   };
     85 
     86   // If not using quota management, the proxy may be NULL.
     87   explicit AppCacheService(quota::QuotaManagerProxy* quota_manager_proxy);
     88   virtual ~AppCacheService();
     89 
     90   void Initialize(const base::FilePath& cache_directory,
     91                   base::MessageLoopProxy* db_thread,
     92                   base::MessageLoopProxy* cache_thread);
     93 
     94   void AddObserver(Observer* observer) {
     95     observers_.AddObserver(observer);
     96   }
     97 
     98   void RemoveObserver(Observer* observer) {
     99     observers_.RemoveObserver(observer);
    100   }
    101 
    102   // For use in a very specific failure mode to reboot the appcache system
    103   // without relaunching the browser.
    104   void Reinitialize();
    105 
    106   // Purges any memory not needed.
    107   void PurgeMemory() {
    108     if (storage_)
    109       storage_->PurgeMemory();
    110   }
    111 
    112   // Determines if a request for 'url' can be satisfied while offline.
    113   // This method always completes asynchronously.
    114   void CanHandleMainResourceOffline(const GURL& url,
    115                                     const GURL& first_party,
    116                                     const net::CompletionCallback& callback);
    117 
    118   // Populates 'collection' with info about all of the appcaches stored
    119   // within the service, 'callback' is invoked upon completion. The service
    120   // acquires a reference to the 'collection' until until completion.
    121   // This method always completes asynchronously.
    122   void GetAllAppCacheInfo(AppCacheInfoCollection* collection,
    123                           const net::CompletionCallback& callback);
    124 
    125   // Deletes the group identified by 'manifest_url', 'callback' is
    126   // invoked upon completion. Upon completion, the cache group and
    127   // any resources within the group are no longer loadable and all
    128   // subresource loads for pages associated with a deleted group
    129   // will fail. This method always completes asynchronously.
    130   void DeleteAppCacheGroup(const GURL& manifest_url,
    131                            const net::CompletionCallback& callback);
    132 
    133   // Deletes all appcaches for the origin, 'callback' is invoked upon
    134   // completion. This method always completes asynchronously.
    135   // (virtual for unit testing)
    136   virtual void DeleteAppCachesForOrigin(
    137       const GURL& origin, const net::CompletionCallback& callback);
    138 
    139   // Checks the integrity of 'response_id' by reading the headers and data.
    140   // If it cannot be read, the cache group for 'manifest_url' is deleted.
    141   void CheckAppCacheResponse(const GURL& manifest_url, int64 cache_id,
    142                              int64 response_id);
    143 
    144   // Context for use during cache updates, should only be accessed
    145   // on the IO thread. We do NOT add a reference to the request context,
    146   // it is the callers responsibility to ensure that the pointer
    147   // remains valid while set.
    148   net::URLRequestContext* request_context() const { return request_context_; }
    149   void set_request_context(net::URLRequestContext* context) {
    150     request_context_ = context;
    151   }
    152 
    153   // The appcache policy, may be null, in which case access is always allowed.
    154   // The service does NOT assume ownership of the policy, it is the callers
    155   // responsibility to ensure that the pointer remains valid while set.
    156   AppCachePolicy* appcache_policy() const { return appcache_policy_; }
    157   void set_appcache_policy(AppCachePolicy* policy) {
    158     appcache_policy_ = policy;
    159   }
    160 
    161   // The factory may be null, in which case invocations of exe handlers
    162   // will result in an error response.
    163   // The service does NOT assume ownership of the factory, it is the callers
    164   // responsibility to ensure that the pointer remains valid while set.
    165   AppCacheExecutableHandlerFactory* handler_factory() const {
    166     return handler_factory_;
    167   }
    168   void set_handler_factory(
    169       AppCacheExecutableHandlerFactory* factory) {
    170     handler_factory_ = factory;
    171   }
    172 
    173   quota::SpecialStoragePolicy* special_storage_policy() const {
    174     return special_storage_policy_.get();
    175   }
    176   void set_special_storage_policy(quota::SpecialStoragePolicy* policy);
    177 
    178   quota::QuotaManagerProxy* quota_manager_proxy() const {
    179     return quota_manager_proxy_.get();
    180   }
    181 
    182   AppCacheQuotaClient* quota_client() const {
    183     return quota_client_;
    184   }
    185 
    186   // Each child process in chrome uses a distinct backend instance.
    187   // See chrome/browser/AppCacheDispatcherHost.
    188   void RegisterBackend(AppCacheBackendImpl* backend_impl);
    189   void UnregisterBackend(AppCacheBackendImpl* backend_impl);
    190   AppCacheBackendImpl* GetBackend(int id) const {
    191     BackendMap::const_iterator it = backends_.find(id);
    192     return (it != backends_.end()) ? it->second : NULL;
    193   }
    194 
    195   AppCacheStorage* storage() const { return storage_.get(); }
    196 
    197   // Disables the exit-time deletion of session-only data.
    198   void set_force_keep_session_state() { force_keep_session_state_ = true; }
    199   bool force_keep_session_state() const { return force_keep_session_state_; }
    200 
    201  protected:
    202   friend class AppCacheStorageImplTest;
    203   friend class AppCacheServiceTest;
    204 
    205   class AsyncHelper;
    206   class CanHandleOfflineHelper;
    207   class DeleteHelper;
    208   class DeleteOriginHelper;
    209   class GetInfoHelper;
    210   class CheckResponseHelper;
    211 
    212   typedef std::set<AsyncHelper*> PendingAsyncHelpers;
    213   typedef std::map<int, AppCacheBackendImpl*> BackendMap;
    214 
    215   base::FilePath cache_directory_;
    216   scoped_refptr<base::MessageLoopProxy> db_thread_;
    217   scoped_refptr<base::MessageLoopProxy> cache_thread_;
    218   AppCachePolicy* appcache_policy_;
    219   AppCacheQuotaClient* quota_client_;
    220   AppCacheExecutableHandlerFactory* handler_factory_;
    221   scoped_ptr<AppCacheStorage> storage_;
    222   scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
    223   scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_;
    224   PendingAsyncHelpers pending_helpers_;
    225   BackendMap backends_;  // One 'backend' per child process.
    226   // Context for use during cache updates.
    227   net::URLRequestContext* request_context_;
    228   // If true, nothing (not even session-only data) should be deleted on exit.
    229   bool force_keep_session_state_;
    230   bool was_reinitialized_;
    231   ObserverList<Observer> observers_;
    232 
    233   DISALLOW_COPY_AND_ASSIGN(AppCacheService);
    234 };
    235 
    236 }  // namespace appcache
    237 
    238 #endif  // WEBKIT_BROWSER_APPCACHE_APPCACHE_SERVICE_H_
    239