void
ServiceWorkerRegistrationInfo::SetActive(ServiceWorkerInfo* aServiceWorker)
{
  AssertIsOnMainThread();
  MOZ_ASSERT(aServiceWorker);

  // TODO: Assert installing, waiting, and active are nullptr once the SWM
  //       moves to the parent process.  After that happens this code will
  //       only run for browser initialization and not for cross-process
  //       overrides.
  MOZ_ASSERT(mInstallingWorker != aServiceWorker);
  MOZ_ASSERT(mWaitingWorker != aServiceWorker);
  MOZ_ASSERT(mActiveWorker != aServiceWorker);

  if (mActiveWorker) {
    MOZ_ASSERT(aServiceWorker->CacheName() != mActiveWorker->CacheName());
    mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
  }

  // The active worker is being overriden due to initial load or
  // another process activating a worker.  Move straight to the
  // Activated state.
  mActiveWorker = aServiceWorker;
  mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
  NotifyListenersOnChange(WhichServiceWorker::ACTIVE_WORKER);
}
void
ServiceWorkerRegistrationInfo::Clear()
{
  if (mEvaluatingWorker) {
    mEvaluatingWorker = nullptr;
  }

  if (mInstallingWorker) {
    mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
    mInstallingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
    mInstallingWorker = nullptr;
    // FIXME(nsm): Abort any inflight requests from installing worker.
  }

  if (mWaitingWorker) {
    mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
    mWaitingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
    mWaitingWorker = nullptr;
  }

  if (mActiveWorker) {
    mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
    mActiveWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
    mActiveWorker = nullptr;
  }

  NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER |
                          WhichServiceWorker::WAITING_WORKER |
                          WhichServiceWorker::ACTIVE_WORKER);
}
void
ServiceWorkerRegistrationInfo::TransitionEvaluatingToInstalling()
{
  AssertIsOnMainThread();
  MOZ_ASSERT(mEvaluatingWorker);
  MOZ_ASSERT(!mInstallingWorker);

  mInstallingWorker = mEvaluatingWorker.forget();
  mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
  NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER);
}
void
ServiceWorkerRegistrationInfo::ClearInstalling()
{
  AssertIsOnMainThread();

  if (!mInstallingWorker) {
    return;
  }

  mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
  mInstallingWorker = nullptr;
  NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER);
}
void
ServiceWorkerRegistrationInfo::SetInstalling(ServiceWorkerInfo* aServiceWorker)
{
  AssertIsOnMainThread();
  MOZ_ASSERT(aServiceWorker);
  MOZ_ASSERT(!mInstallingWorker);
  MOZ_ASSERT(mWaitingWorker != aServiceWorker);
  MOZ_ASSERT(mActiveWorker != aServiceWorker);

  mInstallingWorker = aServiceWorker;
  mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
  NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER);
}
void
ServiceWorkerRegistrationInfo::TransitionWaitingToActive()
{
  AssertIsOnMainThread();
  MOZ_ASSERT(mWaitingWorker);

  if (mActiveWorker) {
    MOZ_ASSERT(mWaitingWorker->CacheName() != mActiveWorker->CacheName());
    mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
  }

  // We are transitioning from waiting to active normally, so go to
  // the activating state.
  mActiveWorker = mWaitingWorker.forget();
  mActiveWorker->UpdateState(ServiceWorkerState::Activating);
  NotifyListenersOnChange(WhichServiceWorker::WAITING_WORKER |
                          WhichServiceWorker::ACTIVE_WORKER);
}
void
ServiceWorkerRegistrationInfo::TransitionInstallingToWaiting()
{
  AssertIsOnMainThread();
  MOZ_ASSERT(mInstallingWorker);

  if (mWaitingWorker) {
    MOZ_ASSERT(mInstallingWorker->CacheName() != mWaitingWorker->CacheName());
    mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
  }

  mWaitingWorker = mInstallingWorker.forget();
  mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
  NotifyListenersOnChange(WhichServiceWorker::INSTALLING_WORKER |
                          WhichServiceWorker::WAITING_WORKER);

  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
  swm->StoreRegistration(mPrincipal, this);
}