LCOV - code coverage report
Current view: top level - gfx/vr/ipc - VRManagerChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 10 282 3.5 %
Date: 2018-08-07 16:42:27 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       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 "VRManagerChild.h"
       8             : #include "VRManagerParent.h"
       9             : #include "VRThread.h"
      10             : #include "VRDisplayClient.h"
      11             : #include "nsGlobalWindow.h"
      12             : #include "mozilla/StaticPtr.h"
      13             : #include "mozilla/layers/CompositorThread.h" // for CompositorThread
      14             : #include "mozilla/dom/Navigator.h"
      15             : #include "mozilla/dom/VREventObserver.h"
      16             : #include "mozilla/dom/WindowBinding.h" // for FrameRequestCallback
      17             : #include "mozilla/dom/ContentChild.h"
      18             : #include "nsContentUtils.h"
      19             : #include "mozilla/dom/GamepadManager.h"
      20             : #include "mozilla/dom/VRServiceTest.h"
      21             : #include "mozilla/layers/SyncObject.h"
      22             : 
      23             : using namespace mozilla::dom;
      24             : 
      25             : namespace {
      26             : const nsTArray<RefPtr<dom::VREventObserver>>::index_type kNoIndex =
      27             :   nsTArray<RefPtr<dom::VREventObserver> >::NoIndex;
      28             : } // namespace
      29             : 
      30             : namespace mozilla {
      31             : namespace gfx {
      32             : 
      33           1 : static StaticRefPtr<VRManagerChild> sVRManagerChildSingleton;
      34           0 : static StaticRefPtr<VRManagerParent> sVRManagerParentSingleton;
      35             : 
      36           0 : void ReleaseVRManagerParentSingleton() {
      37           0 :   sVRManagerParentSingleton = nullptr;
      38           0 : }
      39             : 
      40           0 : VRManagerChild::VRManagerChild()
      41             :   : mDisplaysInitialized(false)
      42           1 :   , mMessageLoop(MessageLoop::current())
      43             :   , mFrameRequestCallbackCounter(0)
      44             :   , mBackend(layers::LayersBackend::LAYERS_NONE)
      45             :   , mPromiseID(0)
      46           0 :   , mVRMockDisplay(nullptr)
      47             : {
      48           0 :   MOZ_ASSERT(NS_IsMainThread());
      49             : 
      50           1 :   mStartTimeStamp = TimeStamp::Now();
      51           0 : }
      52             : 
      53           0 : VRManagerChild::~VRManagerChild()
      54             : {
      55           0 :   MOZ_ASSERT(NS_IsMainThread());
      56           0 : }
      57             : 
      58             : /*static*/ void
      59           0 : VRManagerChild::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier)
      60             : {
      61           0 :   if (sVRManagerChildSingleton) {
      62           0 :     sVRManagerChildSingleton->mBackend = aIdentifier.mParentBackend;
      63           1 :     sVRManagerChildSingleton->mSyncObject =
      64           0 :         layers::SyncObjectClient::CreateSyncObjectClient(aIdentifier.mSyncHandle);
      65             :   }
      66           1 : }
      67             : 
      68             : layers::LayersBackend
      69           0 : VRManagerChild::GetBackendType() const
      70             : {
      71           0 :   return mBackend;
      72             : }
      73             : 
      74             : /*static*/ VRManagerChild*
      75           0 : VRManagerChild::Get()
      76             : {
      77           0 :   MOZ_ASSERT(sVRManagerChildSingleton);
      78           0 :   return sVRManagerChildSingleton;
      79             : }
      80             : 
      81             : /* static */ bool
      82           0 : VRManagerChild::IsCreated()
      83             : {
      84           2 :   return !!sVRManagerChildSingleton;
      85             : }
      86             : 
      87             : /* static */ bool
      88           0 : VRManagerChild::InitForContent(Endpoint<PVRManagerChild>&& aEndpoint)
      89             : {
      90           0 :   MOZ_ASSERT(NS_IsMainThread());
      91           0 :   MOZ_ASSERT(!sVRManagerChildSingleton);
      92             : 
      93           0 :   RefPtr<VRManagerChild> child(new VRManagerChild());
      94           0 :   if (!aEndpoint.Bind(child)) {
      95             :     return false;
      96             :   }
      97           0 :   sVRManagerChildSingleton = child;
      98           0 :   return true;
      99             : }
     100             : 
     101             : /* static */ bool
     102           0 : VRManagerChild::ReinitForContent(Endpoint<PVRManagerChild>&& aEndpoint)
     103             : {
     104           0 :   MOZ_ASSERT(NS_IsMainThread());
     105             : 
     106           0 :   ShutDown();
     107             : 
     108           0 :   return InitForContent(std::move(aEndpoint));
     109             : }
     110             : 
     111             : /*static*/ void
     112           0 : VRManagerChild::InitSameProcess()
     113             : {
     114           1 :   MOZ_ASSERT(NS_IsMainThread());
     115           0 :   MOZ_ASSERT(!sVRManagerChildSingleton);
     116             : 
     117           0 :   sVRManagerChildSingleton = new VRManagerChild();
     118           2 :   sVRManagerParentSingleton = VRManagerParent::CreateSameProcess();
     119           0 :   sVRManagerChildSingleton->Open(sVRManagerParentSingleton->GetIPCChannel(),
     120             :                                  VRListenerThreadHolder::Loop(),
     121           1 :                                  mozilla::ipc::ChildSide);
     122           1 : }
     123             : 
     124             : /* static */ void
     125           0 : VRManagerChild::InitWithGPUProcess(Endpoint<PVRManagerChild>&& aEndpoint)
     126             : {
     127           0 :   MOZ_ASSERT(NS_IsMainThread());
     128           0 :   MOZ_ASSERT(!sVRManagerChildSingleton);
     129             : 
     130           0 :   sVRManagerChildSingleton = new VRManagerChild();
     131           0 :   if (!aEndpoint.Bind(sVRManagerChildSingleton)) {
     132           0 :     MOZ_CRASH("Couldn't Open() Compositor channel.");
     133             :   }
     134           0 : }
     135             : 
     136             : /*static*/ void
     137           0 : VRManagerChild::ShutDown()
     138             : {
     139           0 :   MOZ_ASSERT(NS_IsMainThread());
     140           0 :   if (sVRManagerChildSingleton) {
     141           0 :     sVRManagerChildSingleton->Destroy();
     142             :     sVRManagerChildSingleton = nullptr;
     143             :   }
     144           0 : }
     145             : 
     146             : /*static*/ void
     147           0 : VRManagerChild::DeferredDestroy(RefPtr<VRManagerChild> aVRManagerChild)
     148             : {
     149           0 :   aVRManagerChild->Close();
     150           0 : }
     151             : 
     152             : void
     153           0 : VRManagerChild::Destroy()
     154             : {
     155             :   // Keep ourselves alive until everything has been shut down
     156           0 :   RefPtr<VRManagerChild> selfRef = this;
     157             : 
     158             :   // The DeferredDestroyVRManager task takes ownership of
     159             :   // the VRManagerChild and will release it when it runs.
     160           0 :   MessageLoop::current()->PostTask(
     161           0 :              NewRunnableFunction("VRManagerChildDestroyRunnable",
     162           0 :                                  DeferredDestroy, selfRef));
     163           0 : }
     164             : 
     165             : PVRLayerChild*
     166           0 : VRManagerChild::AllocPVRLayerChild(const uint32_t& aDisplayID,
     167             :                                    const uint32_t& aGroup)
     168             : {
     169           0 :   return VRLayerChild::CreateIPDLActor();
     170             : }
     171             : 
     172             : bool
     173           0 : VRManagerChild::DeallocPVRLayerChild(PVRLayerChild* actor)
     174             : {
     175           0 :   return VRLayerChild::DestroyIPDLActor(actor);
     176             : }
     177             : 
     178             : void
     179           0 : VRManagerChild::UpdateDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayUpdates)
     180             : {
     181           0 :   nsTArray<uint32_t> disconnectedDisplays;
     182           0 :   nsTArray<uint32_t> connectedDisplays;
     183             : 
     184           0 :   nsTArray<RefPtr<VRDisplayClient>> prevDisplays;
     185           0 :   prevDisplays = mDisplays;
     186             : 
     187             :   // Check if any displays have been disconnected
     188           0 :   for (auto& display : prevDisplays) {
     189           0 :     bool found = false;
     190           0 :     for (auto& displayUpdate : aDisplayUpdates) {
     191           0 :       if (display->GetDisplayInfo().GetDisplayID() == displayUpdate.GetDisplayID()) {
     192             :         found = true;
     193             :         break;
     194             :       }
     195             :     }
     196           0 :     if (!found) {
     197           0 :       display->NotifyDisconnected();
     198           0 :       disconnectedDisplays.AppendElement(display->GetDisplayInfo().GetDisplayID());
     199             :     }
     200             :   }
     201             : 
     202             :   // mDisplays could be a hashed container for more scalability, but not worth
     203             :   // it now as we expect < 10 entries.
     204           0 :   nsTArray<RefPtr<VRDisplayClient>> displays;
     205           0 :   for (VRDisplayInfo& displayUpdate : aDisplayUpdates) {
     206           0 :     bool isNewDisplay = true;
     207           0 :     for (auto& display : prevDisplays) {
     208           0 :       const VRDisplayInfo& prevInfo = display->GetDisplayInfo();
     209           0 :       if (prevInfo.GetDisplayID() == displayUpdate.GetDisplayID()) {
     210           0 :         if (displayUpdate.GetIsConnected() && !prevInfo.GetIsConnected()) {
     211           0 :           connectedDisplays.AppendElement(displayUpdate.GetDisplayID());
     212             :         }
     213           0 :         if (!displayUpdate.GetIsConnected() && prevInfo.GetIsConnected()) {
     214           0 :           disconnectedDisplays.AppendElement(displayUpdate.GetDisplayID());
     215             :         }
     216           0 :         display->UpdateDisplayInfo(displayUpdate);
     217           0 :         displays.AppendElement(display);
     218           0 :         isNewDisplay = false;
     219           0 :         break;
     220             :       }
     221             :     }
     222           0 :     if (isNewDisplay) {
     223           0 :       displays.AppendElement(new VRDisplayClient(displayUpdate));
     224           0 :       connectedDisplays.AppendElement(displayUpdate.GetDisplayID());
     225             :     }
     226             :   }
     227             : 
     228           0 :   mDisplays = displays;
     229             : 
     230             :   // We wish to fire the events only after mDisplays is updated
     231           0 :   for (uint32_t displayID : disconnectedDisplays) {
     232           0 :     FireDOMVRDisplayDisconnectEvent(displayID);
     233             :   }
     234             : 
     235           0 :   for (uint32_t displayID : connectedDisplays) {
     236           0 :     FireDOMVRDisplayConnectEvent(displayID);
     237             :   }
     238             : 
     239           0 :   mDisplaysInitialized = true;
     240           0 : }
     241             : 
     242             : mozilla::ipc::IPCResult
     243           0 : VRManagerChild::RecvUpdateDisplayInfo(nsTArray<VRDisplayInfo>&& aDisplayUpdates)
     244             : {
     245           0 :   UpdateDisplayInfo(aDisplayUpdates);
     246           0 :   for (auto& windowId : mNavigatorCallbacks) {
     247             :     /** We must call NotifyVRDisplaysUpdated for every
     248             :      * window's Navigator in mNavigatorCallbacks to ensure that
     249             :      * the promise returned by Navigator.GetVRDevices
     250             :      * can resolve.  This must happen even if no changes
     251             :      * to VRDisplays have been detected here.
     252             :      */
     253             :     nsGlobalWindowInner* window =
     254           0 :       nsGlobalWindowInner::GetInnerWindowWithId(windowId);
     255           0 :     if (!window) {
     256             :       continue;
     257             :     }
     258           0 :     dom::Navigator* nav = window->Navigator();
     259           0 :     if (!nav) {
     260             :       continue;
     261             :     }
     262           0 :     nav->NotifyVRDisplaysUpdated();
     263             :   }
     264           0 :   mNavigatorCallbacks.Clear();
     265           0 :   return IPC_OK();
     266             : }
     267             : 
     268             : bool
     269           0 : VRManagerChild::GetVRDisplays(nsTArray<RefPtr<VRDisplayClient>>& aDisplays)
     270             : {
     271           0 :   aDisplays = mDisplays;
     272           0 :   return true;
     273             : }
     274             : 
     275             : bool
     276           0 : VRManagerChild::RefreshVRDisplaysWithCallback(uint64_t aWindowId)
     277             : {
     278           0 :   bool success = SendRefreshDisplays();
     279           0 :   if (success) {
     280           0 :     mNavigatorCallbacks.AppendElement(aWindowId);
     281             :   }
     282           0 :   return success;
     283             : }
     284             : 
     285             : void
     286           0 : VRManagerChild::CreateVRServiceTestDisplay(const nsCString& aID, dom::Promise* aPromise)
     287             : {
     288           0 :   SendCreateVRServiceTestDisplay(aID, mPromiseID);
     289           0 :   mPromiseList.Put(mPromiseID, aPromise);
     290           0 :   ++mPromiseID;
     291           0 : }
     292             : 
     293             : void
     294           0 : VRManagerChild::CreateVRServiceTestController(const nsCString& aID, dom::Promise* aPromise)
     295             : {
     296           0 :   SendCreateVRServiceTestController(aID, mPromiseID);
     297           0 :   mPromiseList.Put(mPromiseID, aPromise);
     298           0 :   ++mPromiseID;
     299           0 : }
     300             : 
     301             : PVRLayerChild*
     302           0 : VRManagerChild::CreateVRLayer(uint32_t aDisplayID,
     303             :                               nsIEventTarget* aTarget,
     304             :                               uint32_t aGroup)
     305             : {
     306           0 :   PVRLayerChild* vrLayerChild = AllocPVRLayerChild(aDisplayID, aGroup);
     307             :   // Do the DOM labeling.
     308           0 :   if (aTarget) {
     309           0 :     SetEventTargetForActor(vrLayerChild, aTarget);
     310           0 :     MOZ_ASSERT(vrLayerChild->GetActorEventTarget());
     311             :   }
     312           0 :   return SendPVRLayerConstructor(vrLayerChild, aDisplayID, aGroup);
     313             : }
     314             : 
     315             : 
     316             : // XXX TODO - VRManagerChild::FrameRequest is the same as nsIDocument::FrameRequest, should we consolodate these?
     317           0 : struct VRManagerChild::FrameRequest
     318             : {
     319             :   FrameRequest(mozilla::dom::FrameRequestCallback& aCallback,
     320           0 :     int32_t aHandle) :
     321             :     mCallback(&aCallback),
     322           0 :     mHandle(aHandle)
     323             :   {}
     324             : 
     325             :   // Conversion operator so that we can append these to a
     326             :   // FrameRequestCallbackList
     327             :   operator const RefPtr<mozilla::dom::FrameRequestCallback>& () const {
     328             :     return mCallback;
     329             :   }
     330             : 
     331             :   // Comparator operators to allow RemoveElementSorted with an
     332             :   // integer argument on arrays of FrameRequest
     333             :   bool operator==(int32_t aHandle) const {
     334             :     return mHandle == aHandle;
     335             :   }
     336             :   bool operator<(int32_t aHandle) const {
     337             :     return mHandle < aHandle;
     338             :   }
     339             : 
     340             :   RefPtr<mozilla::dom::FrameRequestCallback> mCallback;
     341             :   int32_t mHandle;
     342             : };
     343             : 
     344             : nsresult
     345           0 : VRManagerChild::ScheduleFrameRequestCallback(mozilla::dom::FrameRequestCallback& aCallback,
     346             :                                              int32_t *aHandle)
     347             : {
     348           0 :   if (mFrameRequestCallbackCounter == INT32_MAX) {
     349             :     // Can't increment without overflowing; bail out
     350             :     return NS_ERROR_NOT_AVAILABLE;
     351             :   }
     352           0 :   int32_t newHandle = ++mFrameRequestCallbackCounter;
     353             : 
     354             :   DebugOnly<FrameRequest*> request =
     355           0 :     mFrameRequestCallbacks.AppendElement(FrameRequest(aCallback, newHandle));
     356           0 :   NS_ASSERTION(request, "This is supposed to be infallible!");
     357             : 
     358           0 :   *aHandle = newHandle;
     359           0 :   return NS_OK;
     360             : }
     361             : 
     362             : void
     363           0 : VRManagerChild::CancelFrameRequestCallback(int32_t aHandle)
     364             : {
     365             :   // mFrameRequestCallbacks is stored sorted by handle
     366           0 :   mFrameRequestCallbacks.RemoveElementSorted(aHandle);
     367           0 : }
     368             : 
     369             : mozilla::ipc::IPCResult
     370           0 : VRManagerChild::RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
     371             : {
     372             :   // VRManagerChild could be at other processes, but GamepadManager
     373             :   // only exists at the content process or the same process
     374             :   // in non-e10s mode.
     375           0 :   MOZ_ASSERT(XRE_IsContentProcess() || IsSameProcess());
     376             : 
     377           0 :   RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
     378           0 :   if (gamepadManager) {
     379           0 :     gamepadManager->Update(aGamepadEvent);
     380             :   }
     381             : 
     382           0 :   return IPC_OK();
     383             : }
     384             : 
     385             : mozilla::ipc::IPCResult
     386           0 : VRManagerChild::RecvReplyCreateVRServiceTestDisplay(const nsCString& aID,
     387             :                                                     const uint32_t& aPromiseID,
     388             :                                                     const uint32_t& aDeviceID)
     389             : {
     390           0 :   RefPtr<dom::Promise> p;
     391           0 :   if (!mPromiseList.Get(aPromiseID, getter_AddRefs(p))) {
     392           0 :     MOZ_CRASH("We should always have a promise.");
     393             :   }
     394             : 
     395             :   // We only allow one VRMockDisplay in VR tests.
     396           0 :   if (!mVRMockDisplay) {
     397           0 :     mVRMockDisplay = new VRMockDisplay(aID, aDeviceID);
     398             :   }
     399           0 :   p->MaybeResolve(mVRMockDisplay);
     400           0 :   mPromiseList.Remove(aPromiseID);
     401           0 :   return IPC_OK();
     402             : }
     403             : 
     404             : mozilla::ipc::IPCResult
     405           0 : VRManagerChild::RecvReplyCreateVRServiceTestController(const nsCString& aID,
     406             :                                                        const uint32_t& aPromiseID,
     407             :                                                        const uint32_t& aDeviceID)
     408             : {
     409           0 :   RefPtr<dom::Promise> p;
     410           0 :   if (!mPromiseList.Get(aPromiseID, getter_AddRefs(p))) {
     411           0 :     MOZ_CRASH("We should always have a promise.");
     412             :   }
     413             : 
     414           0 :   if (aDeviceID == 0) {
     415             :     // A value of 0 indicates that the controller could not
     416             :     // be created.  Most likely due to having no VR display
     417             :     // to associate it with.
     418           0 :     p->MaybeRejectWithUndefined();
     419             :   } else {
     420           0 :     p->MaybeResolve(new VRMockController(aID, aDeviceID));
     421             :   }
     422           0 :   mPromiseList.Remove(aPromiseID);
     423           0 :   return IPC_OK();
     424             : }
     425             : 
     426             : void
     427           0 : VRManagerChild::RunFrameRequestCallbacks()
     428             : {
     429           0 :   AUTO_PROFILER_TRACING("VR", "RunFrameRequestCallbacks");
     430             : 
     431           0 :   TimeStamp nowTime = TimeStamp::Now();
     432           0 :   mozilla::TimeDuration duration = nowTime - mStartTimeStamp;
     433           0 :   DOMHighResTimeStamp timeStamp = duration.ToMilliseconds();
     434             : 
     435             : 
     436           0 :   nsTArray<FrameRequest> callbacks;
     437           0 :   callbacks.AppendElements(mFrameRequestCallbacks);
     438           0 :   mFrameRequestCallbacks.Clear();
     439           0 :   for (auto& callback : callbacks) {
     440           0 :     callback.mCallback->Call(timeStamp);
     441             :   }
     442           0 : }
     443             : 
     444             : void
     445           0 : VRManagerChild::FireDOMVRDisplayMountedEvent(uint32_t aDisplayID)
     446             : {
     447           0 :   nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t>(
     448             :     "gfx::VRManagerChild::FireDOMVRDisplayMountedEventInternal",
     449             :     this,
     450             :     &VRManagerChild::FireDOMVRDisplayMountedEventInternal,
     451           0 :     aDisplayID));
     452           0 : }
     453             : 
     454             : void
     455           0 : VRManagerChild::FireDOMVRDisplayUnmountedEvent(uint32_t aDisplayID)
     456             : {
     457           0 :   nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t>(
     458             :     "gfx::VRManagerChild::FireDOMVRDisplayUnmountedEventInternal",
     459             :     this,
     460             :     &VRManagerChild::FireDOMVRDisplayUnmountedEventInternal,
     461           0 :     aDisplayID));
     462           0 : }
     463             : 
     464             : void
     465           0 : VRManagerChild::FireDOMVRDisplayConnectEvent(uint32_t aDisplayID)
     466             : {
     467           0 :   nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t>(
     468             :     "gfx::VRManagerChild::FireDOMVRDisplayConnectEventInternal",
     469             :     this,
     470             :     &VRManagerChild::FireDOMVRDisplayConnectEventInternal,
     471           0 :     aDisplayID));
     472           0 : }
     473             : 
     474             : void
     475           0 : VRManagerChild::FireDOMVRDisplayDisconnectEvent(uint32_t aDisplayID)
     476             : {
     477           0 :   nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t>(
     478             :     "gfx::VRManagerChild::FireDOMVRDisplayDisconnectEventInternal",
     479             :     this,
     480             :     &VRManagerChild::FireDOMVRDisplayDisconnectEventInternal,
     481           0 :     aDisplayID));
     482           0 : }
     483             : 
     484             : void
     485           0 : VRManagerChild::FireDOMVRDisplayPresentChangeEvent(uint32_t aDisplayID)
     486             : {
     487           0 :   nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t>(
     488             :     "gfx::VRManagerChild::FireDOMVRDisplayPresentChangeEventInternal",
     489             :     this,
     490             :     &VRManagerChild::FireDOMVRDisplayPresentChangeEventInternal,
     491           0 :     aDisplayID));
     492           0 : }
     493             : 
     494             : void
     495           0 : VRManagerChild::FireDOMVRDisplayMountedEventInternal(uint32_t aDisplayID)
     496             : {
     497             :   // Iterate over a copy of mListeners, as dispatched events may modify it.
     498           0 :   nsTArray<RefPtr<dom::VREventObserver>> listeners;
     499           0 :   listeners = mListeners;
     500           0 :   for (auto& listener : listeners) {
     501           0 :     listener->NotifyVRDisplayMounted(aDisplayID);
     502             :   }
     503           0 : }
     504             : 
     505             : void
     506           0 : VRManagerChild::FireDOMVRDisplayUnmountedEventInternal(uint32_t aDisplayID)
     507             : {
     508             :   // Iterate over a copy of mListeners, as dispatched events may modify it.
     509           0 :   nsTArray<RefPtr<dom::VREventObserver>> listeners;
     510           0 :   listeners = mListeners;
     511           0 :   for (auto& listener : listeners) {
     512           0 :     listener->NotifyVRDisplayUnmounted(aDisplayID);
     513             :   }
     514           0 : }
     515             : 
     516             : void
     517           0 : VRManagerChild::FireDOMVRDisplayConnectEventInternal(uint32_t aDisplayID)
     518             : {
     519             :   // Iterate over a copy of mListeners, as dispatched events may modify it.
     520           0 :   nsTArray<RefPtr<dom::VREventObserver>> listeners;
     521           0 :   listeners = mListeners;
     522           0 :   for (auto& listener : listeners) {
     523           0 :     listener->NotifyVRDisplayConnect(aDisplayID);
     524             :   }
     525           0 : }
     526             : 
     527             : void
     528           0 : VRManagerChild::FireDOMVRDisplayDisconnectEventInternal(uint32_t aDisplayID)
     529             : {
     530             :   // Iterate over a copy of mListeners, as dispatched events may modify it.
     531           0 :   nsTArray<RefPtr<dom::VREventObserver>> listeners;
     532           0 :   listeners = mListeners;
     533           0 :   for (auto& listener : listeners) {
     534           0 :     listener->NotifyVRDisplayDisconnect(aDisplayID);
     535             :   }
     536           0 : }
     537             : 
     538             : void
     539           0 : VRManagerChild::FireDOMVRDisplayPresentChangeEventInternal(uint32_t aDisplayID)
     540             : {
     541             :   // Iterate over a copy of mListeners, as dispatched events may modify it.
     542           0 :   nsTArray<RefPtr<dom::VREventObserver>> listeners;
     543           0 :   listeners = mListeners;
     544           0 :   for (auto& listener : listeners) {
     545           0 :     listener->NotifyVRDisplayPresentChange(aDisplayID);
     546             :   }
     547           0 : }
     548             : 
     549             : void
     550           0 : VRManagerChild::FireDOMVRDisplayConnectEventsForLoadInternal(uint32_t aDisplayID,
     551             :                                                             dom::VREventObserver* aObserver)
     552             : {
     553           0 :   aObserver->NotifyVRDisplayConnect(aDisplayID);
     554           0 : }
     555             : 
     556             : void
     557           0 : VRManagerChild::FireDOMVRDisplayConnectEventsForLoad(dom::VREventObserver* aObserver)
     558             : {
     559             :   // We need to fire the VRDisplayConnect event when a page is loaded
     560             :   // for each VR Display that has already been enumerated
     561           0 :   nsTArray<RefPtr<VRDisplayClient>> displays;
     562           0 :   displays = mDisplays;
     563           0 :   for (auto& display : displays) {
     564           0 :     const VRDisplayInfo& info = display->GetDisplayInfo();
     565           0 :     if (info.GetIsConnected()) {
     566           0 :         nsContentUtils::AddScriptRunner(NewRunnableMethod<uint32_t, RefPtr<dom::VREventObserver>>(
     567             :       "gfx::VRManagerChild::FireDOMVRDisplayConnectEventsForLoadInternal",
     568             :       this,
     569             :       &VRManagerChild::FireDOMVRDisplayConnectEventsForLoadInternal,
     570           0 :       info.GetDisplayID(),
     571           0 :       aObserver));
     572             :     }
     573             :   }
     574           0 : }
     575             : 
     576             : void
     577           0 : VRManagerChild::AddListener(dom::VREventObserver* aObserver)
     578             : {
     579           0 :   MOZ_ASSERT(aObserver);
     580             : 
     581           0 :   if (mListeners.IndexOf(aObserver) != kNoIndex) {
     582             :     return; // already exists
     583             :   }
     584             : 
     585           0 :   mListeners.AppendElement(aObserver);
     586           0 :   if (mListeners.Length() == 1) {
     587           0 :     Unused << SendSetHaveEventListener(true);
     588             :   }
     589             : }
     590             : 
     591             : void
     592           0 : VRManagerChild::RemoveListener(dom::VREventObserver* aObserver)
     593             : {
     594           0 :   MOZ_ASSERT(aObserver);
     595             : 
     596           0 :   mListeners.RemoveElement(aObserver);
     597           0 :   if (mListeners.IsEmpty()) {
     598           0 :     Unused << SendSetHaveEventListener(false);
     599             :   }
     600           0 : }
     601             : 
     602             : void
     603           0 : VRManagerChild::HandleFatalError(const char* aMsg) const
     604             : {
     605           0 :   dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aMsg, OtherPid());
     606           0 : }
     607             : 
     608             : void
     609           0 : VRManagerChild::AddPromise(const uint32_t& aID, dom::Promise* aPromise)
     610             : {
     611           0 :   MOZ_ASSERT(!mGamepadPromiseList.Get(aID, nullptr));
     612           0 :   mGamepadPromiseList.Put(aID, aPromise);
     613           0 : }
     614             : 
     615             : mozilla::ipc::IPCResult
     616           0 : VRManagerChild::RecvReplyGamepadVibrateHaptic(const uint32_t& aPromiseID)
     617             : {
     618             :   // VRManagerChild could be at other processes, but GamepadManager
     619             :   // only exists at the content process or the same process
     620             :   // in non-e10s mode.
     621           0 :   MOZ_ASSERT(XRE_IsContentProcess() || IsSameProcess());
     622             : 
     623           0 :   RefPtr<dom::Promise> p;
     624           0 :   if (!mGamepadPromiseList.Get(aPromiseID, getter_AddRefs(p))) {
     625           0 :     MOZ_CRASH("We should always have a promise.");
     626             :   }
     627             : 
     628           0 :   p->MaybeResolve(true);
     629           0 :   mGamepadPromiseList.Remove(aPromiseID);
     630           0 :   return IPC_OK();
     631             : }
     632             : 
     633             : mozilla::ipc::IPCResult
     634           0 : VRManagerChild::RecvDispatchSubmitFrameResult(const uint32_t& aDisplayID,
     635             :                                               const VRSubmitFrameResultInfo& aResult)
     636             : {
     637           0 :   nsTArray<RefPtr<VRDisplayClient>> displays;
     638           0 :   displays = mDisplays;
     639             :   for (auto& display : displays) {
     640             :     if (display->GetDisplayInfo().GetDisplayID() == aDisplayID) {
     641             :       display->UpdateSubmitFrameResult(aResult);
     642             :     }
     643             :   }
     644             : 
     645             :   return IPC_OK();
     646             : }
     647             : 
     648             : } // namespace gfx
     649             : } // namespace mozilla

Generated by: LCOV version 1.13-14-ga5dd952