Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/serviceworkers/RemoteServiceWorkerContainerImpl.cpp
Line
Count
Source (jump to first uncovered line)
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 "RemoteServiceWorkerContainerImpl.h"
8
9
#include "mozilla/ipc/BackgroundChild.h"
10
#include "mozilla/ipc/PBackgroundChild.h"
11
#include "ServiceWorkerContainerChild.h"
12
13
namespace mozilla {
14
namespace dom {
15
16
using mozilla::ipc::BackgroundChild;
17
using mozilla::ipc::PBackgroundChild;
18
using mozilla::ipc::ResponseRejectReason;
19
20
RemoteServiceWorkerContainerImpl::~RemoteServiceWorkerContainerImpl()
21
0
{
22
0
  Shutdown();
23
0
  MOZ_DIAGNOSTIC_ASSERT(!mOuter);
24
0
}
25
26
void
27
RemoteServiceWorkerContainerImpl::Shutdown()
28
0
{
29
0
  if (mShutdown) {
30
0
    return;
31
0
  }
32
0
  mShutdown = true;
33
0
34
0
  if (mActor) {
35
0
    mActor->RevokeOwner(this);
36
0
    mActor->MaybeStartTeardown();
37
0
    mActor = nullptr;
38
0
  }
39
0
}
40
41
void
42
RemoteServiceWorkerContainerImpl::AddContainer(ServiceWorkerContainer* aOuter)
43
0
{
44
0
  MOZ_DIAGNOSTIC_ASSERT(aOuter);
45
0
  MOZ_DIAGNOSTIC_ASSERT(!mOuter);
46
0
  mOuter = aOuter;
47
0
}
48
49
void
50
RemoteServiceWorkerContainerImpl::RemoveContainer(ServiceWorkerContainer* aOuter)
51
0
{
52
0
  MOZ_DIAGNOSTIC_ASSERT(aOuter);
53
0
  MOZ_DIAGNOSTIC_ASSERT(mOuter == aOuter);
54
0
  mOuter = nullptr;
55
0
}
56
57
void
58
RemoteServiceWorkerContainerImpl::Register(const ClientInfo& aClientInfo,
59
                                           const nsACString& aScopeURL,
60
                                           const nsACString& aScriptURL,
61
                                           ServiceWorkerUpdateViaCache aUpdateViaCache,
62
                                           ServiceWorkerRegistrationCallback&& aSuccessCB,
63
                                           ServiceWorkerFailureCallback&& aFailureCB) const
64
0
{
65
0
  if (!mActor) {
66
0
    aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
67
0
    return;
68
0
  }
69
0
70
0
  mActor->SendRegister(
71
0
    aClientInfo.ToIPC(), nsCString(aScopeURL), nsCString(aScriptURL),
72
0
    aUpdateViaCache,
73
0
    [successCB = std::move(aSuccessCB), aFailureCB]
74
0
    (const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult& aResult) {
75
0
      if (aResult.type() == IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::TCopyableErrorResult) {
76
0
        // application layer error
77
0
        auto& rv = aResult.get_CopyableErrorResult();
78
0
        MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
79
0
        aFailureCB(CopyableErrorResult(rv));
80
0
        return;
81
0
      }
82
0
      // success
83
0
      auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
84
0
      successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
85
0
    }, [aFailureCB] (ResponseRejectReason aReason) {
86
0
      // IPC layer error
87
0
      aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
88
0
    });
89
0
}
90
91
void
92
RemoteServiceWorkerContainerImpl::GetRegistration(const ClientInfo& aClientInfo,
93
                                                  const nsACString& aURL,
94
                                                  ServiceWorkerRegistrationCallback&& aSuccessCB,
95
                                                  ServiceWorkerFailureCallback&& aFailureCB) const
96
0
{
97
0
  if (!mActor) {
98
0
    aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
99
0
    return;
100
0
  }
101
0
102
0
  mActor->SendGetRegistration(aClientInfo.ToIPC(), nsCString(aURL),
103
0
    [successCB = std::move(aSuccessCB), aFailureCB]
104
0
    (const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult& aResult) {
105
0
      if (aResult.type() == IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::TCopyableErrorResult) {
106
0
        auto& rv = aResult.get_CopyableErrorResult();
107
0
        // If rv is a failure then this is an application layer error.  Note,
108
0
        // though, we also reject with NS_OK to indicate that we just didn't
109
0
        // find a registration.
110
0
        aFailureCB(CopyableErrorResult(rv));
111
0
        return;
112
0
      }
113
0
      // success
114
0
      auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
115
0
      successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
116
0
    }, [aFailureCB] (ResponseRejectReason aReason) {
117
0
      // IPC layer error
118
0
      aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
119
0
    });
120
0
}
121
122
void
123
RemoteServiceWorkerContainerImpl::GetRegistrations(const ClientInfo& aClientInfo,
124
                                                   ServiceWorkerRegistrationListCallback&& aSuccessCB,
125
                                                   ServiceWorkerFailureCallback&& aFailureCB) const
126
0
{
127
0
  if (!mActor) {
128
0
    aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
129
0
    return;
130
0
  }
131
0
132
0
  mActor->SendGetRegistrations(aClientInfo.ToIPC(),
133
0
   [successCB = std::move(aSuccessCB), aFailureCB]
134
0
   (const IPCServiceWorkerRegistrationDescriptorListOrCopyableErrorResult& aResult) {
135
0
      if (aResult.type() == IPCServiceWorkerRegistrationDescriptorListOrCopyableErrorResult::TCopyableErrorResult) {
136
0
        // application layer error
137
0
        auto& rv = aResult.get_CopyableErrorResult();
138
0
        MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
139
0
        aFailureCB(CopyableErrorResult(rv));
140
0
        return;
141
0
      }
142
0
      // success
143
0
      auto& ipcList = aResult.get_IPCServiceWorkerRegistrationDescriptorList();
144
0
      nsTArray<ServiceWorkerRegistrationDescriptor> list(ipcList.values().Length());
145
0
      for (auto& ipcDesc : ipcList.values()) {
146
0
        list.AppendElement(ServiceWorkerRegistrationDescriptor(ipcDesc));
147
0
      }
148
0
      successCB(std::move(list));
149
0
    }, [aFailureCB] (ResponseRejectReason aReason) {
150
0
      // IPC layer error
151
0
      aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
152
0
    });
153
0
}
154
155
void
156
RemoteServiceWorkerContainerImpl::GetReady(const ClientInfo& aClientInfo,
157
                                           ServiceWorkerRegistrationCallback&& aSuccessCB,
158
                                           ServiceWorkerFailureCallback&& aFailureCB) const
159
0
{
160
0
  if (!mActor) {
161
0
    aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
162
0
    return;
163
0
  }
164
0
165
0
  mActor->SendGetReady(aClientInfo.ToIPC(),
166
0
    [successCB = std::move(aSuccessCB), aFailureCB]
167
0
    (const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult& aResult) {
168
0
      if (aResult.type() == IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::TCopyableErrorResult) {
169
0
        // application layer error
170
0
        auto& rv = aResult.get_CopyableErrorResult();
171
0
        MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
172
0
        aFailureCB(CopyableErrorResult(rv));
173
0
        return;
174
0
      }
175
0
      // success
176
0
      auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
177
0
      successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
178
0
    }, [aFailureCB] (ResponseRejectReason aReason) {
179
0
      // IPC layer error
180
0
      aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
181
0
    });
182
0
}
183
184
RemoteServiceWorkerContainerImpl::RemoteServiceWorkerContainerImpl()
185
  : mActor(nullptr)
186
  , mOuter(nullptr)
187
  , mShutdown(false)
188
0
{
189
0
  PBackgroundChild* parentActor = BackgroundChild::GetOrCreateForCurrentThread();
190
0
  if (NS_WARN_IF(!parentActor)) {
191
0
    Shutdown();
192
0
    return;
193
0
  }
194
0
195
0
  RefPtr<WorkerHolderToken> workerHolderToken;
196
0
  if (!NS_IsMainThread()) {
197
0
    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
198
0
    MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
199
0
200
0
    workerHolderToken =
201
0
      WorkerHolderToken::Create(workerPrivate, Canceling,
202
0
                                WorkerHolderToken::AllowIdleShutdownStart);
203
0
204
0
    if (NS_WARN_IF(!workerHolderToken)) {
205
0
      Shutdown();
206
0
      return;
207
0
    }
208
0
  }
209
0
210
0
  ServiceWorkerContainerChild* actor =
211
0
    new ServiceWorkerContainerChild(workerHolderToken);
212
0
  PServiceWorkerContainerChild* sentActor =
213
0
    parentActor->SendPServiceWorkerContainerConstructor(actor);
214
0
  if (NS_WARN_IF(!sentActor)) {
215
0
    Shutdown();
216
0
    return;
217
0
  }
218
0
  MOZ_DIAGNOSTIC_ASSERT(sentActor == actor);
219
0
220
0
  mActor = actor;
221
0
  mActor->SetOwner(this);
222
0
}
223
224
void
225
RemoteServiceWorkerContainerImpl::RevokeActor(ServiceWorkerContainerChild* aActor)
226
0
{
227
0
  MOZ_DIAGNOSTIC_ASSERT(mActor);
228
0
  MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
229
0
  mActor->RevokeOwner(this);
230
0
  mActor = nullptr;
231
0
232
0
  mShutdown = true;
233
0
}
234
235
} // namespace dom
236
} // namespace mozilla