Bug 1494333 - index crons just like artifacts r=Callek
[gecko.git] / dom / serviceworkers / ServiceWorkerUnregisterJob.cpp
blobed8a1ef35bee9f6d79138daa72dfa56287a89f35
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 "nsThreadUtils.h"
12 #include "ServiceWorkerManager.h"
14 namespace mozilla {
15 namespace dom {
17 class ServiceWorkerUnregisterJob::PushUnsubscribeCallback final :
18 public nsIUnsubscribeResultCallback
20 public:
21 NS_DECL_ISUPPORTS
23 explicit PushUnsubscribeCallback(ServiceWorkerUnregisterJob* aJob)
24 : mJob(aJob)
26 MOZ_ASSERT(NS_IsMainThread());
29 NS_IMETHOD
30 OnUnsubscribe(nsresult aStatus, bool) override
32 // Warn if unsubscribing fails, but don't prevent the worker from
33 // unregistering.
34 Unused << NS_WARN_IF(NS_FAILED(aStatus));
35 mJob->Unregister();
36 return NS_OK;
39 private:
40 ~PushUnsubscribeCallback()
44 RefPtr<ServiceWorkerUnregisterJob> mJob;
47 NS_IMPL_ISUPPORTS(ServiceWorkerUnregisterJob::PushUnsubscribeCallback,
48 nsIUnsubscribeResultCallback)
50 ServiceWorkerUnregisterJob::ServiceWorkerUnregisterJob(nsIPrincipal* aPrincipal,
51 const nsACString& aScope,
52 bool aSendToParent)
53 : ServiceWorkerJob(Type::Unregister, aPrincipal, aScope, EmptyCString())
54 , mResult(false)
55 , mSendToParent(aSendToParent)
59 bool
60 ServiceWorkerUnregisterJob::GetResult() const
62 MOZ_ASSERT(NS_IsMainThread());
63 return mResult;
66 ServiceWorkerUnregisterJob::~ServiceWorkerUnregisterJob()
70 void
71 ServiceWorkerUnregisterJob::AsyncExecute()
73 MOZ_ASSERT(NS_IsMainThread());
75 if (Canceled()) {
76 Finish(NS_ERROR_DOM_ABORT_ERR);
77 return;
80 // Push API, section 5: "When a service worker registration is unregistered,
81 // any associated push subscription must be deactivated." To ensure the
82 // service worker registration isn't cleared as we're unregistering, we
83 // unsubscribe first.
84 nsCOMPtr<nsIPushService> pushService =
85 do_GetService("@mozilla.org/push/Service;1");
86 if (NS_WARN_IF(!pushService)) {
87 Unregister();
88 return;
90 nsCOMPtr<nsIUnsubscribeResultCallback> unsubscribeCallback =
91 new PushUnsubscribeCallback(this);
92 nsresult rv = pushService->Unsubscribe(NS_ConvertUTF8toUTF16(mScope),
93 mPrincipal, unsubscribeCallback);
94 if (NS_WARN_IF(NS_FAILED(rv))) {
95 Unregister();
99 void
100 ServiceWorkerUnregisterJob::Unregister()
102 MOZ_ASSERT(NS_IsMainThread());
104 RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
105 if (Canceled() || !swm) {
106 Finish(NS_ERROR_DOM_ABORT_ERR);
107 return;
110 // Step 1 of the Unregister algorithm requires checking that the
111 // client origin matches the scope's origin. We perform this in
112 // registration->update() method directly since we don't have that
113 // client information available here.
115 // "Let registration be the result of running [[Get Registration]]
116 // algorithm passing scope as the argument."
117 RefPtr<ServiceWorkerRegistrationInfo> registration =
118 swm->GetRegistration(mPrincipal, mScope);
119 if (!registration) {
120 // "If registration is null, then, resolve promise with false."
121 Finish(NS_OK);
122 return;
125 // Note, we send the message to remove the registration from disk now even
126 // though we may only set the pending uninstall flag below. This is
127 // necessary to ensure the registration is removed if the controlled
128 // clients are closed by shutting down the browser. If the registration
129 // is resurrected by clearing pending uninstall then it should be saved
130 // to disk again.
131 if (mSendToParent && !registration->IsPendingUninstall()) {
132 swm->MaybeSendUnregister(mPrincipal, mScope);
135 // "Set registration's uninstalling flag."
136 registration->SetPendingUninstall();
138 // "Resolve promise with true"
139 mResult = true;
140 InvokeResultCallbacks(NS_OK);
142 // "If no service worker client is using registration..."
143 if (!registration->IsControllingClients() && registration->IsIdle()) {
144 // "Invoke [[Clear Registration]]..."
145 swm->RemoveRegistration(registration);
148 Finish(NS_OK);
151 } // namespace dom
152 } // namespace mozilla