Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: sw=2 ts=8 et :
3 : */
4 : /* This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 :
8 : #include "VRManagerParent.h"
9 : #include "ipc/VRLayerParent.h"
10 : #include "mozilla/gfx/PVRManagerParent.h"
11 : #include "mozilla/ipc/ProtocolTypes.h"
12 : #include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
13 : #include "mozilla/TimeStamp.h" // for TimeStamp
14 : #include "mozilla/layers/CompositorThread.h"
15 : #include "mozilla/Unused.h"
16 : #include "VRManager.h"
17 : #include "gfxVRPuppet.h"
18 :
19 : namespace mozilla {
20 : using namespace layers;
21 : namespace gfx {
22 :
23 3 : VRManagerParent::VRManagerParent(ProcessId aChildProcessId, bool aIsContentChild)
24 : : HostIPCAllocator()
25 : , mDisplayTestID(0)
26 : , mControllerTestID(0)
27 : , mHaveEventListener(false)
28 : , mHaveControllerListener(false)
29 3 : , mIsContentChild(aIsContentChild)
30 : {
31 3 : MOZ_COUNT_CTOR(VRManagerParent);
32 3 : MOZ_ASSERT(NS_IsMainThread());
33 :
34 3 : SetOtherProcessId(aChildProcessId);
35 3 : }
36 :
37 0 : VRManagerParent::~VRManagerParent()
38 : {
39 0 : MOZ_ASSERT(!mVRManagerHolder);
40 :
41 0 : MOZ_COUNT_DTOR(VRManagerParent);
42 0 : }
43 :
44 : PTextureParent*
45 0 : VRManagerParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
46 : const LayersBackend& aLayersBackend,
47 : const TextureFlags& aFlags,
48 : const uint64_t& aSerial)
49 : {
50 0 : return layers::TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial, Nothing());
51 : }
52 :
53 : bool
54 0 : VRManagerParent::DeallocPTextureParent(PTextureParent* actor)
55 : {
56 0 : return layers::TextureHost::DestroyIPDLActor(actor);
57 : }
58 :
59 : PVRLayerParent*
60 0 : VRManagerParent::AllocPVRLayerParent(const uint32_t& aDisplayID,
61 : const float& aLeftEyeX,
62 : const float& aLeftEyeY,
63 : const float& aLeftEyeWidth,
64 : const float& aLeftEyeHeight,
65 : const float& aRightEyeX,
66 : const float& aRightEyeY,
67 : const float& aRightEyeWidth,
68 : const float& aRightEyeHeight,
69 : const uint32_t& aGroup)
70 : {
71 0 : RefPtr<VRLayerParent> layer;
72 : layer = new VRLayerParent(aDisplayID,
73 0 : Rect(aLeftEyeX, aLeftEyeY, aLeftEyeWidth, aLeftEyeHeight),
74 0 : Rect(aRightEyeX, aRightEyeY, aRightEyeWidth, aRightEyeHeight),
75 0 : aGroup);
76 0 : VRManager* vm = VRManager::Get();
77 0 : RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
78 0 : if (display) {
79 0 : display->AddLayer(layer);
80 : }
81 0 : return layer.forget().take();
82 : }
83 :
84 : bool
85 0 : VRManagerParent::DeallocPVRLayerParent(PVRLayerParent* actor)
86 : {
87 0 : delete actor;
88 0 : return true;
89 : }
90 :
91 : bool
92 0 : VRManagerParent::AllocShmem(size_t aSize,
93 : ipc::SharedMemory::SharedMemoryType aType,
94 : ipc::Shmem* aShmem)
95 : {
96 0 : return PVRManagerParent::AllocShmem(aSize, aType, aShmem);
97 : }
98 :
99 : bool
100 0 : VRManagerParent::AllocUnsafeShmem(size_t aSize,
101 : ipc::SharedMemory::SharedMemoryType aType,
102 : ipc::Shmem* aShmem)
103 : {
104 0 : return PVRManagerParent::AllocUnsafeShmem(aSize, aType, aShmem);
105 : }
106 :
107 : void
108 0 : VRManagerParent::DeallocShmem(ipc::Shmem& aShmem)
109 : {
110 0 : PVRManagerParent::DeallocShmem(aShmem);
111 0 : }
112 :
113 : bool
114 0 : VRManagerParent::IsSameProcess() const
115 : {
116 0 : return OtherPid() == base::GetCurrentProcId();
117 : }
118 :
119 : void
120 0 : VRManagerParent::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
121 : {
122 0 : MOZ_ASSERT_UNREACHABLE("unexpected to be called");
123 : }
124 :
125 : void
126 0 : VRManagerParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
127 : {
128 0 : MOZ_ASSERT_UNREACHABLE("unexpected to be called");
129 : }
130 :
131 : base::ProcessId
132 0 : VRManagerParent::GetChildProcessId()
133 : {
134 0 : return OtherPid();
135 : }
136 :
137 : void
138 3 : VRManagerParent::RegisterWithManager()
139 : {
140 3 : VRManager* vm = VRManager::Get();
141 3 : vm->AddVRManagerParent(this);
142 3 : mVRManagerHolder = vm;
143 3 : }
144 :
145 : void
146 0 : VRManagerParent::UnregisterFromManager()
147 : {
148 0 : VRManager* vm = VRManager::Get();
149 0 : vm->RemoveVRManagerParent(this);
150 0 : mVRManagerHolder = nullptr;
151 0 : }
152 :
153 : /* static */ bool
154 2 : VRManagerParent::CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint)
155 : {
156 2 : MessageLoop* loop = layers::CompositorThreadHolder::Loop();
157 :
158 6 : RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), true);
159 4 : loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
160 : "gfx::VRManagerParent::Bind",
161 : vmp,
162 : &VRManagerParent::Bind,
163 4 : Move(aEndpoint)));
164 :
165 4 : return true;
166 : }
167 :
168 : void
169 2 : VRManagerParent::Bind(Endpoint<PVRManagerParent>&& aEndpoint)
170 : {
171 2 : if (!aEndpoint.Bind(this)) {
172 0 : return;
173 : }
174 2 : mSelfRef = this;
175 :
176 2 : RegisterWithManager();
177 : }
178 :
179 : /*static*/ void
180 1 : VRManagerParent::RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager)
181 : {
182 1 : aVRManager->RegisterWithManager();
183 1 : }
184 :
185 : /*static*/ VRManagerParent*
186 1 : VRManagerParent::CreateSameProcess()
187 : {
188 1 : MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
189 3 : RefPtr<VRManagerParent> vmp = new VRManagerParent(base::GetCurrentProcId(), false);
190 1 : vmp->mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
191 1 : vmp->mSelfRef = vmp;
192 1 : loop->PostTask(NewRunnableFunction(RegisterVRManagerInCompositorThread, vmp.get()));
193 2 : return vmp.get();
194 : }
195 :
196 : bool
197 0 : VRManagerParent::CreateForGPUProcess(Endpoint<PVRManagerParent>&& aEndpoint)
198 : {
199 0 : MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
200 :
201 0 : RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), false);
202 0 : vmp->mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
203 0 : loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
204 : "gfx::VRManagerParent::Bind",
205 : vmp,
206 : &VRManagerParent::Bind,
207 0 : Move(aEndpoint)));
208 0 : return true;
209 : }
210 :
211 : void
212 0 : VRManagerParent::DeferredDestroy()
213 : {
214 0 : mCompositorThreadHolder = nullptr;
215 0 : mSelfRef = nullptr;
216 0 : }
217 :
218 : void
219 0 : VRManagerParent::ActorDestroy(ActorDestroyReason why)
220 : {
221 0 : UnregisterFromManager();
222 0 : MessageLoop::current()->PostTask(
223 0 : NewRunnableMethod("gfx::VRManagerParent::DeferredDestroy",
224 : this,
225 0 : &VRManagerParent::DeferredDestroy));
226 0 : }
227 :
228 : void
229 1 : VRManagerParent::OnChannelConnected(int32_t aPid)
230 : {
231 1 : mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
232 1 : }
233 :
234 : mozilla::ipc::IPCResult
235 0 : VRManagerParent::RecvRefreshDisplays()
236 : {
237 : // This is called to refresh the VR Displays for Navigator.GetVRDevices().
238 : // We must pass "true" to VRManager::RefreshVRDisplays()
239 : // to ensure that the promise returned by Navigator.GetVRDevices
240 : // can resolve even if there are no changes to the VR Displays.
241 0 : VRManager* vm = VRManager::Get();
242 0 : vm->RefreshVRDisplays(true);
243 :
244 0 : return IPC_OK();
245 : }
246 :
247 : mozilla::ipc::IPCResult
248 0 : VRManagerParent::RecvResetSensor(const uint32_t& aDisplayID)
249 : {
250 0 : VRManager* vm = VRManager::Get();
251 0 : RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
252 0 : if (display != nullptr) {
253 0 : display->ZeroSensor();
254 : }
255 :
256 0 : return IPC_OK();
257 : }
258 :
259 : mozilla::ipc::IPCResult
260 0 : VRManagerParent::RecvSetGroupMask(const uint32_t& aDisplayID, const uint32_t& aGroupMask)
261 : {
262 0 : VRManager* vm = VRManager::Get();
263 0 : RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
264 0 : if (display != nullptr) {
265 0 : display->SetGroupMask(aGroupMask);
266 : }
267 0 : return IPC_OK();
268 : }
269 :
270 : bool
271 304 : VRManagerParent::HaveEventListener()
272 : {
273 304 : return mHaveEventListener;
274 : }
275 :
276 : bool
277 304 : VRManagerParent::HaveControllerListener()
278 : {
279 304 : return mHaveControllerListener;
280 : }
281 :
282 : mozilla::ipc::IPCResult
283 0 : VRManagerParent::RecvSetHaveEventListener(const bool& aHaveEventListener)
284 : {
285 0 : mHaveEventListener = aHaveEventListener;
286 0 : return IPC_OK();
287 : }
288 :
289 : mozilla::ipc::IPCResult
290 0 : VRManagerParent::RecvControllerListenerAdded()
291 : {
292 0 : VRManager* vm = VRManager::Get();
293 0 : mHaveControllerListener = true;
294 : // Ask the connected gamepads to be added to GamepadManager
295 0 : vm->ScanForControllers();
296 0 : return IPC_OK();
297 : }
298 :
299 : mozilla::ipc::IPCResult
300 0 : VRManagerParent::RecvControllerListenerRemoved()
301 : {
302 0 : VRManager* vm = VRManager::Get();
303 0 : mHaveControllerListener = false;
304 0 : vm->RemoveControllers();
305 0 : return IPC_OK();
306 : }
307 :
308 : mozilla::ipc::IPCResult
309 0 : VRManagerParent::RecvCreateVRTestSystem()
310 : {
311 0 : VRManager* vm = VRManager::Get();
312 0 : vm->CreateVRTestSystem();
313 0 : return IPC_OK();
314 : }
315 :
316 : mozilla::ipc::IPCResult
317 0 : VRManagerParent::RecvCreateVRServiceTestDisplay(const nsCString& aID, const uint32_t& aPromiseID)
318 : {
319 0 : nsTArray<VRDisplayInfo> displayInfoArray;
320 0 : impl::VRDisplayPuppet* displayPuppet = nullptr;
321 0 : VRManager* vm = VRManager::Get();
322 0 : vm->RefreshVRDisplays();
323 :
324 : // Get VRDisplayPuppet from VRManager
325 0 : vm->GetVRDisplayInfo(displayInfoArray);
326 0 : for (auto& displayInfo : displayInfoArray) {
327 0 : if (displayInfo.GetType() == VRDeviceType::Puppet) {
328 0 : displayPuppet = static_cast<impl::VRDisplayPuppet*>(
329 0 : vm->GetDisplay(displayInfo.GetDisplayID()).get());
330 0 : break;
331 : }
332 : }
333 :
334 0 : MOZ_ASSERT(displayPuppet);
335 0 : MOZ_ASSERT(!mDisplayTestID); // We have only one display in VRSystemManagerPuppet.
336 :
337 0 : if (!mVRDisplayTests.Get(mDisplayTestID, nullptr)) {
338 0 : mVRDisplayTests.Put(mDisplayTestID, displayPuppet);
339 : }
340 :
341 0 : if (SendReplyCreateVRServiceTestDisplay(aID, aPromiseID, mDisplayTestID)) {
342 0 : return IPC_OK();
343 : }
344 :
345 0 : return IPC_FAIL(this, "SendReplyCreateVRServiceTestController fail");
346 : }
347 :
348 : mozilla::ipc::IPCResult
349 0 : VRManagerParent::RecvCreateVRServiceTestController(const nsCString& aID, const uint32_t& aPromiseID)
350 : {
351 0 : uint32_t controllerIdx = 0;
352 0 : nsTArray<VRControllerInfo> controllerInfoArray;
353 0 : impl::VRControllerPuppet* controllerPuppet = nullptr;
354 0 : VRManager* vm = VRManager::Get();
355 :
356 : // Get VRControllerPuppet from VRManager
357 0 : vm->GetVRControllerInfo(controllerInfoArray);
358 0 : for (auto& controllerInfo : controllerInfoArray) {
359 0 : if (controllerInfo.GetType() == VRDeviceType::Puppet) {
360 0 : if (controllerIdx == mControllerTestID) {
361 0 : controllerPuppet = static_cast<impl::VRControllerPuppet*>(
362 0 : vm->GetController(controllerInfo.GetControllerID()).get());
363 0 : break;
364 : }
365 0 : ++controllerIdx;
366 : }
367 : }
368 :
369 0 : MOZ_ASSERT(controllerPuppet);
370 0 : MOZ_ASSERT(mControllerTestID < 2); // We have only two controllers in VRSystemManagerPuppet.
371 :
372 0 : if (!mVRControllerTests.Get(mControllerTestID, nullptr)) {
373 0 : mVRControllerTests.Put(mControllerTestID, controllerPuppet);
374 : }
375 :
376 0 : if (SendReplyCreateVRServiceTestController(aID, aPromiseID, mControllerTestID)) {
377 0 : ++mControllerTestID;
378 0 : return IPC_OK();
379 : }
380 :
381 0 : return IPC_FAIL(this, "SendReplyCreateVRServiceTestController fail");
382 : }
383 :
384 : mozilla::ipc::IPCResult
385 0 : VRManagerParent::RecvSetDisplayInfoToMockDisplay(const uint32_t& aDeviceID,
386 : const VRDisplayInfo& aDisplayInfo)
387 : {
388 0 : RefPtr<impl::VRDisplayPuppet> displayPuppet;
389 0 : mVRDisplayTests.Get(mDisplayTestID,
390 0 : getter_AddRefs(displayPuppet));
391 0 : MOZ_ASSERT(displayPuppet);
392 0 : displayPuppet->SetDisplayInfo(aDisplayInfo);
393 0 : return IPC_OK();
394 : }
395 :
396 : mozilla::ipc::IPCResult
397 0 : VRManagerParent::RecvSetSensorStateToMockDisplay(const uint32_t& aDeviceID,
398 : const VRHMDSensorState& aSensorState)
399 : {
400 0 : RefPtr<impl::VRDisplayPuppet> displayPuppet;
401 0 : mVRDisplayTests.Get(mDisplayTestID,
402 0 : getter_AddRefs(displayPuppet));
403 0 : MOZ_ASSERT(displayPuppet);
404 0 : displayPuppet->SetSensorState(aSensorState);
405 0 : return IPC_OK();
406 : }
407 :
408 : mozilla::ipc::IPCResult
409 0 : VRManagerParent::RecvNewButtonEventToMockController(const uint32_t& aDeviceID, const long& aButton,
410 : const bool& aPressed)
411 : {
412 0 : RefPtr<impl::VRControllerPuppet> controllerPuppet;
413 0 : mVRControllerTests.Get(mControllerTestID,
414 0 : getter_AddRefs(controllerPuppet));
415 0 : MOZ_ASSERT(controllerPuppet);
416 0 : controllerPuppet->SetButtonPressState(aButton, aPressed);
417 0 : return IPC_OK();
418 : }
419 :
420 : mozilla::ipc::IPCResult
421 0 : VRManagerParent::RecvNewAxisMoveEventToMockController(const uint32_t& aDeviceID, const long& aAxis,
422 : const double& aValue)
423 : {
424 0 : RefPtr<impl::VRControllerPuppet> controllerPuppet;
425 0 : mVRControllerTests.Get(mControllerTestID,
426 0 : getter_AddRefs(controllerPuppet));
427 0 : MOZ_ASSERT(controllerPuppet);
428 0 : controllerPuppet->SetAxisMoveState(aAxis, aValue);
429 0 : return IPC_OK();
430 : }
431 :
432 : mozilla::ipc::IPCResult
433 0 : VRManagerParent::RecvNewPoseMoveToMockController(const uint32_t& aDeviceID,
434 : const GamepadPoseState& pose)
435 : {
436 0 : RefPtr<impl::VRControllerPuppet> controllerPuppet;
437 0 : mVRControllerTests.Get(mControllerTestID,
438 0 : getter_AddRefs(controllerPuppet));
439 0 : MOZ_ASSERT(controllerPuppet);
440 0 : controllerPuppet->SetPoseMoveState(pose);
441 0 : return IPC_OK();
442 : }
443 :
444 : mozilla::ipc::IPCResult
445 0 : VRManagerParent::RecvVibrateHaptic(const uint32_t& aControllerIdx,
446 : const uint32_t& aHapticIndex,
447 : const double& aIntensity,
448 : const double& aDuration,
449 : const uint32_t& aPromiseID)
450 : {
451 0 : VRManager* vm = VRManager::Get();
452 0 : vm->VibrateHaptic(aControllerIdx, aHapticIndex, aIntensity,
453 0 : aDuration, aPromiseID);
454 0 : return IPC_OK();
455 : }
456 :
457 : mozilla::ipc::IPCResult
458 0 : VRManagerParent::RecvStopVibrateHaptic(const uint32_t& aControllerIdx)
459 : {
460 0 : VRManager* vm = VRManager::Get();
461 0 : vm->StopVibrateHaptic(aControllerIdx);
462 0 : return IPC_OK();
463 : }
464 :
465 : bool
466 0 : VRManagerParent::SendGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
467 : {
468 : // GamepadManager only exists at the content process
469 : // or the same process in non-e10s mode.
470 0 : if (mHaveControllerListener &&
471 0 : (mIsContentChild || IsSameProcess())) {
472 0 : return PVRManagerParent::SendGamepadUpdate(aGamepadEvent);
473 : } else {
474 0 : return true;
475 : }
476 : }
477 :
478 : bool
479 0 : VRManagerParent::SendReplyGamepadVibrateHaptic(const uint32_t& aPromiseID)
480 : {
481 : // GamepadManager only exists at the content process
482 : // or the same process in non-e10s mode.
483 0 : if (mHaveControllerListener &&
484 0 : (mIsContentChild || IsSameProcess())) {
485 0 : return PVRManagerParent::SendReplyGamepadVibrateHaptic(aPromiseID);
486 : } else {
487 0 : return true;
488 : }
489 : }
490 :
491 : } // namespace gfx
492 9 : } // namespace mozilla
|