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_serviceworkerinfo_h
8 #define mozilla_dom_serviceworkerinfo_h
9 
10 #include "MainThreadUtils.h"
11 #include "mozilla/dom/ServiceWorkerBinding.h"  // For ServiceWorkerState
12 #include "mozilla/dom/WorkerCommon.h"
13 #include "mozilla/OriginAttributes.h"
14 #include "nsIServiceWorkerManager.h"
15 
16 namespace mozilla {
17 namespace dom {
18 
19 class ClientInfoAndState;
20 class ClientState;
21 class ServiceWorkerCloneData;
22 class ServiceWorkerPrivate;
23 
24 /*
25  * Wherever the spec treats a worker instance and a description of said worker
26  * as the same thing; i.e. "Resolve foo with
27  * _GetNewestWorker(serviceWorkerRegistration)", we represent the description
28  * by this class and spawn a ServiceWorker in the right global when required.
29  */
30 class ServiceWorkerInfo final : public nsIServiceWorkerInfo {
31  private:
32   nsCOMPtr<nsIPrincipal> mPrincipal;
33   ServiceWorkerDescriptor mDescriptor;
34   const nsString mCacheName;
35   OriginAttributes mOriginAttributes;
36   const nsString mWorkerPrivateId;
37 
38   // This LoadFlags is only applied to imported scripts, since the main script
39   // has already been downloaded when performing the bytecheck. This LoadFlag is
40   // composed of three parts:
41   //   1. nsIChannel::LOAD_BYPASS_SERVICE_WORKER
42   //   2. (Optional) nsIRequest::VALIDATE_ALWAYS
43   //      depends on ServiceWorkerUpdateViaCache of its registration.
44   //   3. (optional) nsIRequest::LOAD_BYPASS_CACHE
45   //      depends on whether the update timer is expired.
46   const nsLoadFlags mImportsLoadFlags;
47 
48   // Timestamp to track SW's state
49   PRTime mCreationTime;
50   TimeStamp mCreationTimeStamp;
51 
52   // The time of states are 0, if SW has not reached that state yet. Besides, we
53   // update each of them after UpdateState() is called in SWRegistrationInfo.
54   PRTime mInstalledTime;
55   PRTime mActivatedTime;
56   PRTime mRedundantTime;
57 
58   RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate;
59   bool mSkipWaitingFlag;
60 
61   enum { Unknown, Enabled, Disabled } mHandlesFetch;
62 
63   ~ServiceWorkerInfo();
64 
65   // Generates a unique id for the service worker, with zero being treated as
66   // invalid.
67   uint64_t GetNextID() const;
68 
69  public:
70   NS_DECL_ISUPPORTS
71   NS_DECL_NSISERVICEWORKERINFO
72 
73   void PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
74                    const ClientInfo& aClientInfo,
75                    const ClientState& aClientState);
76 
WorkerPrivate()77   class ServiceWorkerPrivate* WorkerPrivate() const {
78     MOZ_ASSERT(mServiceWorkerPrivate);
79     return mServiceWorkerPrivate;
80   }
81 
Principal()82   nsIPrincipal* Principal() const { return mPrincipal; }
83 
ScriptSpec()84   const nsCString& ScriptSpec() const { return mDescriptor.ScriptURL(); }
85 
Scope()86   const nsCString& Scope() const { return mDescriptor.Scope(); }
87 
SkipWaitingFlag()88   bool SkipWaitingFlag() const {
89     MOZ_ASSERT(NS_IsMainThread());
90     return mSkipWaitingFlag;
91   }
92 
SetSkipWaitingFlag()93   void SetSkipWaitingFlag() {
94     MOZ_ASSERT(NS_IsMainThread());
95     mSkipWaitingFlag = true;
96   }
97 
98   ServiceWorkerInfo(nsIPrincipal* aPrincipal, const nsACString& aScope,
99                     uint64_t aRegistrationId, uint64_t aRegistrationVersion,
100                     const nsACString& aScriptSpec, const nsAString& aCacheName,
101                     nsLoadFlags aLoadFlags);
102 
State()103   ServiceWorkerState State() const { return mDescriptor.State(); }
104 
GetOriginAttributes()105   const OriginAttributes& GetOriginAttributes() const {
106     return mOriginAttributes;
107   }
108 
CacheName()109   const nsString& CacheName() const { return mCacheName; }
110 
GetImportsLoadFlags()111   nsLoadFlags GetImportsLoadFlags() const { return mImportsLoadFlags; }
112 
ID()113   uint64_t ID() const { return mDescriptor.Id(); }
114 
Descriptor()115   const ServiceWorkerDescriptor& Descriptor() const { return mDescriptor; }
116 
117   void UpdateState(ServiceWorkerState aState);
118 
119   // Only used to set initial state when loading from disk!
SetActivateStateUncheckedWithoutEvent(ServiceWorkerState aState)120   void SetActivateStateUncheckedWithoutEvent(ServiceWorkerState aState) {
121     MOZ_ASSERT(NS_IsMainThread());
122     mDescriptor.SetState(aState);
123   }
124 
SetHandlesFetch(bool aHandlesFetch)125   void SetHandlesFetch(bool aHandlesFetch) {
126     MOZ_ASSERT(NS_IsMainThread());
127     MOZ_DIAGNOSTIC_ASSERT(mHandlesFetch == Unknown);
128     mHandlesFetch = aHandlesFetch ? Enabled : Disabled;
129     mDescriptor.SetHandlesFetch(aHandlesFetch);
130   }
131 
132   void SetRegistrationVersion(uint64_t aVersion);
133 
HandlesFetch()134   bool HandlesFetch() const {
135     MOZ_ASSERT(NS_IsMainThread());
136     MOZ_DIAGNOSTIC_ASSERT(mHandlesFetch != Unknown);
137     return mHandlesFetch != Disabled;
138   }
139 
140   void UpdateInstalledTime();
141 
142   void UpdateActivatedTime();
143 
144   void UpdateRedundantTime();
145 
GetInstalledTime()146   int64_t GetInstalledTime() const { return mInstalledTime; }
147 
SetInstalledTime(const int64_t aTime)148   void SetInstalledTime(const int64_t aTime) {
149     if (aTime == 0) {
150       return;
151     }
152 
153     mInstalledTime = aTime;
154   }
155 
GetActivatedTime()156   int64_t GetActivatedTime() const { return mActivatedTime; }
157 
SetActivatedTime(const int64_t aTime)158   void SetActivatedTime(const int64_t aTime) {
159     if (aTime == 0) {
160       return;
161     }
162 
163     mActivatedTime = aTime;
164   }
165 };
166 
167 }  // namespace dom
168 }  // namespace mozilla
169 
170 #endif  // mozilla_dom_serviceworkerinfo_h
171