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 "VRManagerParent.h"
9 #include "ipc/VRLayerParent.h"
10 #include "mozilla/gfx/PVRManagerParent.h"
11 #include "mozilla/ipc/Endpoint.h"
12 #include "mozilla/ipc/ProtocolTypes.h"
13 #include "mozilla/StaticPrefs_dom.h"
14 #include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
15 #include "mozilla/TimeStamp.h" // for TimeStamp
16 #include "mozilla/Unused.h"
17 #include "VRManager.h"
20 using mozilla::dom::GamepadHandle
;
23 using namespace layers
;
26 // See VRManagerChild.cpp
27 void ReleaseVRManagerParentSingleton();
29 VRManagerParent::VRManagerParent(ipc::EndpointProcInfo aChildProcess
,
30 dom::ContentParentId aChildId
,
33 mHaveEventListener(false),
34 mHaveControllerListener(false),
35 mIsContentChild(aIsContentChild
),
36 mVRActiveStatus(false) {
37 MOZ_COUNT_CTOR(VRManagerParent
);
38 MOZ_ASSERT(NS_IsMainThread());
40 SetOtherEndpointProcInfo(aChildProcess
);
43 VRManagerParent::~VRManagerParent() {
44 MOZ_ASSERT(!mVRManagerHolder
);
46 MOZ_COUNT_DTOR(VRManagerParent
);
49 PVRLayerParent
* VRManagerParent::AllocPVRLayerParent(const uint32_t& aDisplayID
,
50 const uint32_t& aGroup
) {
51 if (!StaticPrefs::dom_vr_enabled() && !StaticPrefs::dom_vr_webxr_enabled()) {
55 RefPtr
<VRLayerParent
> layer
;
56 layer
= new VRLayerParent(aDisplayID
, aGroup
);
57 VRManager
* vm
= VRManager::Get();
59 return layer
.forget().take();
62 bool VRManagerParent::DeallocPVRLayerParent(PVRLayerParent
* actor
) {
67 bool VRManagerParent::IsSameProcess() const {
68 return OtherPid() == base::GetCurrentProcId();
71 void VRManagerParent::RegisterWithManager() {
72 VRManager
* vm
= VRManager::Get();
73 vm
->AddVRManagerParent(this);
74 mVRManagerHolder
= vm
;
77 void VRManagerParent::UnregisterFromManager() {
78 VRManager
* vm
= VRManager::Get();
79 vm
->RemoveVRManagerParent(this);
80 mVRManagerHolder
= nullptr;
84 bool VRManagerParent::CreateForContent(Endpoint
<PVRManagerParent
>&& aEndpoint
,
85 dom::ContentParentId aChildId
) {
86 if (!CompositorThread()) {
90 RefPtr
<VRManagerParent
> vmp
=
91 new VRManagerParent(aEndpoint
.OtherEndpointProcInfo(), aChildId
, true);
92 CompositorThread()->Dispatch(NewRunnableMethod
<Endpoint
<PVRManagerParent
>&&>(
93 "gfx::VRManagerParent::Bind", vmp
, &VRManagerParent::Bind
,
94 std::move(aEndpoint
)));
99 void VRManagerParent::Bind(Endpoint
<PVRManagerParent
>&& aEndpoint
) {
100 if (!aEndpoint
.Bind(this)) {
103 mCompositorThreadHolder
= CompositorThreadHolder::GetSingleton();
105 RegisterWithManager();
109 void VRManagerParent::RegisterVRManagerInCompositorThread(
110 VRManagerParent
* aVRManager
) {
111 aVRManager
->RegisterWithManager();
115 already_AddRefed
<VRManagerParent
> VRManagerParent::CreateSameProcess() {
116 RefPtr
<VRManagerParent
> vmp
= new VRManagerParent(
117 ipc::EndpointProcInfo::Current(), dom::ContentParentId(), false);
118 vmp
->mCompositorThreadHolder
= CompositorThreadHolder::GetSingleton();
119 CompositorThread()->Dispatch(
120 NewRunnableFunction("RegisterVRManagerIncompositorThreadRunnable",
121 RegisterVRManagerInCompositorThread
, vmp
.get()));
125 bool VRManagerParent::CreateForGPUProcess(
126 Endpoint
<PVRManagerParent
>&& aEndpoint
) {
127 RefPtr
<VRManagerParent
> vmp
= new VRManagerParent(
128 aEndpoint
.OtherEndpointProcInfo(), dom::ContentParentId(), false);
129 vmp
->mCompositorThreadHolder
= CompositorThreadHolder::GetSingleton();
130 CompositorThread()->Dispatch(NewRunnableMethod
<Endpoint
<PVRManagerParent
>&&>(
131 "gfx::VRManagerParent::Bind", vmp
, &VRManagerParent::Bind
,
132 std::move(aEndpoint
)));
137 void VRManagerParent::Shutdown() {
138 MOZ_ASSERT(NS_IsMainThread());
141 "Shutdown() must gets called before the compositor thread is shutdown");
142 ReleaseVRManagerParentSingleton();
143 CompositorThread()->Dispatch(NS_NewRunnableFunction(
144 "VRManagerParent::Shutdown",
145 [vm
= RefPtr
<VRManager
>(VRManager::MaybeGet())]() -> void {
149 vm
->ShutdownVRManagerParents();
153 void VRManagerParent::ActorDestroy(ActorDestroyReason why
) {
154 UnregisterFromManager();
155 mCompositorThreadHolder
= nullptr;
158 mozilla::ipc::IPCResult
VRManagerParent::RecvDetectRuntimes() {
159 // Detect runtime capabilities. This will return the presense of VR and/or AR
160 // runtime software, without enumerating or activating any hardware devices.
161 // UpdateDisplayInfo will be sent to VRManagerChild with the results of the
163 VRManager
* vm
= VRManager::Get();
164 vm
->DetectRuntimes();
169 mozilla::ipc::IPCResult
VRManagerParent::RecvRefreshDisplays() {
170 // This is called to activate the VR runtimes, detecting the
171 // presence and capabilities of XR hardware.
172 // UpdateDisplayInfo will be sent to VRManagerChild with the results of the
173 // enumerated hardware.
174 VRManager
* vm
= VRManager::Get();
175 vm
->EnumerateDevices();
180 mozilla::ipc::IPCResult
VRManagerParent::RecvSetGroupMask(
181 const uint32_t& aDisplayID
, const uint32_t& aGroupMask
) {
182 VRManager
* vm
= VRManager::Get();
183 vm
->SetGroupMask(aGroupMask
);
187 bool VRManagerParent::HaveEventListener() { return mHaveEventListener
; }
189 bool VRManagerParent::HaveControllerListener() {
190 return mHaveControllerListener
;
193 bool VRManagerParent::GetVRActiveStatus() { return mVRActiveStatus
; }
195 mozilla::ipc::IPCResult
VRManagerParent::RecvSetHaveEventListener(
196 const bool& aHaveEventListener
) {
197 mHaveEventListener
= aHaveEventListener
;
201 mozilla::ipc::IPCResult
VRManagerParent::RecvControllerListenerAdded() {
202 // Force update the available controllers for GamepadManager,
203 VRManager
* vm
= VRManager::Get();
204 vm
->StopAllHaptics();
205 mHaveControllerListener
= true;
209 mozilla::ipc::IPCResult
VRManagerParent::RecvControllerListenerRemoved() {
210 mHaveControllerListener
= false;
211 VRManager
* vm
= VRManager::Get();
212 vm
->StopAllHaptics();
216 mozilla::ipc::IPCResult
VRManagerParent::RecvRunPuppet(
217 const nsTArray
<uint64_t>& aBuffer
) {
218 #if defined(MOZ_WIDGET_ANDROID)
219 // Not yet implemented for Android / GeckoView
221 Unused
<< SendNotifyPuppetCommandBufferCompleted(false);
223 VRManager
* vm
= VRManager::Get();
224 if (!vm
->RunPuppet(aBuffer
, this)) {
225 // We have immediately failed, need to resolve the
226 // promise right away
227 Unused
<< SendNotifyPuppetCommandBufferCompleted(false);
229 #endif // defined(MOZ_WIDGET_ANDROID)
233 mozilla::ipc::IPCResult
VRManagerParent::RecvResetPuppet() {
234 #if defined(MOZ_WIDGET_ANDROID)
235 // Not yet implemented for Android / GeckoView
238 VRManager
* vm
= VRManager::Get();
239 vm
->ResetPuppet(this);
240 #endif // defined(MOZ_WIDGET_ANDROID)
244 mozilla::ipc::IPCResult
VRManagerParent::RecvVibrateHaptic(
245 const mozilla::dom::GamepadHandle
& aGamepadHandle
,
246 const uint32_t& aHapticIndex
, const double& aIntensity
,
247 const double& aDuration
, const uint32_t& aPromiseID
) {
248 VRManager
* vm
= VRManager::Get();
249 VRManagerPromise
promise(this, aPromiseID
);
251 vm
->VibrateHaptic(aGamepadHandle
, aHapticIndex
, aIntensity
, aDuration
,
256 mozilla::ipc::IPCResult
VRManagerParent::RecvStopVibrateHaptic(
257 const mozilla::dom::GamepadHandle
& aGamepadHandle
) {
258 VRManager
* vm
= VRManager::Get();
259 vm
->StopVibrateHaptic(aGamepadHandle
);
263 bool VRManagerParent::SendReplyGamepadVibrateHaptic(
264 const uint32_t& aPromiseID
) {
265 // GamepadManager only exists at the content process
266 // or the same process in non-e10s mode.
267 if (mHaveControllerListener
&& (mIsContentChild
|| IsSameProcess())) {
268 return PVRManagerParent::SendReplyGamepadVibrateHaptic(aPromiseID
);
274 mozilla::ipc::IPCResult
VRManagerParent::RecvStartVRNavigation(
275 const uint32_t& aDeviceID
) {
276 VRManager
* vm
= VRManager::Get();
277 vm
->StartVRNavigation(aDeviceID
);
281 mozilla::ipc::IPCResult
VRManagerParent::RecvStopVRNavigation(
282 const uint32_t& aDeviceID
, const TimeDuration
& aTimeout
) {
283 VRManager
* vm
= VRManager::Get();
284 vm
->StopVRNavigation(aDeviceID
, aTimeout
);
288 mozilla::ipc::IPCResult
VRManagerParent::RecvStartActivity() {
289 mVRActiveStatus
= true;
293 mozilla::ipc::IPCResult
VRManagerParent::RecvStopActivity() {
294 mVRActiveStatus
= false;
299 } // namespace mozilla