LCOV - code coverage report
Current view: top level - dom/workers - ServiceWorkerInfo.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 139 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 27 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include "ServiceWorkerInfo.h"
       8             : 
       9             : #include "ServiceWorkerScriptCache.h"
      10             : 
      11             : BEGIN_WORKERS_NAMESPACE
      12             : 
      13             : static_assert(nsIServiceWorkerInfo::STATE_INSTALLING == static_cast<uint16_t>(ServiceWorkerState::Installing),
      14             :               "ServiceWorkerState enumeration value should match state values from nsIServiceWorkerInfo.");
      15             : static_assert(nsIServiceWorkerInfo::STATE_INSTALLED == static_cast<uint16_t>(ServiceWorkerState::Installed),
      16             :               "ServiceWorkerState enumeration value should match state values from nsIServiceWorkerInfo.");
      17             : static_assert(nsIServiceWorkerInfo::STATE_ACTIVATING == static_cast<uint16_t>(ServiceWorkerState::Activating),
      18             :               "ServiceWorkerState enumeration value should match state values from nsIServiceWorkerInfo.");
      19             : static_assert(nsIServiceWorkerInfo::STATE_ACTIVATED == static_cast<uint16_t>(ServiceWorkerState::Activated),
      20             :               "ServiceWorkerState enumeration value should match state values from nsIServiceWorkerInfo.");
      21             : static_assert(nsIServiceWorkerInfo::STATE_REDUNDANT == static_cast<uint16_t>(ServiceWorkerState::Redundant),
      22             :               "ServiceWorkerState enumeration value should match state values from nsIServiceWorkerInfo.");
      23             : static_assert(nsIServiceWorkerInfo::STATE_UNKNOWN == static_cast<uint16_t>(ServiceWorkerState::EndGuard_),
      24             :               "ServiceWorkerState enumeration value should match state values from nsIServiceWorkerInfo.");
      25             : 
      26           0 : NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
      27             : 
      28             : NS_IMETHODIMP
      29           0 : ServiceWorkerInfo::GetScriptSpec(nsAString& aScriptSpec)
      30             : {
      31           0 :   AssertIsOnMainThread();
      32           0 :   CopyUTF8toUTF16(mScriptSpec, aScriptSpec);
      33           0 :   return NS_OK;
      34             : }
      35             : 
      36             : NS_IMETHODIMP
      37           0 : ServiceWorkerInfo::GetCacheName(nsAString& aCacheName)
      38             : {
      39           0 :   AssertIsOnMainThread();
      40           0 :   aCacheName = mCacheName;
      41           0 :   return NS_OK;
      42             : }
      43             : 
      44             : NS_IMETHODIMP
      45           0 : ServiceWorkerInfo::GetState(uint16_t* aState)
      46             : {
      47           0 :   MOZ_ASSERT(aState);
      48           0 :   AssertIsOnMainThread();
      49           0 :   *aState = static_cast<uint16_t>(mState);
      50           0 :   return NS_OK;
      51             : }
      52             : 
      53             : NS_IMETHODIMP
      54           0 : ServiceWorkerInfo::GetDebugger(nsIWorkerDebugger** aResult)
      55             : {
      56           0 :   if (NS_WARN_IF(!aResult)) {
      57           0 :     return NS_ERROR_FAILURE;
      58             :   }
      59             : 
      60           0 :   return mServiceWorkerPrivate->GetDebugger(aResult);
      61             : }
      62             : 
      63             : NS_IMETHODIMP
      64           0 : ServiceWorkerInfo::GetHandlesFetchEvents(bool* aValue)
      65             : {
      66           0 :   MOZ_ASSERT(aValue);
      67           0 :   AssertIsOnMainThread();
      68           0 :   *aValue = HandlesFetch();
      69           0 :   return NS_OK;
      70             : }
      71             : 
      72             : NS_IMETHODIMP
      73           0 : ServiceWorkerInfo::GetInstalledTime(PRTime* _retval)
      74             : {
      75           0 :   AssertIsOnMainThread();
      76           0 :   MOZ_ASSERT(_retval);
      77           0 :   *_retval = mInstalledTime;
      78           0 :   return NS_OK;
      79             : }
      80             : 
      81             : NS_IMETHODIMP
      82           0 : ServiceWorkerInfo::GetActivatedTime(PRTime* _retval)
      83             : {
      84           0 :   AssertIsOnMainThread();
      85           0 :   MOZ_ASSERT(_retval);
      86           0 :   *_retval = mActivatedTime;
      87           0 :   return NS_OK;
      88             : }
      89             : 
      90             : NS_IMETHODIMP
      91           0 : ServiceWorkerInfo::GetRedundantTime(PRTime* _retval)
      92             : {
      93           0 :   AssertIsOnMainThread();
      94           0 :   MOZ_ASSERT(_retval);
      95           0 :   *_retval = mRedundantTime;
      96           0 :   return NS_OK;
      97             : }
      98             : 
      99             : NS_IMETHODIMP
     100           0 : ServiceWorkerInfo::AttachDebugger()
     101             : {
     102           0 :   return mServiceWorkerPrivate->AttachDebugger();
     103             : }
     104             : 
     105             : NS_IMETHODIMP
     106           0 : ServiceWorkerInfo::DetachDebugger()
     107             : {
     108           0 :   return mServiceWorkerPrivate->DetachDebugger();
     109             : }
     110             : 
     111             : void
     112           0 : ServiceWorkerInfo::AppendWorker(ServiceWorker* aWorker)
     113             : {
     114           0 :   MOZ_ASSERT(aWorker);
     115             : #ifdef DEBUG
     116           0 :   nsAutoString workerURL;
     117           0 :   aWorker->GetScriptURL(workerURL);
     118           0 :   MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mScriptSpec)));
     119             : #endif
     120           0 :   MOZ_ASSERT(!mInstances.Contains(aWorker));
     121             : 
     122           0 :   mInstances.AppendElement(aWorker);
     123           0 :   aWorker->SetState(State());
     124           0 : }
     125             : 
     126             : void
     127           0 : ServiceWorkerInfo::RemoveWorker(ServiceWorker* aWorker)
     128             : {
     129           0 :   MOZ_ASSERT(aWorker);
     130             : #ifdef DEBUG
     131           0 :   nsAutoString workerURL;
     132           0 :   aWorker->GetScriptURL(workerURL);
     133           0 :   MOZ_ASSERT(workerURL.Equals(NS_ConvertUTF8toUTF16(mScriptSpec)));
     134             : #endif
     135           0 :   MOZ_ASSERT(mInstances.Contains(aWorker));
     136             : 
     137           0 :   mInstances.RemoveElement(aWorker);
     138           0 : }
     139             : 
     140             : namespace {
     141             : 
     142           0 : class ChangeStateUpdater final : public Runnable
     143             : {
     144             : public:
     145           0 :   ChangeStateUpdater(const nsTArray<ServiceWorker*>& aInstances,
     146             :                      ServiceWorkerState aState)
     147           0 :     : Runnable("dom::workers::ChangeStateUpdater")
     148           0 :     , mState(aState)
     149             :   {
     150           0 :     for (size_t i = 0; i < aInstances.Length(); ++i) {
     151           0 :       mInstances.AppendElement(aInstances[i]);
     152             :     }
     153           0 :   }
     154             : 
     155           0 :   NS_IMETHOD Run() override
     156             :   {
     157             :     // We need to update the state of all instances atomically before notifying
     158             :     // them to make sure that the observed state for all instances inside
     159             :     // statechange event handlers is correct.
     160           0 :     for (size_t i = 0; i < mInstances.Length(); ++i) {
     161           0 :       mInstances[i]->SetState(mState);
     162             :     }
     163           0 :     for (size_t i = 0; i < mInstances.Length(); ++i) {
     164           0 :       mInstances[i]->DispatchStateChange(mState);
     165             :     }
     166             : 
     167           0 :     return NS_OK;
     168             :   }
     169             : 
     170             : private:
     171             :   AutoTArray<RefPtr<ServiceWorker>, 1> mInstances;
     172             :   ServiceWorkerState mState;
     173             : };
     174             : 
     175             : }
     176             : 
     177             : void
     178           0 : ServiceWorkerInfo::UpdateState(ServiceWorkerState aState)
     179             : {
     180           0 :   AssertIsOnMainThread();
     181             : #ifdef DEBUG
     182             :   // Any state can directly transition to redundant, but everything else is
     183             :   // ordered.
     184           0 :   if (aState != ServiceWorkerState::Redundant) {
     185           0 :     MOZ_ASSERT_IF(mState == ServiceWorkerState::EndGuard_, aState == ServiceWorkerState::Installing);
     186           0 :     MOZ_ASSERT_IF(mState == ServiceWorkerState::Installing, aState == ServiceWorkerState::Installed);
     187           0 :     MOZ_ASSERT_IF(mState == ServiceWorkerState::Installed, aState == ServiceWorkerState::Activating);
     188           0 :     MOZ_ASSERT_IF(mState == ServiceWorkerState::Activating, aState == ServiceWorkerState::Activated);
     189             :   }
     190             :   // Activated can only go to redundant.
     191           0 :   MOZ_ASSERT_IF(mState == ServiceWorkerState::Activated, aState == ServiceWorkerState::Redundant);
     192             : #endif
     193             :   // Flush any pending functional events to the worker when it transitions to the
     194             :   // activated state.
     195             :   // TODO: Do we care that these events will race with the propagation of the
     196             :   //       state change?
     197           0 :   if (aState == ServiceWorkerState::Activated && mState != aState) {
     198           0 :     mServiceWorkerPrivate->Activated();
     199             :   }
     200           0 :   mState = aState;
     201           0 :   nsCOMPtr<nsIRunnable> r = new ChangeStateUpdater(mInstances, mState);
     202           0 :   MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r.forget()));
     203           0 :   if (mState == ServiceWorkerState::Redundant) {
     204           0 :     serviceWorkerScriptCache::PurgeCache(mPrincipal, mCacheName);
     205             :   }
     206           0 : }
     207             : 
     208           0 : ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
     209             :                                      const nsACString& aScope,
     210             :                                      const nsACString& aScriptSpec,
     211             :                                      const nsAString& aCacheName,
     212           0 :                                      nsLoadFlags aLoadFlags)
     213             :   : mPrincipal(aPrincipal)
     214             :   , mScope(aScope)
     215             :   , mScriptSpec(aScriptSpec)
     216             :   , mCacheName(aCacheName)
     217             :   , mLoadFlags(aLoadFlags)
     218             :   , mState(ServiceWorkerState::EndGuard_)
     219           0 :   , mServiceWorkerID(GetNextID())
     220           0 :   , mCreationTime(PR_Now())
     221             :   , mCreationTimeStamp(TimeStamp::Now())
     222             :   , mInstalledTime(0)
     223             :   , mActivatedTime(0)
     224             :   , mRedundantTime(0)
     225           0 :   , mServiceWorkerPrivate(new ServiceWorkerPrivate(this))
     226             :   , mSkipWaitingFlag(false)
     227           0 :   , mHandlesFetch(Unknown)
     228             : {
     229           0 :   MOZ_ASSERT(mPrincipal);
     230             :   // cache origin attributes so we can use them off main thread
     231           0 :   mOriginAttributes = mPrincipal->OriginAttributesRef();
     232           0 :   MOZ_ASSERT(!mScope.IsEmpty());
     233           0 :   MOZ_ASSERT(!mScriptSpec.IsEmpty());
     234           0 :   MOZ_ASSERT(!mCacheName.IsEmpty());
     235           0 : }
     236             : 
     237           0 : ServiceWorkerInfo::~ServiceWorkerInfo()
     238             : {
     239           0 :   MOZ_ASSERT(mServiceWorkerPrivate);
     240           0 :   mServiceWorkerPrivate->NoteDeadServiceWorkerInfo();
     241           0 : }
     242             : 
     243             : static uint64_t gServiceWorkerInfoCurrentID = 0;
     244             : 
     245             : uint64_t
     246           0 : ServiceWorkerInfo::GetNextID() const
     247             : {
     248           0 :   return ++gServiceWorkerInfoCurrentID;
     249             : }
     250             : 
     251             : already_AddRefed<ServiceWorker>
     252           0 : ServiceWorkerInfo::GetOrCreateInstance(nsPIDOMWindowInner* aWindow)
     253             : {
     254           0 :   AssertIsOnMainThread();
     255           0 :   MOZ_ASSERT(aWindow);
     256             : 
     257           0 :   RefPtr<ServiceWorker> ref;
     258             : 
     259           0 :   for (uint32_t i = 0; i < mInstances.Length(); ++i) {
     260           0 :     MOZ_ASSERT(mInstances[i]);
     261           0 :     if (mInstances[i]->GetOwner() == aWindow) {
     262           0 :       ref = mInstances[i];
     263           0 :       break;
     264             :     }
     265             :   }
     266             : 
     267           0 :   if (!ref) {
     268           0 :     ref = new ServiceWorker(aWindow, this);
     269             :   }
     270             : 
     271           0 :   return ref.forget();
     272             : }
     273             : 
     274             : void
     275           0 : ServiceWorkerInfo::UpdateInstalledTime()
     276             : {
     277           0 :   MOZ_ASSERT(mState == ServiceWorkerState::Installed);
     278           0 :   MOZ_ASSERT(mInstalledTime == 0);
     279             : 
     280           0 :   mInstalledTime =
     281           0 :     mCreationTime + static_cast<PRTime>((TimeStamp::Now() -
     282           0 :                                          mCreationTimeStamp).ToMicroseconds());
     283           0 : }
     284             : 
     285             : void
     286           0 : ServiceWorkerInfo::UpdateActivatedTime()
     287             : {
     288           0 :   MOZ_ASSERT(mState == ServiceWorkerState::Activated);
     289           0 :   MOZ_ASSERT(mActivatedTime == 0);
     290             : 
     291           0 :   mActivatedTime =
     292           0 :     mCreationTime + static_cast<PRTime>((TimeStamp::Now() -
     293           0 :                                          mCreationTimeStamp).ToMicroseconds());
     294           0 : }
     295             : 
     296             : void
     297           0 : ServiceWorkerInfo::UpdateRedundantTime()
     298             : {
     299           0 :   MOZ_ASSERT(mState == ServiceWorkerState::Redundant);
     300           0 :   MOZ_ASSERT(mRedundantTime == 0);
     301             : 
     302           0 :   mRedundantTime =
     303           0 :     mCreationTime + static_cast<PRTime>((TimeStamp::Now() -
     304           0 :                                          mCreationTimeStamp).ToMicroseconds());
     305           0 : }
     306             : 
     307             : END_WORKERS_NAMESPACE

Generated by: LCOV version 1.13