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 "ServiceWorkerRegistrationInfo.h"
8 :
9 : BEGIN_WORKERS_NAMESPACE
10 :
11 : namespace {
12 :
13 0 : class ContinueActivateRunnable final : public LifeCycleEventCallback
14 : {
15 : nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
16 : bool mSuccess;
17 :
18 : public:
19 0 : explicit ContinueActivateRunnable(const nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration)
20 0 : : mRegistration(aRegistration)
21 0 : , mSuccess(false)
22 : {
23 0 : AssertIsOnMainThread();
24 0 : }
25 :
26 : void
27 0 : SetResult(bool aResult) override
28 : {
29 0 : mSuccess = aResult;
30 0 : }
31 :
32 : NS_IMETHOD
33 0 : Run() override
34 : {
35 0 : AssertIsOnMainThread();
36 0 : mRegistration->FinishActivate(mSuccess);
37 0 : mRegistration = nullptr;
38 0 : return NS_OK;
39 : }
40 : };
41 :
42 : } // anonymous namespace
43 :
44 : void
45 0 : ServiceWorkerRegistrationInfo::Clear()
46 : {
47 0 : if (mEvaluatingWorker) {
48 0 : mEvaluatingWorker = nullptr;
49 : }
50 :
51 0 : UpdateRegistrationStateProperties(WhichServiceWorker::INSTALLING_WORKER |
52 0 : WhichServiceWorker::WAITING_WORKER |
53 0 : WhichServiceWorker::ACTIVE_WORKER, Invalidate);
54 :
55 0 : if (mInstallingWorker) {
56 0 : mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
57 0 : mInstallingWorker->UpdateRedundantTime();
58 0 : mInstallingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
59 0 : mInstallingWorker = nullptr;
60 : // FIXME(nsm): Abort any inflight requests from installing worker.
61 : }
62 :
63 0 : if (mWaitingWorker) {
64 0 : mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
65 0 : mWaitingWorker->UpdateRedundantTime();
66 0 : mWaitingWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
67 0 : mWaitingWorker = nullptr;
68 : }
69 :
70 0 : if (mActiveWorker) {
71 0 : mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
72 0 : mActiveWorker->UpdateRedundantTime();
73 0 : mActiveWorker->WorkerPrivate()->NoteDeadServiceWorkerInfo();
74 0 : mActiveWorker = nullptr;
75 : }
76 :
77 0 : NotifyChromeRegistrationListeners();
78 0 : }
79 :
80 0 : ServiceWorkerRegistrationInfo::ServiceWorkerRegistrationInfo(const nsACString& aScope,
81 : nsIPrincipal* aPrincipal,
82 0 : nsLoadFlags aLoadFlags)
83 : : mControlledDocumentsCounter(0)
84 : , mUpdateState(NoUpdate)
85 0 : , mCreationTime(PR_Now())
86 : , mCreationTimeStamp(TimeStamp::Now())
87 : , mLastUpdateTime(0)
88 : , mLoadFlags(aLoadFlags)
89 : , mScope(aScope)
90 : , mPrincipal(aPrincipal)
91 0 : , mPendingUninstall(false)
92 0 : {}
93 :
94 0 : ServiceWorkerRegistrationInfo::~ServiceWorkerRegistrationInfo()
95 : {
96 0 : if (IsControllingDocuments()) {
97 0 : NS_WARNING("ServiceWorkerRegistrationInfo is still controlling documents. This can be a bug or a leak in ServiceWorker API or in any other API that takes the document alive.");
98 : }
99 0 : }
100 :
101 0 : NS_IMPL_ISUPPORTS(ServiceWorkerRegistrationInfo, nsIServiceWorkerRegistrationInfo)
102 :
103 : NS_IMETHODIMP
104 0 : ServiceWorkerRegistrationInfo::GetPrincipal(nsIPrincipal** aPrincipal)
105 : {
106 0 : AssertIsOnMainThread();
107 0 : NS_ADDREF(*aPrincipal = mPrincipal);
108 0 : return NS_OK;
109 : }
110 :
111 : NS_IMETHODIMP
112 0 : ServiceWorkerRegistrationInfo::GetScope(nsAString& aScope)
113 : {
114 0 : AssertIsOnMainThread();
115 0 : CopyUTF8toUTF16(mScope, aScope);
116 0 : return NS_OK;
117 : }
118 :
119 : NS_IMETHODIMP
120 0 : ServiceWorkerRegistrationInfo::GetScriptSpec(nsAString& aScriptSpec)
121 : {
122 0 : AssertIsOnMainThread();
123 0 : RefPtr<ServiceWorkerInfo> newest = Newest();
124 0 : if (newest) {
125 0 : CopyUTF8toUTF16(newest->ScriptSpec(), aScriptSpec);
126 : }
127 0 : return NS_OK;
128 : }
129 :
130 : NS_IMETHODIMP
131 0 : ServiceWorkerRegistrationInfo::GetLastUpdateTime(PRTime* _retval)
132 : {
133 0 : AssertIsOnMainThread();
134 0 : MOZ_ASSERT(_retval);
135 0 : *_retval = mLastUpdateTime;
136 0 : return NS_OK;
137 : }
138 :
139 : NS_IMETHODIMP
140 0 : ServiceWorkerRegistrationInfo::GetInstallingWorker(nsIServiceWorkerInfo **aResult)
141 : {
142 0 : AssertIsOnMainThread();
143 0 : nsCOMPtr<nsIServiceWorkerInfo> info = do_QueryInterface(mInstallingWorker);
144 0 : info.forget(aResult);
145 0 : return NS_OK;
146 : }
147 :
148 : NS_IMETHODIMP
149 0 : ServiceWorkerRegistrationInfo::GetWaitingWorker(nsIServiceWorkerInfo **aResult)
150 : {
151 0 : AssertIsOnMainThread();
152 0 : nsCOMPtr<nsIServiceWorkerInfo> info = do_QueryInterface(mWaitingWorker);
153 0 : info.forget(aResult);
154 0 : return NS_OK;
155 : }
156 :
157 : NS_IMETHODIMP
158 0 : ServiceWorkerRegistrationInfo::GetActiveWorker(nsIServiceWorkerInfo **aResult)
159 : {
160 0 : AssertIsOnMainThread();
161 0 : nsCOMPtr<nsIServiceWorkerInfo> info = do_QueryInterface(mActiveWorker);
162 0 : info.forget(aResult);
163 0 : return NS_OK;
164 : }
165 :
166 : NS_IMETHODIMP
167 0 : ServiceWorkerRegistrationInfo::GetWorkerByID(uint64_t aID, nsIServiceWorkerInfo **aResult)
168 : {
169 0 : AssertIsOnMainThread();
170 0 : MOZ_ASSERT(aResult);
171 :
172 0 : RefPtr<ServiceWorkerInfo> info = GetServiceWorkerInfoById(aID);
173 : // It is ok to return null for a missing service worker info.
174 0 : info.forget(aResult);
175 0 : return NS_OK;
176 : }
177 :
178 : NS_IMETHODIMP
179 0 : ServiceWorkerRegistrationInfo::AddListener(
180 : nsIServiceWorkerRegistrationInfoListener *aListener)
181 : {
182 0 : AssertIsOnMainThread();
183 :
184 0 : if (!aListener || mListeners.Contains(aListener)) {
185 0 : return NS_ERROR_INVALID_ARG;
186 : }
187 :
188 0 : mListeners.AppendElement(aListener);
189 :
190 0 : return NS_OK;
191 : }
192 :
193 : NS_IMETHODIMP
194 0 : ServiceWorkerRegistrationInfo::RemoveListener(
195 : nsIServiceWorkerRegistrationInfoListener *aListener)
196 : {
197 0 : AssertIsOnMainThread();
198 :
199 0 : if (!aListener || !mListeners.Contains(aListener)) {
200 0 : return NS_ERROR_INVALID_ARG;
201 : }
202 :
203 0 : mListeners.RemoveElement(aListener);
204 :
205 0 : return NS_OK;
206 : }
207 :
208 : already_AddRefed<ServiceWorkerInfo>
209 0 : ServiceWorkerRegistrationInfo::GetServiceWorkerInfoById(uint64_t aId)
210 : {
211 0 : AssertIsOnMainThread();
212 :
213 0 : RefPtr<ServiceWorkerInfo> serviceWorker;
214 0 : if (mEvaluatingWorker && mEvaluatingWorker->ID() == aId) {
215 0 : serviceWorker = mEvaluatingWorker;
216 0 : } else if (mInstallingWorker && mInstallingWorker->ID() == aId) {
217 0 : serviceWorker = mInstallingWorker;
218 0 : } else if (mWaitingWorker && mWaitingWorker->ID() == aId) {
219 0 : serviceWorker = mWaitingWorker;
220 0 : } else if (mActiveWorker && mActiveWorker->ID() == aId) {
221 0 : serviceWorker = mActiveWorker;
222 : }
223 :
224 0 : return serviceWorker.forget();
225 : }
226 :
227 : void
228 0 : ServiceWorkerRegistrationInfo::TryToActivateAsync()
229 : {
230 0 : MOZ_ALWAYS_SUCCEEDS(
231 : NS_DispatchToMainThread(NewRunnableMethod("ServiceWorkerRegistrationInfo::TryToActivate",
232 : this,
233 : &ServiceWorkerRegistrationInfo::TryToActivate)));
234 0 : }
235 :
236 : /*
237 : * TryToActivate should not be called directly, use TryToActivateAsync instead.
238 : */
239 : void
240 0 : ServiceWorkerRegistrationInfo::TryToActivate()
241 : {
242 0 : AssertIsOnMainThread();
243 0 : bool controlling = IsControllingDocuments();
244 0 : bool skipWaiting = mWaitingWorker && mWaitingWorker->SkipWaitingFlag();
245 0 : bool idle = IsIdle();
246 0 : if (idle && (!controlling || skipWaiting)) {
247 0 : Activate();
248 : }
249 0 : }
250 :
251 : void
252 0 : ServiceWorkerRegistrationInfo::Activate()
253 : {
254 0 : if (!mWaitingWorker) {
255 0 : return;
256 : }
257 :
258 0 : RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
259 0 : if (!swm) {
260 : // browser shutdown began during async activation step
261 0 : return;
262 : }
263 :
264 0 : TransitionWaitingToActive();
265 :
266 : // FIXME(nsm): Unlink appcache if there is one.
267 :
268 : // "Queue a task to fire a simple event named controllerchange..."
269 : nsCOMPtr<nsIRunnable> controllerChangeRunnable =
270 0 : NewRunnableMethod<RefPtr<ServiceWorkerRegistrationInfo>>(
271 : "dom::workers::ServiceWorkerManager::FireControllerChange",
272 : swm,
273 : &ServiceWorkerManager::FireControllerChange,
274 0 : this);
275 0 : NS_DispatchToMainThread(controllerChangeRunnable);
276 :
277 0 : nsCOMPtr<nsIRunnable> failRunnable = NewRunnableMethod<bool>(
278 : "dom::workers::ServiceWorkerRegistrationInfo::FinishActivate",
279 : this,
280 : &ServiceWorkerRegistrationInfo::FinishActivate,
281 0 : false /* success */);
282 :
283 : nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> handle(
284 : new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(
285 0 : "ServiceWorkerRegistrationInfo", this));
286 0 : RefPtr<LifeCycleEventCallback> callback = new ContinueActivateRunnable(handle);
287 :
288 0 : ServiceWorkerPrivate* workerPrivate = mActiveWorker->WorkerPrivate();
289 0 : MOZ_ASSERT(workerPrivate);
290 0 : nsresult rv = workerPrivate->SendLifeCycleEvent(NS_LITERAL_STRING("activate"),
291 0 : callback, failRunnable);
292 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
293 0 : MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(failRunnable));
294 0 : return;
295 : }
296 : }
297 :
298 : void
299 0 : ServiceWorkerRegistrationInfo::FinishActivate(bool aSuccess)
300 : {
301 0 : if (mPendingUninstall || !mActiveWorker ||
302 0 : mActiveWorker->State() != ServiceWorkerState::Activating) {
303 0 : return;
304 : }
305 :
306 : // Activation never fails, so aSuccess is ignored.
307 0 : mActiveWorker->UpdateState(ServiceWorkerState::Activated);
308 0 : mActiveWorker->UpdateActivatedTime();
309 0 : NotifyChromeRegistrationListeners();
310 :
311 0 : RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
312 0 : if (!swm) {
313 : // browser shutdown started during async activation completion step
314 0 : return;
315 : }
316 0 : swm->StoreRegistration(mPrincipal, this);
317 : }
318 :
319 : void
320 0 : ServiceWorkerRegistrationInfo::RefreshLastUpdateCheckTime()
321 : {
322 0 : AssertIsOnMainThread();
323 :
324 0 : mLastUpdateTime =
325 0 : mCreationTime + static_cast<PRTime>((TimeStamp::Now() -
326 0 : mCreationTimeStamp).ToMicroseconds());
327 0 : NotifyChromeRegistrationListeners();
328 0 : }
329 :
330 : bool
331 0 : ServiceWorkerRegistrationInfo::IsLastUpdateCheckTimeOverOneDay() const
332 : {
333 0 : AssertIsOnMainThread();
334 :
335 : // For testing.
336 0 : if (Preferences::GetBool("dom.serviceWorkers.testUpdateOverOneDay")) {
337 0 : return true;
338 : }
339 :
340 0 : const int64_t kSecondsPerDay = 86400;
341 : const int64_t now =
342 0 : mCreationTime + static_cast<PRTime>((TimeStamp::Now() -
343 0 : mCreationTimeStamp).ToMicroseconds());
344 :
345 : // now < mLastUpdateTime if the system time is reset between storing
346 : // and loading mLastUpdateTime from ServiceWorkerRegistrar.
347 0 : if (now < mLastUpdateTime ||
348 0 : (now - mLastUpdateTime) / PR_MSEC_PER_SEC > kSecondsPerDay) {
349 0 : return true;
350 : }
351 0 : return false;
352 : }
353 :
354 : void
355 0 : ServiceWorkerRegistrationInfo::AsyncUpdateRegistrationStateProperties(WhichServiceWorker aWorker,
356 : TransitionType aTransition)
357 : {
358 0 : AssertIsOnMainThread();
359 0 : RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
360 0 : if (!swm) {
361 : // browser shutdown started during this async step
362 0 : return;
363 : }
364 :
365 0 : if (aTransition == Invalidate) {
366 0 : swm->InvalidateServiceWorkerRegistrationWorker(this, aWorker);
367 : } else {
368 0 : MOZ_ASSERT(aTransition == TransitionToNextState);
369 0 : swm->TransitionServiceWorkerRegistrationWorker(this, aWorker);
370 :
371 0 : if (aWorker == WhichServiceWorker::WAITING_WORKER) {
372 0 : swm->CheckPendingReadyPromises();
373 : }
374 : }
375 : }
376 :
377 : void
378 0 : ServiceWorkerRegistrationInfo::UpdateRegistrationStateProperties(WhichServiceWorker aWorker,
379 : TransitionType aTransition)
380 : {
381 0 : AssertIsOnMainThread();
382 :
383 : nsCOMPtr<nsIRunnable> runnable =
384 0 : NewRunnableMethod<WhichServiceWorker, TransitionType>(
385 : "dom::workers::ServiceWorkerRegistrationInfo::"
386 : "AsyncUpdateRegistrationStateProperties",
387 : this,
388 : &ServiceWorkerRegistrationInfo::AsyncUpdateRegistrationStateProperties,
389 : aWorker,
390 0 : aTransition);
391 0 : MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable.forget()));
392 0 : }
393 :
394 : void
395 0 : ServiceWorkerRegistrationInfo::NotifyChromeRegistrationListeners()
396 : {
397 0 : nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> listeners(mListeners);
398 0 : for (size_t index = 0; index < listeners.Length(); ++index) {
399 0 : listeners[index]->OnChange();
400 : }
401 0 : }
402 :
403 : void
404 0 : ServiceWorkerRegistrationInfo::MaybeScheduleTimeCheckAndUpdate()
405 : {
406 0 : AssertIsOnMainThread();
407 :
408 0 : RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
409 0 : if (!swm) {
410 : // shutting down, do nothing
411 0 : return;
412 : }
413 :
414 0 : if (mUpdateState == NoUpdate) {
415 0 : mUpdateState = NeedTimeCheckAndUpdate;
416 : }
417 :
418 0 : swm->ScheduleUpdateTimer(mPrincipal, mScope);
419 : }
420 :
421 : void
422 0 : ServiceWorkerRegistrationInfo::MaybeScheduleUpdate()
423 : {
424 0 : AssertIsOnMainThread();
425 :
426 0 : RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
427 0 : if (!swm) {
428 : // shutting down, do nothing
429 0 : return;
430 : }
431 :
432 0 : mUpdateState = NeedUpdate;
433 :
434 0 : swm->ScheduleUpdateTimer(mPrincipal, mScope);
435 : }
436 :
437 : bool
438 0 : ServiceWorkerRegistrationInfo::CheckAndClearIfUpdateNeeded()
439 : {
440 0 : AssertIsOnMainThread();
441 :
442 0 : bool result = mUpdateState == NeedUpdate ||
443 0 : (mUpdateState == NeedTimeCheckAndUpdate &&
444 0 : IsLastUpdateCheckTimeOverOneDay());
445 :
446 0 : mUpdateState = NoUpdate;
447 :
448 0 : return result;
449 : }
450 :
451 : ServiceWorkerInfo*
452 0 : ServiceWorkerRegistrationInfo::GetEvaluating() const
453 : {
454 0 : AssertIsOnMainThread();
455 0 : return mEvaluatingWorker;
456 : }
457 :
458 : ServiceWorkerInfo*
459 0 : ServiceWorkerRegistrationInfo::GetInstalling() const
460 : {
461 0 : AssertIsOnMainThread();
462 0 : return mInstallingWorker;
463 : }
464 :
465 : ServiceWorkerInfo*
466 0 : ServiceWorkerRegistrationInfo::GetWaiting() const
467 : {
468 0 : AssertIsOnMainThread();
469 0 : return mWaitingWorker;
470 : }
471 :
472 : ServiceWorkerInfo*
473 0 : ServiceWorkerRegistrationInfo::GetActive() const
474 : {
475 0 : AssertIsOnMainThread();
476 0 : return mActiveWorker;
477 : }
478 :
479 : ServiceWorkerInfo*
480 0 : ServiceWorkerRegistrationInfo::GetByID(uint64_t aID) const
481 : {
482 0 : if (mActiveWorker && mActiveWorker->ID() == aID) {
483 0 : return mActiveWorker;
484 : }
485 0 : if (mWaitingWorker && mWaitingWorker->ID() == aID) {
486 0 : return mWaitingWorker;
487 : }
488 0 : if (mInstallingWorker && mInstallingWorker->ID() == aID) {
489 0 : return mInstallingWorker;
490 : }
491 0 : if (mEvaluatingWorker && mEvaluatingWorker->ID() == aID) {
492 0 : return mEvaluatingWorker;
493 : }
494 0 : return nullptr;
495 : }
496 :
497 : void
498 0 : ServiceWorkerRegistrationInfo::SetEvaluating(ServiceWorkerInfo* aServiceWorker)
499 : {
500 0 : AssertIsOnMainThread();
501 0 : MOZ_ASSERT(aServiceWorker);
502 0 : MOZ_ASSERT(!mEvaluatingWorker);
503 0 : MOZ_ASSERT(!mInstallingWorker);
504 0 : MOZ_ASSERT(mWaitingWorker != aServiceWorker);
505 0 : MOZ_ASSERT(mActiveWorker != aServiceWorker);
506 :
507 0 : mEvaluatingWorker = aServiceWorker;
508 0 : }
509 :
510 : void
511 0 : ServiceWorkerRegistrationInfo::ClearEvaluating()
512 : {
513 0 : AssertIsOnMainThread();
514 :
515 0 : if (!mEvaluatingWorker) {
516 0 : return;
517 : }
518 :
519 0 : mEvaluatingWorker->UpdateState(ServiceWorkerState::Redundant);
520 : // We don't update the redundant time for the sw here, since we've not expose
521 : // evalutingWorker yet.
522 0 : mEvaluatingWorker = nullptr;
523 : }
524 :
525 : void
526 0 : ServiceWorkerRegistrationInfo::ClearInstalling()
527 : {
528 0 : AssertIsOnMainThread();
529 :
530 0 : if (!mInstallingWorker) {
531 0 : return;
532 : }
533 :
534 : UpdateRegistrationStateProperties(WhichServiceWorker::INSTALLING_WORKER,
535 0 : Invalidate);
536 0 : mInstallingWorker->UpdateState(ServiceWorkerState::Redundant);
537 0 : mInstallingWorker->UpdateRedundantTime();
538 0 : mInstallingWorker = nullptr;
539 :
540 0 : NotifyChromeRegistrationListeners();
541 : }
542 :
543 : void
544 0 : ServiceWorkerRegistrationInfo::TransitionEvaluatingToInstalling()
545 : {
546 0 : AssertIsOnMainThread();
547 0 : MOZ_ASSERT(mEvaluatingWorker);
548 0 : MOZ_ASSERT(!mInstallingWorker);
549 :
550 0 : mInstallingWorker = mEvaluatingWorker.forget();
551 0 : mInstallingWorker->UpdateState(ServiceWorkerState::Installing);
552 0 : NotifyChromeRegistrationListeners();
553 0 : }
554 :
555 : void
556 0 : ServiceWorkerRegistrationInfo::TransitionInstallingToWaiting()
557 : {
558 0 : AssertIsOnMainThread();
559 0 : MOZ_ASSERT(mInstallingWorker);
560 :
561 0 : if (mWaitingWorker) {
562 0 : MOZ_ASSERT(mInstallingWorker->CacheName() != mWaitingWorker->CacheName());
563 0 : mWaitingWorker->UpdateState(ServiceWorkerState::Redundant);
564 0 : mWaitingWorker->UpdateRedundantTime();
565 : }
566 :
567 0 : mWaitingWorker = mInstallingWorker.forget();
568 : UpdateRegistrationStateProperties(WhichServiceWorker::INSTALLING_WORKER,
569 0 : TransitionToNextState);
570 0 : mWaitingWorker->UpdateState(ServiceWorkerState::Installed);
571 0 : mWaitingWorker->UpdateInstalledTime();
572 0 : NotifyChromeRegistrationListeners();
573 :
574 0 : RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
575 0 : if (!swm) {
576 : // browser shutdown began
577 0 : return;
578 : }
579 0 : swm->StoreRegistration(mPrincipal, this);
580 : }
581 :
582 : void
583 0 : ServiceWorkerRegistrationInfo::SetActive(ServiceWorkerInfo* aServiceWorker)
584 : {
585 0 : AssertIsOnMainThread();
586 0 : MOZ_ASSERT(aServiceWorker);
587 :
588 : // TODO: Assert installing, waiting, and active are nullptr once the SWM
589 : // moves to the parent process. After that happens this code will
590 : // only run for browser initialization and not for cross-process
591 : // overrides.
592 0 : MOZ_ASSERT(mInstallingWorker != aServiceWorker);
593 0 : MOZ_ASSERT(mWaitingWorker != aServiceWorker);
594 0 : MOZ_ASSERT(mActiveWorker != aServiceWorker);
595 :
596 0 : if (mActiveWorker) {
597 0 : MOZ_ASSERT(aServiceWorker->CacheName() != mActiveWorker->CacheName());
598 0 : mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
599 0 : mActiveWorker->UpdateRedundantTime();
600 : }
601 :
602 : // The active worker is being overriden due to initial load or
603 : // another process activating a worker. Move straight to the
604 : // Activated state.
605 0 : mActiveWorker = aServiceWorker;
606 0 : mActiveWorker->SetActivateStateUncheckedWithoutEvent(ServiceWorkerState::Activated);
607 : // We don't need to update activated time when we load registration from
608 : // registrar.
609 0 : UpdateRegistrationStateProperties(WhichServiceWorker::ACTIVE_WORKER, Invalidate);
610 0 : NotifyChromeRegistrationListeners();
611 0 : }
612 :
613 : void
614 0 : ServiceWorkerRegistrationInfo::TransitionWaitingToActive()
615 : {
616 0 : AssertIsOnMainThread();
617 0 : MOZ_ASSERT(mWaitingWorker);
618 :
619 0 : if (mActiveWorker) {
620 0 : MOZ_ASSERT(mWaitingWorker->CacheName() != mActiveWorker->CacheName());
621 0 : mActiveWorker->UpdateState(ServiceWorkerState::Redundant);
622 0 : mActiveWorker->UpdateRedundantTime();
623 : }
624 :
625 : // We are transitioning from waiting to active normally, so go to
626 : // the activating state.
627 0 : mActiveWorker = mWaitingWorker.forget();
628 : UpdateRegistrationStateProperties(WhichServiceWorker::WAITING_WORKER,
629 0 : TransitionToNextState);
630 0 : mActiveWorker->UpdateState(ServiceWorkerState::Activating);
631 0 : NotifyChromeRegistrationListeners();
632 0 : }
633 :
634 : bool
635 0 : ServiceWorkerRegistrationInfo::IsIdle() const
636 : {
637 0 : return !mActiveWorker || mActiveWorker->WorkerPrivate()->IsIdle();
638 : }
639 :
640 : nsLoadFlags
641 0 : ServiceWorkerRegistrationInfo::GetLoadFlags() const
642 : {
643 0 : return mLoadFlags;
644 : }
645 :
646 : void
647 0 : ServiceWorkerRegistrationInfo::SetLoadFlags(nsLoadFlags aLoadFlags)
648 : {
649 0 : mLoadFlags = aLoadFlags;
650 0 : }
651 :
652 : int64_t
653 0 : ServiceWorkerRegistrationInfo::GetLastUpdateTime() const
654 : {
655 0 : return mLastUpdateTime;
656 : }
657 :
658 : void
659 0 : ServiceWorkerRegistrationInfo::SetLastUpdateTime(const int64_t aTime)
660 : {
661 0 : if (aTime == 0) {
662 0 : return;
663 : }
664 :
665 0 : mLastUpdateTime = aTime;
666 : }
667 :
668 : END_WORKERS_NAMESPACE
|