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