Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/clients/manager/ClientHandle.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 "ClientHandle.h"
8
9
#include "ClientHandleChild.h"
10
#include "ClientHandleOpChild.h"
11
#include "ClientManager.h"
12
#include "ClientPrincipalUtils.h"
13
#include "ClientState.h"
14
#include "mozilla/dom/PClientManagerChild.h"
15
#include "mozilla/dom/ServiceWorkerDescriptor.h"
16
#include "mozilla/dom/ipc/StructuredCloneData.h"
17
18
namespace mozilla {
19
namespace dom {
20
21
using mozilla::dom::ipc::StructuredCloneData;
22
23
ClientHandle::~ClientHandle()
24
0
{
25
0
  Shutdown();
26
0
}
27
28
void
29
ClientHandle::Shutdown()
30
0
{
31
0
  NS_ASSERT_OWNINGTHREAD(ClientSource);
32
0
  if (IsShutdown()) {
33
0
    return;
34
0
  }
35
0
36
0
  ShutdownThing();
37
0
38
0
  mManager = nullptr;
39
0
}
40
41
void
42
ClientHandle::StartOp(const ClientOpConstructorArgs& aArgs,
43
                      const ClientOpCallback&& aResolveCallback,
44
                      const ClientOpCallback&& aRejectCallback)
45
0
{
46
0
  // Hold a ref to the client until the remote operation completes.  Otherwise
47
0
  // the ClientHandle might get de-refed and teardown the actor before we
48
0
  // get an answer.
49
0
  RefPtr<ClientHandle> kungFuGrip = this;
50
0
51
0
  MaybeExecute([aArgs, kungFuGrip, aRejectCallback,
52
0
                resolve = std::move(aResolveCallback)] (ClientHandleChild* aActor) {
53
0
    MOZ_DIAGNOSTIC_ASSERT(aActor);
54
0
    ClientHandleOpChild* actor =
55
0
      new ClientHandleOpChild(kungFuGrip, aArgs, std::move(resolve),
56
0
                              std::move(aRejectCallback));
57
0
    if (!aActor->SendPClientHandleOpConstructor(actor, aArgs)) {
58
0
      // Constructor failure will call reject callback via ActorDestroy()
59
0
      return;
60
0
    }
61
0
  }, [aRejectCallback] {
62
0
    MOZ_DIAGNOSTIC_ASSERT(aRejectCallback);
63
0
    aRejectCallback(NS_ERROR_DOM_INVALID_STATE_ERR);
64
0
  });
65
0
}
66
67
void
68
ClientHandle::OnShutdownThing()
69
0
{
70
0
  NS_ASSERT_OWNINGTHREAD(ClientHandle);
71
0
  if (!mDetachPromise) {
72
0
    return;
73
0
  }
74
0
  mDetachPromise->Resolve(true, __func__);
75
0
}
76
77
ClientHandle::ClientHandle(ClientManager* aManager,
78
                           nsISerialEventTarget* aSerialEventTarget,
79
                           const ClientInfo& aClientInfo)
80
  : mManager(aManager)
81
  , mSerialEventTarget(aSerialEventTarget)
82
  , mClientInfo(aClientInfo)
83
0
{
84
0
  MOZ_DIAGNOSTIC_ASSERT(mManager);
85
0
  MOZ_DIAGNOSTIC_ASSERT(mSerialEventTarget);
86
0
  MOZ_ASSERT(mSerialEventTarget->IsOnCurrentThread());
87
0
}
88
89
void
90
ClientHandle::Activate(PClientManagerChild* aActor)
91
0
{
92
0
  NS_ASSERT_OWNINGTHREAD(ClientHandle);
93
0
94
0
  if (IsShutdown()) {
95
0
    return;
96
0
  }
97
0
98
0
  PClientHandleChild* actor =
99
0
    aActor->SendPClientHandleConstructor(mClientInfo.ToIPC());
100
0
  if (!actor) {
101
0
    Shutdown();
102
0
    return;
103
0
  }
104
0
105
0
  ActivateThing(static_cast<ClientHandleChild*>(actor));
106
0
}
107
108
void
109
ClientHandle::ExecutionReady(const ClientInfo& aClientInfo)
110
0
{
111
0
  mClientInfo = aClientInfo;
112
0
}
113
114
const ClientInfo&
115
ClientHandle::Info() const
116
0
{
117
0
  return mClientInfo;
118
0
}
119
120
RefPtr<GenericPromise>
121
ClientHandle::Control(const ServiceWorkerDescriptor& aServiceWorker)
122
0
{
123
0
  RefPtr<GenericPromise::Private> outerPromise =
124
0
    new GenericPromise::Private(__func__);
125
0
126
0
  // We should never have a cross-origin controller.  Since this would be
127
0
  // same-origin policy violation we do a full release assertion here.
128
0
  MOZ_RELEASE_ASSERT(ClientMatchPrincipalInfo(mClientInfo.PrincipalInfo(),
129
0
                                              aServiceWorker.PrincipalInfo()));
130
0
131
0
  StartOp(ClientControlledArgs(aServiceWorker.ToIPC()),
132
0
    [outerPromise](const ClientOpResult& aResult) {
133
0
      outerPromise->Resolve(true, __func__);
134
0
    },
135
0
    [outerPromise](const ClientOpResult& aResult) {
136
0
      outerPromise->Reject(aResult.get_nsresult(), __func__);
137
0
    });
138
0
139
0
  return outerPromise.forget();
140
0
}
141
142
RefPtr<ClientStatePromise>
143
ClientHandle::Focus()
144
0
{
145
0
  RefPtr<ClientStatePromise::Private> outerPromise =
146
0
    new ClientStatePromise::Private(__func__);
147
0
148
0
  StartOp(ClientFocusArgs(),
149
0
    [outerPromise](const ClientOpResult& aResult) {
150
0
      outerPromise->Resolve(ClientState::FromIPC(aResult.get_IPCClientState()), __func__);
151
0
    }, [outerPromise](const ClientOpResult& aResult) {
152
0
      outerPromise->Reject(aResult.get_nsresult(), __func__);
153
0
    });
154
0
155
0
  RefPtr<ClientStatePromise> ref = outerPromise.get();
156
0
  return ref.forget();
157
0
}
158
159
RefPtr<GenericPromise>
160
ClientHandle::PostMessage(StructuredCloneData& aData,
161
                          const ServiceWorkerDescriptor& aSource)
162
0
{
163
0
  RefPtr<GenericPromise> ref;
164
0
165
0
  if (IsShutdown()) {
166
0
    ref = GenericPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
167
0
    return ref.forget();
168
0
  }
169
0
170
0
  ClientPostMessageArgs args;
171
0
  args.serviceWorker() = aSource.ToIPC();
172
0
173
0
  if (!aData.BuildClonedMessageDataForBackgroundChild(GetActor()->Manager()->Manager(),
174
0
                                                      args.clonedData())) {
175
0
    ref = GenericPromise::CreateAndReject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__);
176
0
    return ref.forget();
177
0
  }
178
0
179
0
  RefPtr<GenericPromise::Private> outerPromise =
180
0
    new GenericPromise::Private(__func__);
181
0
182
0
  StartOp(args,
183
0
    [outerPromise](const ClientOpResult& aResult) {
184
0
      outerPromise->Resolve(true, __func__);
185
0
    }, [outerPromise](const ClientOpResult& aResult) {
186
0
      outerPromise->Reject(aResult.get_nsresult(), __func__);
187
0
    });
188
0
189
0
  ref = outerPromise.get();
190
0
  return ref.forget();
191
0
}
192
193
RefPtr<GenericPromise>
194
ClientHandle::OnDetach()
195
0
{
196
0
  NS_ASSERT_OWNINGTHREAD(ClientSource);
197
0
198
0
  if (!mDetachPromise) {
199
0
    mDetachPromise = new GenericPromise::Private(__func__);
200
0
    if (IsShutdown()) {
201
0
      mDetachPromise->Resolve(true, __func__);
202
0
    }
203
0
  }
204
0
205
0
  RefPtr<GenericPromise> ref(mDetachPromise);
206
0
  return ref;
207
0
}
208
209
} // namespace dom
210
} // namespace mozilla