Home | History | Annotate | Download | only in service_worker
      1 // Copyright 2013 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 CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
      6 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
      7 
      8 #include <deque>
      9 #include <map>
     10 #include <set>
     11 #include <vector>
     12 
     13 #include "base/bind.h"
     14 #include "base/files/file_path.h"
     15 #include "base/gtest_prod_util.h"
     16 #include "base/memory/scoped_vector.h"
     17 #include "base/memory/weak_ptr.h"
     18 #include "content/browser/service_worker/service_worker_database.h"
     19 #include "content/common/content_export.h"
     20 #include "content/common/service_worker/service_worker_status_code.h"
     21 #include "url/gurl.h"
     22 
     23 namespace base {
     24 class MessageLoopProxy;
     25 class SequencedTaskRunner;
     26 }
     27 
     28 namespace quota {
     29 class QuotaManagerProxy;
     30 }
     31 
     32 namespace content {
     33 
     34 class ServiceWorkerContextCore;
     35 class ServiceWorkerDiskCache;
     36 class ServiceWorkerRegistration;
     37 class ServiceWorkerRegistrationInfo;
     38 class ServiceWorkerResponseReader;
     39 class ServiceWorkerResponseWriter;
     40 class ServiceWorkerVersion;
     41 
     42 // This class provides an interface to store and retrieve ServiceWorker
     43 // registration data.
     44 class CONTENT_EXPORT ServiceWorkerStorage {
     45  public:
     46   typedef std::vector<ServiceWorkerDatabase::ResourceRecord> ResourceList;
     47   typedef base::Callback<void(ServiceWorkerStatusCode status)> StatusCallback;
     48   typedef base::Callback<void(ServiceWorkerStatusCode status,
     49                               const scoped_refptr<ServiceWorkerRegistration>&
     50                                   registration)> FindRegistrationCallback;
     51   typedef base::Callback<
     52       void(const std::vector<ServiceWorkerRegistrationInfo>& registrations)>
     53           GetAllRegistrationInfosCallback;
     54   typedef base::Callback<
     55       void(ServiceWorkerStatusCode status, int result)>
     56           CompareCallback;
     57 
     58   ServiceWorkerStorage(const base::FilePath& path,
     59                        base::WeakPtr<ServiceWorkerContextCore> context,
     60                        base::SequencedTaskRunner* database_task_runner,
     61                        base::MessageLoopProxy* disk_cache_thread,
     62                        quota::QuotaManagerProxy* quota_manager_proxy);
     63   ~ServiceWorkerStorage();
     64 
     65   // Finds registration for |document_url| or |pattern| or |registration_id|.
     66   // The Find methods will find stored and initially installing registrations.
     67   // Returns SERVICE_WORKER_OK with non-null registration if registration
     68   // is found, or returns SERVICE_WORKER_ERROR_NOT_FOUND if no matching
     69   // registration is found.  The FindRegistrationForPattern method is
     70   // guaranteed to return asynchronously. However, the methods to find
     71   // for |document_url| or |registration_id| may complete immediately
     72   // (the callback may be called prior to the method returning) or
     73   // asynchronously.
     74   void FindRegistrationForDocument(const GURL& document_url,
     75                                    const FindRegistrationCallback& callback);
     76   void FindRegistrationForPattern(const GURL& scope,
     77                                   const FindRegistrationCallback& callback);
     78   void FindRegistrationForId(int64 registration_id,
     79                              const GURL& origin,
     80                              const FindRegistrationCallback& callback);
     81 
     82   // Returns info about all stored and initially installing registrations.
     83   void GetAllRegistrations(const GetAllRegistrationInfosCallback& callback);
     84 
     85   // Commits |registration| with the installed but not activated |version|
     86   // to storage, overwritting any pre-existing registration data for the scope.
     87   // A pre-existing version's script resources will remain available until
     88   // either a browser restart or DeleteVersionResources is called.
     89   void StoreRegistration(
     90       ServiceWorkerRegistration* registration,
     91       ServiceWorkerVersion* version,
     92       const StatusCallback& callback);
     93 
     94   // Updates the state of the registration's stored version to active.
     95   void UpdateToActiveState(
     96       ServiceWorkerRegistration* registration,
     97       const StatusCallback& callback);
     98 
     99   // Deletes the registration data for |registration_id|, the
    100   // script resources for the registration's stored version
    101   // will remain available until either a browser restart or
    102   // DeleteVersionResources is called.
    103   void DeleteRegistration(int64 registration_id,
    104                           const GURL& origin,
    105                           const StatusCallback& callback);
    106 
    107   scoped_ptr<ServiceWorkerResponseReader> CreateResponseReader(
    108       int64 response_id);
    109   scoped_ptr<ServiceWorkerResponseWriter> CreateResponseWriter(
    110       int64 response_id);
    111 
    112   // Adds |id| to the set of resources ids that are in the disk
    113   // cache but not yet stored with a registration.
    114   void StoreUncommittedReponseId(int64 id);
    115 
    116   // Removes |id| from uncommitted list, adds it to the
    117   // purgeable list and purges it.
    118   void DoomUncommittedResponse(int64 id);
    119 
    120   // Returns new IDs which are guaranteed to be unique in the storage.
    121   int64 NewRegistrationId();
    122   int64 NewVersionId();
    123   int64 NewResourceId();
    124 
    125   // Intended for use only by ServiceWorkerRegisterJob.
    126   void NotifyInstallingRegistration(
    127       ServiceWorkerRegistration* registration);
    128   void NotifyDoneInstallingRegistration(
    129       ServiceWorkerRegistration* registration,
    130       ServiceWorkerVersion* version,
    131       ServiceWorkerStatusCode status);
    132 
    133  private:
    134   friend class ServiceWorkerStorageTest;
    135   FRIEND_TEST_ALL_PREFIXES(ServiceWorkerStorageTest,
    136                            ResourceIdsAreStoredAndPurged);
    137 
    138   struct InitialData {
    139     int64 next_registration_id;
    140     int64 next_version_id;
    141     int64 next_resource_id;
    142     std::set<GURL> origins;
    143 
    144     InitialData();
    145     ~InitialData();
    146   };
    147 
    148   typedef std::vector<ServiceWorkerDatabase::RegistrationData> RegistrationList;
    149   typedef std::map<int64, scoped_refptr<ServiceWorkerRegistration> >
    150       RegistrationRefsById;
    151   typedef base::Callback<void(
    152       InitialData* data,
    153       ServiceWorkerDatabase::Status status)> InitializeCallback;
    154   typedef base::Callback<void(
    155       const GURL& origin,
    156       const std::vector<int64>& newly_purgeable_resources,
    157       ServiceWorkerDatabase::Status status)> WriteRegistrationCallback;
    158   typedef base::Callback<void(
    159       bool origin_is_deletable,
    160       const std::vector<int64>& newly_purgeable_resources,
    161       ServiceWorkerDatabase::Status status)> DeleteRegistrationCallback;
    162   typedef base::Callback<void(
    163       const ServiceWorkerDatabase::RegistrationData& data,
    164       const ResourceList& resources,
    165       ServiceWorkerDatabase::Status status)> FindInDBCallback;
    166 
    167   base::FilePath GetDatabasePath();
    168   base::FilePath GetDiskCachePath();
    169 
    170   bool LazyInitialize(
    171       const base::Closure& callback);
    172   void DidReadInitialData(
    173       InitialData* data,
    174       ServiceWorkerDatabase::Status status);
    175   void DidFindRegistrationForDocument(
    176       const GURL& document_url,
    177       const FindRegistrationCallback& callback,
    178       const ServiceWorkerDatabase::RegistrationData& data,
    179       const ResourceList& resources,
    180       ServiceWorkerDatabase::Status status);
    181   void DidFindRegistrationForPattern(
    182       const GURL& scope,
    183       const FindRegistrationCallback& callback,
    184       const ServiceWorkerDatabase::RegistrationData& data,
    185       const ResourceList& resources,
    186       ServiceWorkerDatabase::Status status);
    187   void DidFindRegistrationForId(
    188       const FindRegistrationCallback& callback,
    189       const ServiceWorkerDatabase::RegistrationData& data,
    190       const ResourceList& resources,
    191       ServiceWorkerDatabase::Status status);
    192   void DidGetAllRegistrations(
    193       const GetAllRegistrationInfosCallback& callback,
    194       RegistrationList* registrations,
    195       ServiceWorkerDatabase::Status status);
    196   void DidStoreRegistration(
    197       const StatusCallback& callback,
    198       const GURL& origin,
    199       const std::vector<int64>& newly_purgeable_resources,
    200       ServiceWorkerDatabase::Status status);
    201   void DidUpdateToActiveState(
    202       const StatusCallback& callback,
    203       ServiceWorkerDatabase::Status status);
    204   void DidDeleteRegistration(
    205       const GURL& origin,
    206       const StatusCallback& callback,
    207       bool origin_is_deletable,
    208       const std::vector<int64>& newly_purgeable_resources,
    209       ServiceWorkerDatabase::Status status);
    210 
    211   scoped_refptr<ServiceWorkerRegistration> GetOrCreateRegistration(
    212       const ServiceWorkerDatabase::RegistrationData& data,
    213       const ResourceList& resources);
    214   ServiceWorkerRegistration* FindInstallingRegistrationForDocument(
    215       const GURL& document_url);
    216   ServiceWorkerRegistration* FindInstallingRegistrationForPattern(
    217       const GURL& scope);
    218   ServiceWorkerRegistration* FindInstallingRegistrationForId(
    219       int64 registration_id);
    220 
    221   // Lazy disk_cache getter.
    222   ServiceWorkerDiskCache* disk_cache();
    223   void OnDiskCacheInitialized(int rv);
    224 
    225   void StartPurgingResources(const std::vector<int64>& ids);
    226   void StartPurgingResources(const ResourceList& resources);
    227   void ContinuePurgingResources();
    228   void PurgeResource(int64 id);
    229   void OnResourcePurged(int64 id, int rv);
    230 
    231   // Static cross-thread helpers.
    232   static void ReadInitialDataFromDB(
    233       ServiceWorkerDatabase* database,
    234       scoped_refptr<base::SequencedTaskRunner> original_task_runner,
    235       const InitializeCallback& callback);
    236   static void DeleteRegistrationFromDB(
    237       ServiceWorkerDatabase* database,
    238       scoped_refptr<base::SequencedTaskRunner> original_task_runner,
    239       int64 registration_id,
    240       const GURL& origin,
    241       const DeleteRegistrationCallback& callback);
    242   static void WriteRegistrationInDB(
    243       ServiceWorkerDatabase* database,
    244       scoped_refptr<base::SequencedTaskRunner> original_task_runner,
    245       const ServiceWorkerDatabase::RegistrationData& registration,
    246       const ResourceList& resources,
    247       const WriteRegistrationCallback& callback);
    248   static void FindForDocumentInDB(
    249       ServiceWorkerDatabase* database,
    250       scoped_refptr<base::SequencedTaskRunner> original_task_runner,
    251       const GURL& document_url,
    252       const FindInDBCallback& callback);
    253   static void FindForPatternInDB(
    254       ServiceWorkerDatabase* database,
    255       scoped_refptr<base::SequencedTaskRunner> original_task_runner,
    256       const GURL& scope,
    257       const FindInDBCallback& callback);
    258   static void FindForIdInDB(
    259       ServiceWorkerDatabase* database,
    260       scoped_refptr<base::SequencedTaskRunner> original_task_runner,
    261       int64 registration_id,
    262       const GURL& origin,
    263       const FindInDBCallback& callback);
    264 
    265   // For finding registrations being installed.
    266   RegistrationRefsById installing_registrations_;
    267 
    268   // Origins having registations.
    269   std::set<GURL> registered_origins_;
    270 
    271   // Pending database tasks waiting for initialization.
    272   std::vector<base::Closure> pending_tasks_;
    273 
    274   int64 next_registration_id_;
    275   int64 next_version_id_;
    276   int64 next_resource_id_;
    277 
    278   enum State {
    279     UNINITIALIZED,
    280     INITIALIZING,
    281     INITIALIZED,
    282     DISABLED,
    283   };
    284   State state_;
    285 
    286   base::FilePath path_;
    287   base::WeakPtr<ServiceWorkerContextCore> context_;
    288 
    289   // Only accessed on |database_task_runner_|.
    290   scoped_ptr<ServiceWorkerDatabase> database_;
    291 
    292   scoped_refptr<base::SequencedTaskRunner> database_task_runner_;
    293   scoped_refptr<base::MessageLoopProxy> disk_cache_thread_;
    294   scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_;
    295   scoped_ptr<ServiceWorkerDiskCache> disk_cache_;
    296   std::deque<int64> purgeable_reource_ids_;
    297   bool is_purge_pending_;
    298 
    299   base::WeakPtrFactory<ServiceWorkerStorage> weak_factory_;
    300 
    301   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerStorage);
    302 };
    303 
    304 }  // namespace content
    305 
    306 #endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STORAGE_H_
    307