tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ServiceWorkerRegistrationInfo.h (9220B)


      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_serviceworkerregistrationinfo_h
      8 #define mozilla_dom_serviceworkerregistrationinfo_h
      9 
     10 #include <functional>
     11 
     12 #include "mozilla/dom/IPCNavigationPreloadState.h"
     13 #include "mozilla/dom/ServiceWorkerInfo.h"
     14 #include "mozilla/dom/ServiceWorkerLifetimeExtension.h"
     15 #include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
     16 #include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
     17 #include "nsProxyRelease.h"
     18 #include "nsTObserverArray.h"
     19 
     20 namespace mozilla::dom {
     21 
     22 class ServiceWorkerRegistrationListener;
     23 
     24 class ServiceWorkerRegistrationInfo final
     25    : public nsIServiceWorkerRegistrationInfo {
     26  nsCOMPtr<nsIPrincipal> mPrincipal;
     27  ServiceWorkerRegistrationDescriptor mDescriptor;
     28  nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
     29  nsTObserverArray<ServiceWorkerRegistrationListener*> mInstanceList;
     30 
     31  struct VersionEntry {
     32    const ServiceWorkerRegistrationDescriptor mDescriptor;
     33    TimeStamp mTimeStamp;
     34 
     35    explicit VersionEntry(
     36        const ServiceWorkerRegistrationDescriptor& aDescriptor)
     37        : mDescriptor(aDescriptor), mTimeStamp(TimeStamp::Now()) {}
     38  };
     39  nsTArray<UniquePtr<VersionEntry>> mVersionList;
     40 
     41  const nsID mAgentClusterId = nsID::GenerateUUID();
     42 
     43  uint32_t mControlledClientsCounter;
     44  uint32_t mDelayMultiplier;
     45 
     46  enum { NoUpdate, NeedTimeCheckAndUpdate, NeedUpdate } mUpdateState;
     47 
     48  // Timestamp to track SWR's last update time
     49  PRTime mCreationTime;
     50  TimeStamp mCreationTimeStamp;
     51  // The time of update is 0, if SWR've never been updated yet.
     52  PRTime mLastUpdateTime;
     53 
     54  RefPtr<ServiceWorkerInfo> mEvaluatingWorker;
     55  RefPtr<ServiceWorkerInfo> mActiveWorker;
     56  RefPtr<ServiceWorkerInfo> mWaitingWorker;
     57  RefPtr<ServiceWorkerInfo> mInstallingWorker;
     58 
     59  virtual ~ServiceWorkerRegistrationInfo();
     60 
     61  // When unregister() is called on a registration, it is removed from the
     62  // "scope to registration map" but not immediately "cleared" (i.e. its workers
     63  // terminated, updated to the redundant state, etc.) because it may still be
     64  // controlling clients. It is marked as unregistered and when all controlled
     65  // clients go away, cleared. This way we can tell if a registration
     66  // is unregistered by querying the object itself rather than incurring a table
     67  // lookup (in the case when the registrations are passed around as pointers).
     68  bool mUnregistered;
     69 
     70  bool mCorrupt;
     71 
     72  IPCNavigationPreloadState mNavigationPreloadState;
     73  int64_t mNumberOfAttemptedActivations{0};
     74  bool mIsBroken{false};
     75  int64_t mCacheAPIId{-1};
     76 
     77 public:
     78  NS_DECL_ISUPPORTS
     79  NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
     80 
     81  using TryToActivateCallback = std::function<void()>;
     82 
     83  ServiceWorkerRegistrationInfo(
     84      const nsACString& aScope, WorkerType aType, nsIPrincipal* aPrincipal,
     85      ServiceWorkerUpdateViaCache aUpdateViaCache,
     86      IPCNavigationPreloadState&& aNavigationPreloadState);
     87 
     88  int64_t GetNumberOfAttemptedActivations() const {
     89    return mNumberOfAttemptedActivations;
     90  }
     91 
     92  bool IsBroken() const { return mIsBroken; }
     93 
     94  int64_t GetCacheAPIId() const { return mCacheAPIId; }
     95 
     96  void AddInstance(ServiceWorkerRegistrationListener* aInstance,
     97                   const ServiceWorkerRegistrationDescriptor& aDescriptor);
     98 
     99  void RemoveInstance(ServiceWorkerRegistrationListener* aInstance);
    100 
    101  const nsCString& Scope() const;
    102 
    103  WorkerType Type() const;
    104 
    105  nsIPrincipal* Principal() const;
    106 
    107  bool IsUnregistered() const;
    108 
    109  void SetUnregistered();
    110 
    111  already_AddRefed<ServiceWorkerInfo> Newest() const {
    112    RefPtr<ServiceWorkerInfo> newest;
    113    if (mInstallingWorker) {
    114      newest = mInstallingWorker;
    115    } else if (mWaitingWorker) {
    116      newest = mWaitingWorker;
    117    } else {
    118      newest = mActiveWorker;
    119    }
    120 
    121    return newest.forget();
    122  }
    123 
    124  already_AddRefed<ServiceWorkerInfo> NewestIncludingEvaluating() const {
    125    if (mEvaluatingWorker) {
    126      RefPtr<ServiceWorkerInfo> newest = mEvaluatingWorker;
    127      return newest.forget();
    128    }
    129    return Newest();
    130  }
    131 
    132  already_AddRefed<ServiceWorkerInfo> GetServiceWorkerInfoById(uint64_t aId);
    133 
    134  void StartControllingClient() {
    135    ++mControlledClientsCounter;
    136    mDelayMultiplier = 0;
    137  }
    138 
    139  void StopControllingClient() {
    140    MOZ_ASSERT(mControlledClientsCounter);
    141    --mControlledClientsCounter;
    142  }
    143 
    144  bool IsControllingClients() const {
    145    return mActiveWorker && mControlledClientsCounter;
    146  }
    147 
    148  // As a side effect, this nullifies
    149  // `m{Evaluating,Installing,Waiting,Active}Worker`s.
    150  void ShutdownWorkers();
    151 
    152  void Clear();
    153 
    154  void ClearAsCorrupt();
    155 
    156  bool IsCorrupt() const;
    157 
    158  void TryToActivateAsync(
    159      const ServiceWorkerLifetimeExtension& aLifetimeExtension,
    160      TryToActivateCallback&& aCallback = nullptr);
    161 
    162  void TryToActivate(ServiceWorkerLifetimeExtension&& aLifetimeExtension,
    163                     TryToActivateCallback&& aCallback);
    164 
    165  void Activate(const ServiceWorkerLifetimeExtension& aLifetimeExtension);
    166 
    167  void FinishActivate(bool aSuccess);
    168 
    169  void RefreshLastUpdateCheckTime();
    170 
    171  bool IsLastUpdateCheckTimeOverOneDay() const;
    172 
    173  void MaybeScheduleTimeCheckAndUpdate();
    174 
    175  void MaybeScheduleUpdate();
    176 
    177  bool CheckAndClearIfUpdateNeeded();
    178 
    179  ServiceWorkerInfo* GetEvaluating() const;
    180 
    181  ServiceWorkerInfo* GetInstalling() const;
    182 
    183  ServiceWorkerInfo* GetWaiting() const;
    184 
    185  ServiceWorkerInfo* GetActive() const;
    186 
    187  ServiceWorkerInfo* GetByDescriptor(
    188      const ServiceWorkerDescriptor& aDescriptor) const;
    189 
    190  ServiceWorkerInfo* GetByClientInfo(const ClientInfo& aClientInfo) const;
    191 
    192  // Set the given worker as the evaluating service worker.  The worker
    193  // state is not changed.
    194  void SetEvaluating(ServiceWorkerInfo* aServiceWorker);
    195 
    196  // Remove an existing evaluating worker, if present.  The worker will
    197  // be transitioned to the Redundant state.
    198  void ClearEvaluating();
    199 
    200  // Remove an existing installing worker, if present.  The worker will
    201  // be transitioned to the Redundant state.
    202  void ClearInstalling();
    203 
    204  // Transition the current evaluating worker to be the installing worker.  The
    205  // worker's state is update to Installing.
    206  void TransitionEvaluatingToInstalling();
    207 
    208  // Transition the current installing worker to be the waiting worker.  The
    209  // worker's state is updated to Installed.
    210  void TransitionInstallingToWaiting();
    211 
    212  // Override the current active worker.  This is used during browser
    213  // initialization to load persisted workers.  Its also used to propagate
    214  // active workers across child processes in e10s.  This second use will
    215  // go away once the ServiceWorkerManager moves to the parent process.
    216  // The worker is transitioned to the Activated state.
    217  void SetActive(ServiceWorkerInfo* aServiceWorker);
    218 
    219  // Transition the current waiting worker to be the new active worker.  The
    220  // worker is updated to the Activating state.
    221  void TransitionWaitingToActive();
    222 
    223  // Determine if the registration is actively performing work.
    224  bool IsIdle() const;
    225 
    226  ServiceWorkerUpdateViaCache GetUpdateViaCache() const;
    227 
    228  void SetOptions(ServiceWorkerUpdateViaCache aUpdateViaCache,
    229                  WorkerType aType);
    230 
    231  int64_t GetLastUpdateTime() const;
    232 
    233  void SetLastUpdateTime(const int64_t aTime);
    234 
    235  const ServiceWorkerRegistrationDescriptor& Descriptor() const;
    236 
    237  uint64_t Id() const;
    238 
    239  uint64_t Version() const;
    240 
    241  uint32_t GetUpdateDelay(const bool aWithMultiplier = true);
    242 
    243  void FireUpdateFound();
    244 
    245  void NotifyCleared();
    246 
    247  void ClearWhenIdle();
    248 
    249  const nsID& AgentClusterId() const;
    250 
    251  void SetNavigationPreloadEnabled(const bool& aEnabled);
    252 
    253  void SetNavigationPreloadHeader(const nsCString& aHeader);
    254 
    255  IPCNavigationPreloadState GetNavigationPreloadState() const;
    256 
    257 private:
    258  // Roughly equivalent to [[Update Registration State algorithm]]. Make sure
    259  // this is called *before* updating SW instances' state, otherwise they
    260  // may get CC-ed.
    261  void UpdateRegistrationState();
    262 
    263  void UpdateRegistrationState(ServiceWorkerUpdateViaCache aUpdateViaCache,
    264                               WorkerType aType);
    265 
    266  // Used by devtools to track changes to the properties of
    267  // *nsIServiceWorkerRegistrationInfo*. Note, this doesn't necessarily need to
    268  // be in sync with the DOM registration objects, but it does need to be called
    269  // in the same task that changed |mInstallingWorker|, |mWaitingWorker| or
    270  // |mActiveWorker|.
    271  void NotifyChromeRegistrationListeners();
    272 
    273  static uint64_t GetNextId();
    274 
    275  static uint64_t GetNextVersion();
    276 
    277  // `aFunc`'s argument will be a reference to
    278  // `m{Evaluating,Installing,Waiting,Active}Worker` (not to copy of them).
    279  // Additionally, a null check will be performed for each worker before each
    280  // call to `aFunc`, so `aFunc` will always get a reference to a non-null
    281  // pointer.
    282  void ForEachWorker(void (*aFunc)(RefPtr<ServiceWorkerInfo>&));
    283 
    284  void CheckQuotaUsage();
    285 };
    286 
    287 }  // namespace mozilla::dom
    288 
    289 #endif  // mozilla_dom_serviceworkerregistrationinfo_h