ClientHandleParent.cpp (3647B)
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 "ClientHandleParent.h" 8 9 #include "ClientHandleOpParent.h" 10 #include "ClientManagerService.h" 11 #include "ClientPrincipalUtils.h" 12 #include "ClientSourceParent.h" 13 #include "mozilla/dom/ClientIPCTypes.h" 14 15 namespace mozilla::dom { 16 17 using mozilla::ipc::IPCResult; 18 19 IPCResult ClientHandleParent::RecvTeardown() { 20 (void)Send__delete__(this); 21 return IPC_OK(); 22 } 23 24 void ClientHandleParent::ActorDestroy(ActorDestroyReason aReason) { 25 if (mSource) { 26 mSource->DetachHandle(this); 27 mSource = nullptr; 28 } else { 29 if (!mSourcePromiseHolder.IsEmpty()) { 30 CopyableErrorResult rv; 31 rv.ThrowAbortError("Client aborted"); 32 mSourcePromiseHolder.Reject(rv, __func__); 33 } 34 35 mSourcePromiseRequestHolder.DisconnectIfExists(); 36 } 37 } 38 39 PClientHandleOpParent* ClientHandleParent::AllocPClientHandleOpParent( 40 const ClientOpConstructorArgs& aArgs) { 41 return new ClientHandleOpParent(); 42 } 43 44 bool ClientHandleParent::DeallocPClientHandleOpParent( 45 PClientHandleOpParent* aActor) { 46 delete aActor; 47 return true; 48 } 49 50 IPCResult ClientHandleParent::RecvPClientHandleOpConstructor( 51 PClientHandleOpParent* aActor, const ClientOpConstructorArgs& aArgs) { 52 auto actor = static_cast<ClientHandleOpParent*>(aActor); 53 actor->Init(std::move(const_cast<ClientOpConstructorArgs&>(aArgs))); 54 return IPC_OK(); 55 } 56 57 ClientHandleParent::ClientHandleParent() 58 : mService(ClientManagerService::GetOrCreateInstance()), mSource(nullptr) {} 59 60 ClientHandleParent::~ClientHandleParent() { MOZ_DIAGNOSTIC_ASSERT(!mSource); } 61 62 void ClientHandleParent::Init(const IPCClientInfo& aClientInfo) { 63 mClientId = aClientInfo.id(); 64 mPrincipalInfo = aClientInfo.principalInfo(); 65 66 // Callbacks are disconnected in ActorDestroy, so capturing `this` is safe. 67 mService->FindSource(aClientInfo.id(), aClientInfo.principalInfo()) 68 ->Then( 69 GetCurrentSerialEventTarget(), __func__, 70 [self = RefPtr{this}](bool) { 71 self->mSourcePromiseRequestHolder.Complete(); 72 ClientSourceParent* source = self->mService->FindExistingSource( 73 self->mClientId, self->mPrincipalInfo); 74 if (source) { 75 self->FoundSource(source); 76 } 77 }, 78 [self = RefPtr{this}](const CopyableErrorResult&) { 79 self->mSourcePromiseRequestHolder.Complete(); 80 (void)Send__delete__(self); 81 }) 82 ->Track(mSourcePromiseRequestHolder); 83 } 84 85 ClientSourceParent* ClientHandleParent::GetSource() const { return mSource; } 86 87 RefPtr<SourcePromise> ClientHandleParent::EnsureSource() { 88 if (mSource) { 89 return SourcePromise::CreateAndResolve(mSource, __func__); 90 } 91 92 return mSourcePromiseHolder.Ensure(__func__); 93 } 94 95 void ClientHandleParent::FoundSource(ClientSourceParent* aSource) { 96 MOZ_ASSERT(aSource); 97 MOZ_ASSERT(aSource->Info().Id() == mClientId); 98 if (!ClientMatchPrincipalInfo(aSource->Info().PrincipalInfo(), 99 mPrincipalInfo)) { 100 if (mSourcePromiseHolder.IsEmpty()) { 101 CopyableErrorResult rv; 102 rv.ThrowAbortError("Client aborted"); 103 mSourcePromiseHolder.Reject(rv, __func__); 104 } 105 (void)Send__delete__(this); 106 return; 107 } 108 109 mSource = aSource; 110 mSource->AttachHandle(this); 111 mSourcePromiseHolder.ResolveIfExists(true, __func__); 112 } 113 114 } // namespace mozilla::dom