Source code

Revision control

Other Tools

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