VRManagerParent.cpp (9207B)
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 "VRManagerParent.h" 8 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 "VRManager.h" 17 #include "VRThread.h" 18 19 using mozilla::dom::GamepadHandle; 20 21 namespace mozilla { 22 using namespace layers; 23 namespace gfx { 24 25 // See VRManagerChild.cpp 26 void ReleaseVRManagerParentSingleton(); 27 28 VRManagerParent::VRManagerParent(ipc::EndpointProcInfo aChildProcess, 29 dom::ContentParentId aChildId, 30 bool aIsContentChild) 31 : mChildId(aChildId), 32 mHaveEventListener(false), 33 mHaveControllerListener(false), 34 mIsContentChild(aIsContentChild), 35 mVRActiveStatus(false) { 36 MOZ_COUNT_CTOR(VRManagerParent); 37 MOZ_ASSERT(NS_IsMainThread()); 38 39 SetOtherEndpointProcInfo(aChildProcess); 40 } 41 42 VRManagerParent::~VRManagerParent() { 43 MOZ_ASSERT(!mVRManagerHolder); 44 45 MOZ_COUNT_DTOR(VRManagerParent); 46 } 47 48 PVRLayerParent* VRManagerParent::AllocPVRLayerParent(const uint32_t& aDisplayID, 49 const uint32_t& aGroup) { 50 if (!StaticPrefs::dom_vr_enabled() && !StaticPrefs::dom_vr_webxr_enabled()) { 51 return nullptr; 52 } 53 54 RefPtr<VRLayerParent> layer; 55 layer = new VRLayerParent(aDisplayID, aGroup); 56 VRManager* vm = VRManager::Get(); 57 vm->AddLayer(layer); 58 return layer.forget().take(); 59 } 60 61 bool VRManagerParent::DeallocPVRLayerParent(PVRLayerParent* actor) { 62 delete actor; 63 return true; 64 } 65 66 bool VRManagerParent::IsSameProcess() const { 67 return OtherPid() == base::GetCurrentProcId(); 68 } 69 70 void VRManagerParent::RegisterWithManager() { 71 VRManager* vm = VRManager::Get(); 72 vm->AddVRManagerParent(this); 73 mVRManagerHolder = vm; 74 } 75 76 void VRManagerParent::UnregisterFromManager() { 77 VRManager* vm = VRManager::Get(); 78 vm->RemoveVRManagerParent(this); 79 mVRManagerHolder = nullptr; 80 } 81 82 /* static */ 83 bool VRManagerParent::CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint, 84 dom::ContentParentId aChildId) { 85 if (!CompositorThread()) { 86 return false; 87 } 88 89 RefPtr<VRManagerParent> vmp = 90 new VRManagerParent(aEndpoint.OtherEndpointProcInfo(), aChildId, true); 91 CompositorThread()->Dispatch(NewRunnableMethod<Endpoint<PVRManagerParent>&&>( 92 "gfx::VRManagerParent::Bind", vmp, &VRManagerParent::Bind, 93 std::move(aEndpoint))); 94 95 return true; 96 } 97 98 void VRManagerParent::Bind(Endpoint<PVRManagerParent>&& aEndpoint) { 99 if (!aEndpoint.Bind(this)) { 100 return; 101 } 102 mCompositorThreadHolder = CompositorThreadHolder::GetSingleton(); 103 104 RegisterWithManager(); 105 } 106 107 /*static*/ 108 void VRManagerParent::RegisterVRManagerInCompositorThread( 109 VRManagerParent* aVRManager) { 110 aVRManager->RegisterWithManager(); 111 } 112 113 /*static*/ 114 already_AddRefed<VRManagerParent> VRManagerParent::CreateSameProcess() { 115 RefPtr<VRManagerParent> vmp = new VRManagerParent( 116 ipc::EndpointProcInfo::Current(), dom::ContentParentId(), false); 117 vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton(); 118 CompositorThread()->Dispatch( 119 NewRunnableFunction("RegisterVRManagerIncompositorThreadRunnable", 120 RegisterVRManagerInCompositorThread, vmp.get())); 121 return vmp.forget(); 122 } 123 124 bool VRManagerParent::CreateForGPUProcess( 125 Endpoint<PVRManagerParent>&& aEndpoint) { 126 RefPtr<VRManagerParent> vmp = new VRManagerParent( 127 aEndpoint.OtherEndpointProcInfo(), dom::ContentParentId(), false); 128 vmp->mCompositorThreadHolder = CompositorThreadHolder::GetSingleton(); 129 CompositorThread()->Dispatch(NewRunnableMethod<Endpoint<PVRManagerParent>&&>( 130 "gfx::VRManagerParent::Bind", vmp, &VRManagerParent::Bind, 131 std::move(aEndpoint))); 132 return true; 133 } 134 135 /*static*/ 136 void VRManagerParent::Shutdown() { 137 MOZ_ASSERT(NS_IsMainThread()); 138 MOZ_ASSERT( 139 CompositorThread(), 140 "Shutdown() must gets called before the compositor thread is shutdown"); 141 ReleaseVRManagerParentSingleton(); 142 CompositorThread()->Dispatch(NS_NewRunnableFunction( 143 "VRManagerParent::Shutdown", 144 [vm = RefPtr<VRManager>(VRManager::MaybeGet())]() -> void { 145 if (!vm) { 146 return; 147 } 148 vm->ShutdownVRManagerParents(); 149 })); 150 } 151 152 void VRManagerParent::ActorDestroy(ActorDestroyReason why) { 153 UnregisterFromManager(); 154 mCompositorThreadHolder = nullptr; 155 } 156 157 mozilla::ipc::IPCResult VRManagerParent::RecvDetectRuntimes() { 158 // Detect runtime capabilities. This will return the presense of VR and/or AR 159 // runtime software, without enumerating or activating any hardware devices. 160 // UpdateDisplayInfo will be sent to VRManagerChild with the results of the 161 // detection. 162 VRManager* vm = VRManager::Get(); 163 vm->DetectRuntimes(); 164 165 return IPC_OK(); 166 } 167 168 mozilla::ipc::IPCResult VRManagerParent::RecvRefreshDisplays() { 169 // This is called to activate the VR runtimes, detecting the 170 // presence and capabilities of XR hardware. 171 // UpdateDisplayInfo will be sent to VRManagerChild with the results of the 172 // enumerated hardware. 173 VRManager* vm = VRManager::Get(); 174 vm->EnumerateDevices(); 175 176 return IPC_OK(); 177 } 178 179 mozilla::ipc::IPCResult VRManagerParent::RecvSetGroupMask( 180 const uint32_t& aDisplayID, const uint32_t& aGroupMask) { 181 VRManager* vm = VRManager::Get(); 182 vm->SetGroupMask(aGroupMask); 183 return IPC_OK(); 184 } 185 186 bool VRManagerParent::HaveEventListener() { return mHaveEventListener; } 187 188 bool VRManagerParent::HaveControllerListener() { 189 return mHaveControllerListener; 190 } 191 192 bool VRManagerParent::GetVRActiveStatus() { return mVRActiveStatus; } 193 194 mozilla::ipc::IPCResult VRManagerParent::RecvSetHaveEventListener( 195 const bool& aHaveEventListener) { 196 mHaveEventListener = aHaveEventListener; 197 return IPC_OK(); 198 } 199 200 mozilla::ipc::IPCResult VRManagerParent::RecvControllerListenerAdded() { 201 // Force update the available controllers for GamepadManager, 202 VRManager* vm = VRManager::Get(); 203 vm->StopAllHaptics(); 204 mHaveControllerListener = true; 205 return IPC_OK(); 206 } 207 208 mozilla::ipc::IPCResult VRManagerParent::RecvControllerListenerRemoved() { 209 mHaveControllerListener = false; 210 VRManager* vm = VRManager::Get(); 211 vm->StopAllHaptics(); 212 return IPC_OK(); 213 } 214 215 mozilla::ipc::IPCResult VRManagerParent::RecvRunPuppet( 216 const nsTArray<uint64_t>& aBuffer) { 217 #if defined(MOZ_WIDGET_ANDROID) 218 // Not yet implemented for Android / GeckoView 219 // See Bug 1555192 220 (void)SendNotifyPuppetCommandBufferCompleted(false); 221 #else 222 VRManager* vm = VRManager::Get(); 223 if (!vm->RunPuppet(aBuffer, this)) { 224 // We have immediately failed, need to resolve the 225 // promise right away 226 (void)SendNotifyPuppetCommandBufferCompleted(false); 227 } 228 #endif // defined(MOZ_WIDGET_ANDROID) 229 return IPC_OK(); 230 } 231 232 mozilla::ipc::IPCResult VRManagerParent::RecvResetPuppet() { 233 #if defined(MOZ_WIDGET_ANDROID) 234 // Not yet implemented for Android / GeckoView 235 // See Bug 1555192 236 #else 237 VRManager* vm = VRManager::Get(); 238 vm->ResetPuppet(this); 239 #endif // defined(MOZ_WIDGET_ANDROID) 240 return IPC_OK(); 241 } 242 243 mozilla::ipc::IPCResult VRManagerParent::RecvVibrateHaptic( 244 const mozilla::dom::GamepadHandle& aGamepadHandle, 245 const uint32_t& aHapticIndex, const double& aIntensity, 246 const double& aDuration, const uint32_t& aPromiseID) { 247 VRManager* vm = VRManager::Get(); 248 VRManagerPromise promise(this, aPromiseID); 249 250 vm->VibrateHaptic(aGamepadHandle, aHapticIndex, aIntensity, aDuration, 251 promise); 252 return IPC_OK(); 253 } 254 255 mozilla::ipc::IPCResult VRManagerParent::RecvStopVibrateHaptic( 256 const mozilla::dom::GamepadHandle& aGamepadHandle) { 257 VRManager* vm = VRManager::Get(); 258 vm->StopVibrateHaptic(aGamepadHandle); 259 return IPC_OK(); 260 } 261 262 bool VRManagerParent::SendReplyGamepadVibrateHaptic( 263 const uint32_t& aPromiseID) { 264 // GamepadManager only exists at the content process 265 // or the same process in non-e10s mode. 266 if (mHaveControllerListener && (mIsContentChild || IsSameProcess())) { 267 return PVRManagerParent::SendReplyGamepadVibrateHaptic(aPromiseID); 268 } 269 270 return true; 271 } 272 273 mozilla::ipc::IPCResult VRManagerParent::RecvStartVRNavigation( 274 const uint32_t& aDeviceID) { 275 VRManager* vm = VRManager::Get(); 276 vm->StartVRNavigation(aDeviceID); 277 return IPC_OK(); 278 } 279 280 mozilla::ipc::IPCResult VRManagerParent::RecvStopVRNavigation( 281 const uint32_t& aDeviceID, const TimeDuration& aTimeout) { 282 VRManager* vm = VRManager::Get(); 283 vm->StopVRNavigation(aDeviceID, aTimeout); 284 return IPC_OK(); 285 } 286 287 mozilla::ipc::IPCResult VRManagerParent::RecvStartActivity() { 288 mVRActiveStatus = true; 289 return IPC_OK(); 290 } 291 292 mozilla::ipc::IPCResult VRManagerParent::RecvStopActivity() { 293 mVRActiveStatus = false; 294 return IPC_OK(); 295 } 296 297 } // namespace gfx 298 } // namespace mozilla