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/. */
7 #include "ServiceWorkerUnregisterJob.h"
9 #include "mozilla/Unused.h"
10 #include "nsIPushService.h"
11 #include "nsServiceManagerUtils.h"
12 #include "nsThreadUtils.h"
13 #include "ServiceWorkerManager.h"
15 namespace mozilla::dom
{
17 class ServiceWorkerUnregisterJob::PushUnsubscribeCallback final
18 : public nsIUnsubscribeResultCallback
{
22 explicit PushUnsubscribeCallback(ServiceWorkerUnregisterJob
* aJob
)
24 MOZ_ASSERT(NS_IsMainThread());
28 OnUnsubscribe(nsresult aStatus
, bool) override
{
29 // Warn if unsubscribing fails, but don't prevent the worker from
31 Unused
<< NS_WARN_IF(NS_FAILED(aStatus
));
37 ~PushUnsubscribeCallback() = default;
39 RefPtr
<ServiceWorkerUnregisterJob
> mJob
;
42 NS_IMPL_ISUPPORTS(ServiceWorkerUnregisterJob::PushUnsubscribeCallback
,
43 nsIUnsubscribeResultCallback
)
45 ServiceWorkerUnregisterJob::ServiceWorkerUnregisterJob(nsIPrincipal
* aPrincipal
,
46 const nsACString
& aScope
)
47 : ServiceWorkerJob(Type::Unregister
, aPrincipal
, aScope
, ""_ns
),
50 bool ServiceWorkerUnregisterJob::GetResult() const {
51 MOZ_ASSERT(NS_IsMainThread());
55 ServiceWorkerUnregisterJob::~ServiceWorkerUnregisterJob() = default;
57 void ServiceWorkerUnregisterJob::AsyncExecute() {
58 MOZ_ASSERT(NS_IsMainThread());
61 Finish(NS_ERROR_DOM_ABORT_ERR
);
65 // Push API, section 5: "When a service worker registration is unregistered,
66 // any associated push subscription must be deactivated." To ensure the
67 // service worker registration isn't cleared as we're unregistering, we
69 nsCOMPtr
<nsIPushService
> pushService
=
70 do_GetService("@mozilla.org/push/Service;1");
71 if (NS_WARN_IF(!pushService
)) {
75 nsCOMPtr
<nsIUnsubscribeResultCallback
> unsubscribeCallback
=
76 new PushUnsubscribeCallback(this);
77 nsresult rv
= pushService
->Unsubscribe(NS_ConvertUTF8toUTF16(mScope
),
78 mPrincipal
, unsubscribeCallback
);
79 if (NS_WARN_IF(NS_FAILED(rv
))) {
84 void ServiceWorkerUnregisterJob::Unregister() {
85 MOZ_ASSERT(NS_IsMainThread());
87 RefPtr
<ServiceWorkerManager
> swm
= ServiceWorkerManager::GetInstance();
88 if (Canceled() || !swm
) {
89 Finish(NS_ERROR_DOM_ABORT_ERR
);
93 // Step 1 of the Unregister algorithm requires checking that the
94 // client origin matches the scope's origin. We perform this in
95 // registration->update() method directly since we don't have that
96 // client information available here.
98 // "Let registration be the result of running [[Get Registration]]
99 // algorithm passing scope as the argument."
100 RefPtr
<ServiceWorkerRegistrationInfo
> registration
=
101 swm
->GetRegistration(mPrincipal
, mScope
);
103 // "If registration is null, then, resolve promise with false."
108 // Note, we send the message to remove the registration from disk now. This is
109 // necessary to ensure the registration is removed if the controlled
110 // clients are closed by shutting down the browser.
111 swm
->MaybeSendUnregister(mPrincipal
, mScope
);
113 swm
->EvictFromBFCache(registration
);
115 // "Remove scope to registration map[job's scope url]."
116 swm
->RemoveRegistration(registration
);
117 MOZ_ASSERT(registration
->IsUnregistered());
119 // "Resolve promise with true"
121 InvokeResultCallbacks(NS_OK
);
123 // "Invoke Try Clear Registration with registration"
124 if (!registration
->IsControllingClients()) {
125 if (registration
->IsIdle()) {
126 registration
->Clear();
128 registration
->ClearWhenIdle();
135 } // namespace mozilla::dom