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 RefPtr
<ClientHandleChild
> actor
= new ClientHandleChild();
89 if (!aActor
->SendPClientHandleConstructor(actor
, mClientInfo
.ToIPC())) {
97 void ClientHandle::ExecutionReady(const ClientInfo
& aClientInfo
) {
98 mClientInfo
= aClientInfo
;
101 const ClientInfo
& ClientHandle::Info() const { return mClientInfo
; }
103 RefPtr
<GenericErrorResultPromise
> ClientHandle::Control(
104 const ServiceWorkerDescriptor
& aServiceWorker
) {
105 RefPtr
<GenericErrorResultPromise::Private
> outerPromise
=
106 new GenericErrorResultPromise::Private(__func__
);
108 // We should never have a cross-origin controller. Since this would be
109 // same-origin policy violation we do a full release assertion here.
110 MOZ_RELEASE_ASSERT(ClientMatchPrincipalInfo(mClientInfo
.PrincipalInfo(),
111 aServiceWorker
.PrincipalInfo()));
114 ClientControlledArgs(aServiceWorker
.ToIPC()),
115 [outerPromise
](const ClientOpResult
& aResult
) {
116 outerPromise
->Resolve(true, __func__
);
118 [outerPromise
](const ClientOpResult
& aResult
) {
119 outerPromise
->Reject(aResult
.get_CopyableErrorResult(), __func__
);
125 RefPtr
<ClientStatePromise
> ClientHandle::Focus(CallerType aCallerType
) {
126 RefPtr
<ClientStatePromise::Private
> outerPromise
=
127 new ClientStatePromise::Private(__func__
);
130 ClientFocusArgs(aCallerType
),
131 [outerPromise
](const ClientOpResult
& aResult
) {
132 outerPromise
->Resolve(
133 ClientState::FromIPC(aResult
.get_IPCClientState()), __func__
);
135 [outerPromise
](const ClientOpResult
& aResult
) {
136 outerPromise
->Reject(aResult
.get_CopyableErrorResult(), __func__
);
142 RefPtr
<GenericErrorResultPromise
> ClientHandle::PostMessage(
143 StructuredCloneData
& aData
, const ServiceWorkerDescriptor
& aSource
) {
145 CopyableErrorResult rv
;
146 rv
.ThrowInvalidStateError("Client has been destroyed");
147 return GenericErrorResultPromise::CreateAndReject(rv
, __func__
);
150 ClientPostMessageArgs args
;
151 args
.serviceWorker() = aSource
.ToIPC();
153 if (!aData
.BuildClonedMessageData(args
.clonedData())) {
154 CopyableErrorResult rv
;
155 rv
.ThrowInvalidStateError("Failed to clone data");
156 return GenericErrorResultPromise::CreateAndReject(rv
, __func__
);
159 RefPtr
<GenericErrorResultPromise::Private
> outerPromise
=
160 new GenericErrorResultPromise::Private(__func__
);
164 [outerPromise
](const ClientOpResult
& aResult
) {
165 outerPromise
->Resolve(true, __func__
);
167 [outerPromise
](const ClientOpResult
& aResult
) {
168 outerPromise
->Reject(aResult
.get_CopyableErrorResult(), __func__
);
174 RefPtr
<GenericPromise
> ClientHandle::OnDetach() {
175 NS_ASSERT_OWNINGTHREAD(ClientSource
);
177 if (!mDetachPromise
) {
178 mDetachPromise
= new GenericPromise::Private(__func__
);
180 mDetachPromise
->Resolve(true, __func__
);
184 return mDetachPromise
;
187 void ClientHandle::EvictFromBFCache() {
188 ClientEvictBFCacheArgs args
;
190 std::move(args
), [](const ClientOpResult
& aResult
) {},
191 [](const ClientOpResult
& aResult
) {});
194 } // namespace mozilla::dom