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 "ClientHandle.h"
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"
18 namespace mozilla::dom
{
20 using mozilla::dom::ipc::StructuredCloneData
;
22 ClientHandle::~ClientHandle() { Shutdown(); }
24 void ClientHandle::Shutdown() {
25 NS_ASSERT_OWNINGTHREAD(ClientSource
);
35 void ClientHandle::StartOp(const ClientOpConstructorArgs
& aArgs
,
36 const ClientOpCallback
&& aResolveCallback
,
37 const ClientOpCallback
&& aRejectCallback
) {
38 // Hold a ref to the client until the remote operation completes. Otherwise
39 // the ClientHandle might get de-refed and teardown the actor before we
41 RefPtr
<ClientHandle
> kungFuGrip
= this;
44 [&aArgs
, kungFuGrip
, aRejectCallback
,
45 resolve
= std::move(aResolveCallback
)](ClientHandleChild
* aActor
) {
46 MOZ_DIAGNOSTIC_ASSERT(aActor
);
47 ClientHandleOpChild
* actor
= new ClientHandleOpChild(
48 kungFuGrip
, aArgs
, std::move(resolve
), std::move(aRejectCallback
));
49 if (!aActor
->SendPClientHandleOpConstructor(actor
, aArgs
)) {
50 // Constructor failure will call reject callback via ActorDestroy()
55 MOZ_DIAGNOSTIC_ASSERT(aRejectCallback
);
56 CopyableErrorResult rv
;
57 rv
.ThrowInvalidStateError("Client has been destroyed");
62 void ClientHandle::OnShutdownThing() {
63 NS_ASSERT_OWNINGTHREAD(ClientHandle
);
64 if (!mDetachPromise
) {
67 mDetachPromise
->Resolve(true, __func__
);
70 ClientHandle::ClientHandle(ClientManager
* aManager
,
71 nsISerialEventTarget
* aSerialEventTarget
,
72 const ClientInfo
& aClientInfo
)
74 mSerialEventTarget(aSerialEventTarget
),
75 mClientInfo(aClientInfo
) {
76 MOZ_DIAGNOSTIC_ASSERT(mManager
);
77 MOZ_DIAGNOSTIC_ASSERT(mSerialEventTarget
);
78 MOZ_ASSERT(mSerialEventTarget
->IsOnCurrentThread());
81 void ClientHandle::Activate(PClientManagerChild
* aActor
) {
82 NS_ASSERT_OWNINGTHREAD(ClientHandle
);
88 PClientHandleChild
* actor
=
89 aActor
->SendPClientHandleConstructor(mClientInfo
.ToIPC());
95 ActivateThing(static_cast<ClientHandleChild
*>(actor
));
98 void ClientHandle::ExecutionReady(const ClientInfo
& aClientInfo
) {
99 mClientInfo
= aClientInfo
;
102 const ClientInfo
& ClientHandle::Info() const { return mClientInfo
; }
104 RefPtr
<GenericErrorResultPromise
> ClientHandle::Control(
105 const ServiceWorkerDescriptor
& aServiceWorker
) {
106 RefPtr
<GenericErrorResultPromise::Private
> outerPromise
=
107 new GenericErrorResultPromise::Private(__func__
);
109 // We should never have a cross-origin controller. Since this would be
110 // same-origin policy violation we do a full release assertion here.
111 MOZ_RELEASE_ASSERT(ClientMatchPrincipalInfo(mClientInfo
.PrincipalInfo(),
112 aServiceWorker
.PrincipalInfo()));
115 ClientControlledArgs(aServiceWorker
.ToIPC()),
116 [outerPromise
](const ClientOpResult
& aResult
) {
117 outerPromise
->Resolve(true, __func__
);
119 [outerPromise
](const ClientOpResult
& aResult
) {
120 outerPromise
->Reject(aResult
.get_CopyableErrorResult(), __func__
);
126 RefPtr
<ClientStatePromise
> ClientHandle::Focus(CallerType aCallerType
) {
127 RefPtr
<ClientStatePromise::Private
> outerPromise
=
128 new ClientStatePromise::Private(__func__
);
131 ClientFocusArgs(aCallerType
),
132 [outerPromise
](const ClientOpResult
& aResult
) {
133 outerPromise
->Resolve(
134 ClientState::FromIPC(aResult
.get_IPCClientState()), __func__
);
136 [outerPromise
](const ClientOpResult
& aResult
) {
137 outerPromise
->Reject(aResult
.get_CopyableErrorResult(), __func__
);
143 RefPtr
<GenericErrorResultPromise
> ClientHandle::PostMessage(
144 StructuredCloneData
& aData
, const ServiceWorkerDescriptor
& aSource
) {
146 CopyableErrorResult rv
;
147 rv
.ThrowInvalidStateError("Client has been destroyed");
148 return GenericErrorResultPromise::CreateAndReject(rv
, __func__
);
151 ClientPostMessageArgs args
;
152 args
.serviceWorker() = aSource
.ToIPC();
154 if (!aData
.BuildClonedMessageData(args
.clonedData())) {
155 CopyableErrorResult rv
;
156 rv
.ThrowInvalidStateError("Failed to clone data");
157 return GenericErrorResultPromise::CreateAndReject(rv
, __func__
);
160 RefPtr
<GenericErrorResultPromise::Private
> outerPromise
=
161 new GenericErrorResultPromise::Private(__func__
);
165 [outerPromise
](const ClientOpResult
& aResult
) {
166 outerPromise
->Resolve(true, __func__
);
168 [outerPromise
](const ClientOpResult
& aResult
) {
169 outerPromise
->Reject(aResult
.get_CopyableErrorResult(), __func__
);
175 RefPtr
<GenericPromise
> ClientHandle::OnDetach() {
176 NS_ASSERT_OWNINGTHREAD(ClientSource
);
178 if (!mDetachPromise
) {
179 mDetachPromise
= new GenericPromise::Private(__func__
);
181 mDetachPromise
->Resolve(true, __func__
);
185 return mDetachPromise
;
188 void ClientHandle::EvictFromBFCache() {
189 ClientEvictBFCacheArgs args
;
191 std::move(args
), [](const ClientOpResult
& aResult
) {},
192 [](const ClientOpResult
& aResult
) {});
195 } // namespace mozilla::dom