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 "ServiceWorkerUnregisterJob.h"
8 :
9 : #include "nsIPushService.h"
10 :
11 : namespace mozilla {
12 : namespace dom {
13 : namespace workers {
14 :
15 : class ServiceWorkerUnregisterJob::PushUnsubscribeCallback final :
16 : public nsIUnsubscribeResultCallback
17 : {
18 : public:
19 : NS_DECL_ISUPPORTS
20 :
21 0 : explicit PushUnsubscribeCallback(ServiceWorkerUnregisterJob* aJob)
22 0 : : mJob(aJob)
23 : {
24 0 : AssertIsOnMainThread();
25 0 : }
26 :
27 : NS_IMETHOD
28 0 : OnUnsubscribe(nsresult aStatus, bool) override
29 : {
30 : // Warn if unsubscribing fails, but don't prevent the worker from
31 : // unregistering.
32 0 : Unused << NS_WARN_IF(NS_FAILED(aStatus));
33 0 : mJob->Unregister();
34 0 : return NS_OK;
35 : }
36 :
37 : private:
38 0 : ~PushUnsubscribeCallback()
39 0 : {
40 0 : }
41 :
42 : RefPtr<ServiceWorkerUnregisterJob> mJob;
43 : };
44 :
45 0 : NS_IMPL_ISUPPORTS(ServiceWorkerUnregisterJob::PushUnsubscribeCallback,
46 : nsIUnsubscribeResultCallback)
47 :
48 0 : ServiceWorkerUnregisterJob::ServiceWorkerUnregisterJob(nsIPrincipal* aPrincipal,
49 : const nsACString& aScope,
50 0 : bool aSendToParent)
51 0 : : ServiceWorkerJob(Type::Unregister, aPrincipal, aScope, EmptyCString())
52 : , mResult(false)
53 0 : , mSendToParent(aSendToParent)
54 : {
55 0 : }
56 :
57 : bool
58 0 : ServiceWorkerUnregisterJob::GetResult() const
59 : {
60 0 : AssertIsOnMainThread();
61 0 : return mResult;
62 : }
63 :
64 0 : ServiceWorkerUnregisterJob::~ServiceWorkerUnregisterJob()
65 : {
66 0 : }
67 :
68 : void
69 0 : ServiceWorkerUnregisterJob::AsyncExecute()
70 : {
71 0 : AssertIsOnMainThread();
72 :
73 0 : if (Canceled()) {
74 0 : Finish(NS_ERROR_DOM_ABORT_ERR);
75 0 : return;
76 : }
77 :
78 : // Push API, section 5: "When a service worker registration is unregistered,
79 : // any associated push subscription must be deactivated." To ensure the
80 : // service worker registration isn't cleared as we're unregistering, we
81 : // unsubscribe first.
82 : nsCOMPtr<nsIPushService> pushService =
83 0 : do_GetService("@mozilla.org/push/Service;1");
84 0 : if (NS_WARN_IF(!pushService)) {
85 0 : Unregister();
86 0 : return;
87 : }
88 : nsCOMPtr<nsIUnsubscribeResultCallback> unsubscribeCallback =
89 0 : new PushUnsubscribeCallback(this);
90 0 : nsresult rv = pushService->Unsubscribe(NS_ConvertUTF8toUTF16(mScope),
91 0 : mPrincipal, unsubscribeCallback);
92 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
93 0 : Unregister();
94 : }
95 : }
96 :
97 : void
98 0 : ServiceWorkerUnregisterJob::Unregister()
99 : {
100 0 : AssertIsOnMainThread();
101 :
102 0 : RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
103 0 : if (Canceled() || !swm) {
104 0 : Finish(NS_ERROR_DOM_ABORT_ERR);
105 0 : return;
106 : }
107 :
108 : // Step 1 of the Unregister algorithm requires checking that the
109 : // client origin matches the scope's origin. We perform this in
110 : // registration->update() method directly since we don't have that
111 : // client information available here.
112 :
113 : // "Let registration be the result of running [[Get Registration]]
114 : // algorithm passing scope as the argument."
115 : RefPtr<ServiceWorkerRegistrationInfo> registration =
116 0 : swm->GetRegistration(mPrincipal, mScope);
117 0 : if (!registration) {
118 : // "If registration is null, then, resolve promise with false."
119 0 : Finish(NS_OK);
120 0 : return;
121 : }
122 :
123 : // Note, we send the message to remove the registration from disk now even
124 : // though we may only set the mPendingUninstall flag below. This is
125 : // necessary to ensure the registration is removed if the controlled
126 : // clients are closed by shutting down the browser. If the registration
127 : // is resurrected by clearing mPendingUninstall then it should be saved
128 : // to disk again.
129 0 : if (mSendToParent && !registration->mPendingUninstall) {
130 0 : swm->MaybeSendUnregister(mPrincipal, mScope);
131 : }
132 :
133 : // "Set registration's uninstalling flag."
134 0 : registration->mPendingUninstall = true;
135 :
136 : // "Resolve promise with true"
137 0 : mResult = true;
138 0 : InvokeResultCallbacks(NS_OK);
139 :
140 : // "If no service worker client is using registration..."
141 0 : if (!registration->IsControllingDocuments() && registration->IsIdle()) {
142 : // "Invoke [[Clear Registration]]..."
143 0 : swm->RemoveRegistration(registration);
144 : }
145 :
146 0 : Finish(NS_OK);
147 : }
148 :
149 : } // namespace workers
150 : } // namespace dom
151 : } // namespace mozilla
|