File: ServiceWorkerRegistrar.h

package info (click to toggle)
firefox 143.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,617,328 kB
  • sloc: cpp: 7,478,492; javascript: 6,417,157; ansic: 3,720,058; python: 1,396,372; xml: 627,523; asm: 438,677; java: 186,156; sh: 63,477; makefile: 19,171; objc: 13,059; perl: 12,983; yacc: 4,583; cs: 3,846; pascal: 3,405; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (161 lines) | stat: -rw-r--r-- 4,943 bytes parent folder | download | duplicates (3)
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