PCompositorBridgeParent* CompositorManagerParent::AllocPCompositorBridgeParent( const CompositorBridgeOptions& aOpt) { switch (aOpt.type()) { case CompositorBridgeOptions::TContentCompositorOptions: { ContentCompositorBridgeParent* bridge = new ContentCompositorBridgeParent(this); bridge->AddRef(); return bridge; } case CompositorBridgeOptions::TWidgetCompositorOptions: { // Only the UI process is allowed to create widget compositors in the // compositor process. gfx::GPUParent* gpu = gfx::GPUParent::GetSingleton(); if (NS_WARN_IF(!gpu || OtherPid() != gpu->OtherPid())) { MOZ_ASSERT_UNREACHABLE("Child cannot create widget compositor!"); break; } const WidgetCompositorOptions& opt = aOpt.get_WidgetCompositorOptions(); CompositorBridgeParent* bridge = new CompositorBridgeParent( this, opt.scale(), opt.vsyncRate(), opt.options(), opt.useExternalSurfaceSize(), opt.surfaceSize()); bridge->AddRef(); return bridge; } case CompositorBridgeOptions::TSameProcessWidgetCompositorOptions: { // If the GPU and UI process are combined, we actually already created the // CompositorBridgeParent, so we need to reuse that to inject it into the // IPDL framework. if (NS_WARN_IF(OtherPid() != base::GetCurrentProcId())) { MOZ_ASSERT_UNREACHABLE("Child cannot create same process compositor!"); break; } // Note that the static mutex not only is used to protect sInstance, but // also mPendingCompositorBridges. StaticMutexAutoLock lock(sMutex); if (mPendingCompositorBridges.IsEmpty()) { break; } CompositorBridgeParent* bridge = mPendingCompositorBridges[0]; bridge->AddRef(); mPendingCompositorBridges.RemoveElementAt(0); return bridge; } default: break; } return nullptr; }
Shmem::SharedMemory* IToplevelProtocol::CreateSharedMemory(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, bool aUnsafe, Shmem::id_t* aId) { RefPtr<Shmem::SharedMemory> segment( Shmem::Alloc(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), aSize, aType, aUnsafe)); if (!segment) { return nullptr; } int32_t id = GetSide() == ParentSide ? ++mLastShmemId : --mLastShmemId; Shmem shmem( Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), segment.get(), id); Message* descriptor = shmem.ShareTo( Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), OtherPid(), MSG_ROUTING_CONTROL); if (!descriptor) { return nullptr; } Unused << GetIPCChannel()->Send(descriptor); *aId = shmem.Id(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead()); Shmem::SharedMemory* rawSegment = segment.get(); mShmemMap.AddWithID(segment.forget().take(), *aId); return rawSegment; }
mozilla::ipc::IPCResult CompositorManagerParent::RecvReportSharedSurfacesMemory( ReportSharedSurfacesMemoryResolver&& aResolver) { SharedSurfacesMemoryReport report; SharedSurfacesParent::AccumulateMemoryReport(OtherPid(), report); aResolver(std::move(report)); return IPC_OK(); }
PLayerTransactionParent* CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent( const nsTArray<LayersBackend>&, const uint64_t& aId) { MOZ_ASSERT(aId != 0); // Check to see if this child process has access to this layer tree. if (!LayerTreeOwnerTracker::Get()->IsMapped(aId, OtherPid())) { NS_ERROR("Unexpected layers id in AllocPLayerTransactionParent; dropping message..."); return nullptr; } MonitorAutoLock lock(*sIndirectLayerTreesLock); CompositorBridgeParent::LayerTreeState* state = nullptr; LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId); if (sIndirectLayerTrees.end() != itr) { state = &itr->second; } if (state && state->mLayerManager) { state->mCrossProcessParent = this; HostLayerManager* lm = state->mLayerManager; LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId); p->AddIPDLReference(); sIndirectLayerTrees[aId].mLayerTree = p; return p; } NS_WARNING("Created child without a matching parent?"); LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId); p->AddIPDLReference(); return p; }
PAPZCTreeManagerParent* CrossProcessCompositorBridgeParent::AllocPAPZCTreeManagerParent(const uint64_t& aLayersId) { // Check to see if this child process has access to this layer tree. if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) { NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message..."); return nullptr; } MonitorAutoLock lock(*sIndirectLayerTreesLock); CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId]; // If the widget has shutdown its compositor, we may not have had a chance yet // to unmap our layers id, and we could get here without a parent compositor. // In this case return an empty APZCTM. if (!state.mParent) { // Note: we immediately call ClearTree since otherwise the APZCTM will // retain a reference to itself, through the checkerboard observer. RefPtr<APZCTreeManager> temp = new APZCTreeManager(); temp->ClearTree(); return new APZCTreeManagerParent(aLayersId, temp); } MOZ_ASSERT(!state.mApzcTreeManagerParent); state.mApzcTreeManagerParent = new APZCTreeManagerParent(aLayersId, state.mParent->GetAPZCTreeManager()); return state.mApzcTreeManagerParent; }
void CompositorManagerParent::ActorDestroy(ActorDestroyReason aReason) { SharedSurfacesParent::DestroyProcess(OtherPid()); StaticMutexAutoLock lock(sMutex); if (sInstance == this) { sInstance = nullptr; } }
bool IToplevelProtocol::TakeMinidump(nsIFile** aDump, uint32_t* aSequence) { MOZ_RELEASE_ASSERT(GetSide() == ParentSide); #ifdef MOZ_CRASHREPORTER return XRE_TakeMinidumpForChild(OtherPid(), aDump, aSequence); #else return false; #endif }
void RenderFrameParent::ActorDestroy(ActorDestroyReason why) { if (mLayersId != 0) { if (XRE_IsParentProcess()) { GPUProcessManager::Get()->UnmapLayerTreeId(mLayersId, OtherPid()); } else if (XRE_IsContentProcess()) { ContentChild::GetSingleton()->SendDeallocateLayerTreeId(mLayersId); } } mFrameLoader = nullptr; }
void TestHangsParent::CleanUp() { ipc::ScopedProcessHandle otherProcessHandle; if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle.rwget())) { fail("couldn't open child process"); } else { if (!KillProcess(otherProcessHandle, 0, false)) { fail("terminating child process"); } } Close(); }
mozilla::ipc::IPCResult CrossProcessCompositorBridgeParent::RecvAsyncPanZoomEnabled(const uint64_t& aLayersId, bool* aHasAPZ) { // Check to see if this child process has access to this layer tree. if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) { NS_ERROR("Unexpected layers id in RecvAsyncPanZoomEnabled; dropping message..."); return IPC_FAIL_NO_REASON(this); } MonitorAutoLock lock(*sIndirectLayerTreesLock); CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId]; *aHasAPZ = state.mParent ? state.mParent->AsyncPanZoomEnabled() : false; return IPC_OK(); }
PAPZCTreeManagerParent* CrossProcessCompositorBridgeParent::AllocPAPZCTreeManagerParent(const uint64_t& aLayersId) { // Check to see if this child process has access to this layer tree. if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) { NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message..."); return nullptr; } MonitorAutoLock lock(*sIndirectLayerTreesLock); CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId]; MOZ_ASSERT(state.mParent); MOZ_ASSERT(!state.mApzcTreeManagerParent); state.mApzcTreeManagerParent = new APZCTreeManagerParent(aLayersId, state.mParent->GetAPZCTreeManager()); return state.mApzcTreeManagerParent; }
void CompositorManagerParent::BindComplete() { // Add the IPDL reference to ourself, so we can't get freed until IPDL is // done with us. AddRef(); StaticMutexAutoLock lock(sMutex); if (OtherPid() == base::GetCurrentProcId()) { sInstance = this; } #ifdef COMPOSITOR_MANAGER_PARENT_EXPLICIT_SHUTDOWN if (!sActiveActors) { sActiveActors = new nsTArray<CompositorManagerParent*>(); } sActiveActors->AppendElement(this); #endif }
void ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy) { // Can't alloc/dealloc shmems from now on. mClosed = true; { MonitorAutoLock lock(*sImageBridgesLock); sImageBridges.erase(OtherPid()); } MessageLoop::current()->PostTask(NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy)); // It is very important that this method gets called at shutdown (be it a clean // or an abnormal shutdown), because DeferredDestroy is what clears mSelfRef. // If mSelfRef is not null and ActorDestroy is not called, the ImageBridgeParent // is leaked which causes the CompositorThreadHolder to be leaked and // CompsoitorParent's shutdown ends up spinning the event loop forever, waiting // for the compositor thread to terminate. }
nsresult PresentationRequestParent::DoRequest(const BuildTransportRequest& aRequest) { MOZ_ASSERT(mService); // Validate the accessibility (primarily for receiver side) so that a // compromised child process can't fake the ID. if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())-> IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) { return SendResponse(NS_ERROR_DOM_SECURITY_ERR); } nsresult rv = mService->BuildTransport(aRequest.sessionId(), aRequest.role()); if (NS_WARN_IF(NS_FAILED(rv))) { return SendResponse(rv); } return SendResponse(NS_OK); }
PLayerTransactionParent* CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent( const nsTArray<LayersBackend>&, const uint64_t& aId, TextureFactoryIdentifier* aTextureFactoryIdentifier, bool *aSuccess) { MOZ_ASSERT(aId != 0); // Check to see if this child process has access to this layer tree. if (!LayerTreeOwnerTracker::Get()->IsMapped(aId, OtherPid())) { NS_ERROR("Unexpected layers id in AllocPLayerTransactionParent; dropping message..."); return nullptr; } MonitorAutoLock lock(*sIndirectLayerTreesLock); CompositorBridgeParent::LayerTreeState* state = nullptr; LayerTreeMap::iterator itr = sIndirectLayerTrees.find(aId); if (sIndirectLayerTrees.end() != itr) { state = &itr->second; } if (state && state->mLayerManager) { state->mCrossProcessParent = this; HostLayerManager* lm = state->mLayerManager; *aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier(); *aSuccess = true; LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId); p->AddIPDLReference(); sIndirectLayerTrees[aId].mLayerTree = p; p->SetPendingCompositorUpdates(state->mPendingCompositorUpdates); return p; } NS_WARNING("Created child without a matching parent?"); // XXX: should be false, but that causes us to fail some tests on Mac w/ OMTC. // Bug 900745. change *aSuccess to false to see test failures. *aSuccess = true; LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId); p->AddIPDLReference(); return p; }
nsresult PresentationRequestParent::DoRequest(const ReconnectSessionRequest& aRequest) { MOZ_ASSERT(mService); // Validate the accessibility (primarily for receiver side) so that a // compromised child process can't fake the ID. if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())-> IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) { // NOTE: Return NS_ERROR_DOM_NOT_FOUND_ERR here to match the spec. // https://w3c.github.io/presentation-api/#reconnecting-to-a-presentation return SendResponse(NS_ERROR_DOM_NOT_FOUND_ERR); } mSessionId = aRequest.sessionId(); return mService->ReconnectSession(aRequest.urls(), aRequest.sessionId(), aRequest.role(), this); }
/* virtual */ mozilla::ipc::IPCResult PresentationParent::RecvRegisterSessionHandler(const nsString& aSessionId, const uint8_t& aRole) { MOZ_ASSERT(mService); // Validate the accessibility (primarily for receiver side) so that a // compromised child process can't fake the ID. if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())-> IsSessionAccessible(aSessionId, aRole, OtherPid()))) { return IPC_OK(); } if (nsIPresentationService::ROLE_CONTROLLER == aRole) { mSessionIdsAtController.AppendElement(aSessionId); } else { mSessionIdsAtReceiver.AppendElement(aSessionId); } Unused << NS_WARN_IF(NS_FAILED(mService->RegisterSessionListener(aSessionId, aRole, this))); return IPC_OK(); }
bool IToplevelProtocol::DestroySharedMemory(Shmem& shmem) { Shmem::id_t aId = shmem.Id(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead()); Shmem::SharedMemory* segment = LookupSharedMemory(aId); if (!segment) { return false; } Message* descriptor = shmem.UnshareFrom( Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), OtherPid(), MSG_ROUTING_CONTROL); mShmemMap.Remove(aId); Shmem::Dealloc(Shmem::IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead(), segment); if (!GetIPCChannel()->CanSend()) { delete descriptor; return true; } return descriptor && GetIPCChannel()->Send(descriptor); }
bool TestEndpointBridgeSubParent::RecvBridgeEm() { Endpoint<PTestEndpointBridgeMainSubParent> parent; Endpoint<PTestEndpointBridgeMainSubChild> child; nsresult rv; rv = PTestEndpointBridgeMainSub::CreateEndpoints( gEndpointBridgeMainChild->OtherPid(), OtherPid(), &parent, &child); if (NS_FAILED(rv)) { fail("opening PTestEndpointOpensOpened"); } if (!gEndpointBridgeMainChild->SendBridged(mozilla::Move(parent))) { fail("SendBridge failed for parent"); } if (!SendBridged(mozilla::Move(child))) { fail("SendBridge failed for child"); } return true; }
PAPZParent* CrossProcessCompositorBridgeParent::AllocPAPZParent(const uint64_t& aLayersId) { // Check to see if this child process has access to this layer tree. if (!LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, OtherPid())) { NS_ERROR("Unexpected layers id in AllocPAPZParent; dropping message..."); return nullptr; } RemoteContentController* controller = new RemoteContentController(); // Increment the controller's refcount before we return it. This will keep the // controller alive until it is released by IPDL in DeallocPAPZParent. controller->AddRef(); MonitorAutoLock lock(*sIndirectLayerTreesLock); CompositorBridgeParent::LayerTreeState& state = sIndirectLayerTrees[aLayersId]; MOZ_ASSERT(!state.mController); state.mController = controller; return controller; }
PWebRenderBridgeParent* CrossProcessCompositorBridgeParent::AllocPWebRenderBridgeParent(const wr::PipelineId& aPipelineId, const LayoutDeviceIntSize& aSize, TextureFactoryIdentifier* aTextureFactoryIdentifier, uint32_t *aIdNamespace) { #ifndef MOZ_BUILD_WEBRENDER // Extra guard since this in the parent process and we don't want a malicious // child process invoking this codepath before it's ready MOZ_RELEASE_ASSERT(false); #endif uint64_t layersId = wr::AsUint64(aPipelineId); // Check to see if this child process has access to this layer tree. if (!LayerTreeOwnerTracker::Get()->IsMapped(layersId, OtherPid())) { NS_ERROR("Unexpected layers id in AllocPAPZCTreeManagerParent; dropping message..."); return nullptr; } MonitorAutoLock lock(*sIndirectLayerTreesLock); MOZ_ASSERT(sIndirectLayerTrees.find(layersId) != sIndirectLayerTrees.end()); MOZ_ASSERT(sIndirectLayerTrees[layersId].mWrBridge == nullptr); CompositorBridgeParent* cbp = sIndirectLayerTrees[layersId].mParent; WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWrBridge.get(); WebRenderBridgeParent* parent = nullptr; RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI(); RefPtr<WebRenderCompositableHolder> holder = root->CompositableHolder(); parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder)); parent->AddRef(); // IPDL reference sIndirectLayerTrees[layersId].mCrossProcessParent = this; sIndirectLayerTrees[layersId].mWrBridge = parent; *aTextureFactoryIdentifier = parent->GetTextureFactoryIdentifier(); *aIdNamespace = parent->GetIdNameSpace(); return parent; }
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvAddPipelineIdForCompositable(const wr::PipelineId& aPipelineId, const CompositableHandle& aHandle, const bool& aAsync) { if (mDestroyed) { return IPC_OK(); } MOZ_ASSERT(!mAsyncCompositables.Get(wr::AsUint64(aPipelineId)).get()); RefPtr<CompositableHost> host; if (aAsync) { RefPtr<ImageBridgeParent> imageBridge = ImageBridgeParent::GetInstance(OtherPid()); if (!imageBridge) { return IPC_FAIL_NO_REASON(this); } host = imageBridge->FindCompositable(aHandle); } else { host = FindCompositable(aHandle); } if (!host) { return IPC_FAIL_NO_REASON(this); } MOZ_ASSERT(host->AsWebRenderImageHost()); WebRenderImageHost* wrHost = host->AsWebRenderImageHost(); if (!wrHost) { return IPC_OK(); } wrHost->SetWrBridge(this); mAsyncCompositables.Put(wr::AsUint64(aPipelineId), wrHost); mAsyncImageManager->AddAsyncImagePipeline(aPipelineId, wrHost); return IPC_OK(); }
base::ProcessId VRManagerParent::GetChildProcessId() { return OtherPid(); }
bool VRManagerParent::IsSameProcess() const { return OtherPid() == base::GetCurrentProcId(); }
bool CrossProcessCompositorBridgeParent::IsSameProcess() const { return OtherPid() == base::GetCurrentProcId(); }
bool VideoBridgeChild::IsSameProcess() const { return OtherPid() == base::GetCurrentProcId(); }
mozilla::ipc::IPCResult CompositorManagerParent::RecvAddSharedSurface( const wr::ExternalImageId& aId, const SurfaceDescriptorShared& aDesc) { SharedSurfacesParent::Add(aId, aDesc, OtherPid()); return IPC_OK(); }
bool WebRenderBridgeParent::IsSameProcess() const { return OtherPid() == base::GetCurrentProcId(); }
void VsyncBridgeChild::HandleFatalError(const char* aMsg) const { dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aMsg, OtherPid()); }
base::ProcessId WebRenderBridgeParent::GetChildProcessId() { return OtherPid(); }