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;
}
예제 #2
0
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;
  }
}
예제 #7
0
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
}
예제 #8
0
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;
}
예제 #9
0
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
}
예제 #13
0
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.
}
예제 #14
0
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;
}
예제 #16
0
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);
}
예제 #17
0
/* 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();
}
예제 #18
0
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;
}
예제 #22
0
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();
}
예제 #23
0
base::ProcessId
VRManagerParent::GetChildProcessId()
{
  return OtherPid();
}
예제 #24
0
bool
VRManagerParent::IsSameProcess() const
{
  return OtherPid() == base::GetCurrentProcId();
}
bool
CrossProcessCompositorBridgeParent::IsSameProcess() const
{
  return OtherPid() == base::GetCurrentProcId();
}
예제 #26
0
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();
}
예제 #28
0
bool
WebRenderBridgeParent::IsSameProcess() const
{
  return OtherPid() == base::GetCurrentProcId();
}
예제 #29
0
void
VsyncBridgeChild::HandleFatalError(const char* aMsg) const
{
  dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aMsg, OtherPid());
}
예제 #30
0
base::ProcessId
WebRenderBridgeParent::GetChildProcessId()
{
  return OtherPid();
}