ServiceWorkerRegistrar.h (4943B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_ServiceWorkerRegistrar_h 8 #define mozilla_dom_ServiceWorkerRegistrar_h 9 10 #include "mozilla/Monitor.h" 11 #include "mozilla/dom/ServiceWorkerRegistrarTypes.h" 12 #include "nsCOMPtr.h" 13 #include "nsClassHashtable.h" 14 #include "nsIAsyncShutdown.h" 15 #include "nsIObserver.h" 16 #include "nsString.h" 17 #include "nsTArray.h" 18 19 #define SERVICEWORKERREGISTRAR_FILE u"serviceworker.txt" 20 #define SERVICEWORKERREGISTRAR_VERSION 12 21 #define SERVICEWORKERREGISTRAR_TERMINATOR "#" 22 #define SERVICEWORKERREGISTRAR_TRUE "true" 23 #define SERVICEWORKERREGISTRAR_FALSE "false" 24 25 class nsIFile; 26 27 namespace mozilla { 28 29 namespace ipc { 30 class PrincipalInfo; 31 } // namespace ipc 32 33 } // namespace mozilla 34 35 namespace mozilla::dom { 36 37 class ServiceWorkerRegistrar : public nsIObserver, 38 public nsIAsyncShutdownBlocker { 39 friend class ServiceWorkerRegistrarSaveDataRunnable; 40 41 // The internal data struct is public to make gtests happy. 42 public: 43 // An expando handler consists of a set of callbacks and a key. During 44 // serialization/deserialization, ServiceWorkerRegistrar triggers these 45 // callbacks based on the key name found on disk. 46 struct ExpandoHandler { 47 nsCString mKey; 48 // The deserialization of the value is up to this callback. 49 void (*mServiceWorkerLoaded)(const ServiceWorkerRegistrationData& aData, 50 const nsACString& aValue); 51 void (*mServiceWorkerUpdated)(const ServiceWorkerRegistrationData& aData); 52 void (*mServiceWorkerUnregistered)( 53 const ServiceWorkerRegistrationData& aData); 54 }; 55 56 struct ExpandoData { 57 nsCString mKey; 58 nsCString mValue; 59 const ExpandoHandler* mHandler; 60 }; 61 62 struct ServiceWorkerData { 63 ServiceWorkerRegistrationData mRegistration; 64 CopyableTArray<ExpandoData> mExpandos; 65 }; 66 67 public: 68 NS_DECL_THREADSAFE_ISUPPORTS 69 NS_DECL_NSIOBSERVER 70 NS_DECL_NSIASYNCSHUTDOWNBLOCKER 71 72 static void Initialize(); 73 74 void Shutdown(); 75 76 void DataSaved(uint32_t aFileGeneration); 77 78 static already_AddRefed<ServiceWorkerRegistrar> Get(); 79 80 void GetRegistrations(nsTArray<ServiceWorkerRegistrationData>& aValues); 81 82 void RegisterServiceWorker(const ServiceWorkerRegistrationData& aData); 83 void UnregisterServiceWorker( 84 const mozilla::ipc::PrincipalInfo& aPrincipalInfo, 85 const nsACString& aScope); 86 87 // Add or overwrite an expando key/value to a SW registration. 88 void StoreServiceWorkerExpandoOnMainThread( 89 const mozilla::ipc::PrincipalInfo& aPrincipalInfo, 90 const nsACString& aScope, const nsACString& aKey, 91 const nsACString& aValue); 92 93 // Remove an existing expando key from a SW registration. 94 // This method is main-thread only. 95 void UnstoreServiceWorkerExpandoOnMainThread( 96 const mozilla::ipc::PrincipalInfo& aPrincipalInfo, 97 const nsACString& aScope, const nsACString& aKey); 98 99 void RemoveAll(); 100 101 bool ReloadDataForTest(); 102 103 protected: 104 // These methods are protected because we test this class using gTest 105 // subclassing it. 106 void LoadData(); 107 nsresult SaveData(const nsTArray<ServiceWorkerData>& aData); 108 109 nsresult ReadData(); 110 nsresult WriteData(const nsTArray<ServiceWorkerData>& aData); 111 void DeleteData(); 112 113 void RegisterServiceWorkerInternal(const ServiceWorkerRegistrationData& aData) 114 MOZ_REQUIRES(mMonitor); 115 116 ServiceWorkerRegistrar(); 117 virtual ~ServiceWorkerRegistrar(); 118 119 private: 120 void ProfileStarted(); 121 void ProfileStopped(); 122 123 void MaybeScheduleSaveData(); 124 void ShutdownCompleted(); 125 void MaybeScheduleShutdownCompleted(); 126 127 uint32_t GetNextGeneration(); 128 void MaybeResetGeneration(); 129 130 nsCOMPtr<nsIAsyncShutdownClient> GetShutdownPhase() const; 131 132 bool IsSupportedVersion(uint32_t aVersion) const; 133 134 void LoadExpandoCallbacks(const CopyableTArray<ServiceWorkerData>& aData); 135 void UpdateExpandoCallbacks(const ServiceWorkerData& aData); 136 void UnregisterExpandoCallbacks( 137 const CopyableTArray<ServiceWorkerData>& aData); 138 139 protected: 140 mozilla::Monitor mMonitor; 141 142 // protected by mMonitor. 143 nsCOMPtr<nsIFile> mProfileDir MOZ_GUARDED_BY(mMonitor); 144 // Read on mainthread, modified on background thread EXCEPT for 145 // ReloadDataForTest() AND for gtest, which modifies this on MainThread. 146 nsTArray<ServiceWorkerData> mData MOZ_GUARDED_BY(mMonitor); 147 bool mDataLoaded MOZ_GUARDED_BY(mMonitor); 148 149 // PBackground thread only 150 uint32_t mDataGeneration; 151 uint32_t mFileGeneration; 152 uint32_t mRetryCount; 153 bool mShuttingDown; 154 bool mSaveDataRunnableDispatched; 155 156 nsTArray<ExpandoHandler> mExpandoHandlers; 157 }; 158 159 } // namespace mozilla::dom 160 161 #endif // mozilla_dom_ServiceWorkerRegistrar_h