diff --git a/dom/gamepad/GamepadManager.cpp b/dom/gamepad/GamepadManager.cpp index 4e2eaf5f6d4d..dfccc38974f7 100644 --- a/dom/gamepad/GamepadManager.cpp +++ b/dom/gamepad/GamepadManager.cpp @@ -60,7 +60,8 @@ NS_IMPL_ISUPPORTS(GamepadManager, nsIObserver) GamepadManager::GamepadManager() : mEnabled(false), mNonstandardEventsEnabled(false), - mShuttingDown(false) + mShuttingDown(false), + mPromiseID(0) {} nsresult @@ -667,17 +668,29 @@ GamepadManager::Update(const GamepadChangeEvent& aEvent) } -void +already_AddRefed GamepadManager::VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex, - double aIntensity, double aDuration) + double aIntensity, double aDuration, + nsIGlobalObject* aGlobal, ErrorResult& aRv) { + RefPtr promise = Promise::Create(aGlobal, aRv); + if (NS_WARN_IF(aRv.Failed())) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + if (aControllerIdx >= VR_GAMEPAD_IDX_OFFSET) { uint32_t index = aControllerIdx - VR_GAMEPAD_IDX_OFFSET; + mVRChannelChild->AddPromise(mPromiseID, promise); mVRChannelChild->SendVibrateHaptic(index, aHapticIndex, - aIntensity, aDuration); + aIntensity, aDuration, + mPromiseID); } else { // TODO: Bug 680289, implement for standard gamepads } + + ++mPromiseID; + return promise.forget(); } //Override nsIIPCBackgroundChildCreateCallback diff --git a/dom/gamepad/GamepadManager.h b/dom/gamepad/GamepadManager.h index 24864a0df07c..73059caf1f7f 100644 --- a/dom/gamepad/GamepadManager.h +++ b/dom/gamepad/GamepadManager.h @@ -85,8 +85,9 @@ class GamepadManager final : public nsIObserver, void Update(const GamepadChangeEvent& aGamepadEvent); // Trigger vibrate haptic event to gamepad channels. - void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex, - double aIntensity, double aDuration); + already_AddRefed VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex, + double aIntensity, double aDuration, + nsIGlobalObject* aGlobal, ErrorResult& aRv); protected: GamepadManager(); @@ -153,6 +154,7 @@ class GamepadManager final : public nsIObserver, // Inner windows that are listening for gamepad events. // has been sent to that window. nsTArray> mListeners; + uint32_t mPromiseID; }; } // namespace dom diff --git a/gfx/vr/VRManager.cpp b/gfx/vr/VRManager.cpp index 6c16201b3269..aa37882435ca 100644 --- a/gfx/vr/VRManager.cpp +++ b/gfx/vr/VRManager.cpp @@ -425,11 +425,12 @@ VRManager::NotifyGamepadChange(const T& aInfo) void VRManager::VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex, - double aIntensity, double aDuration) + double aIntensity, double aDuration, uint32_t aPromiseID) + { for (uint32_t i = 0; i < mManagers.Length(); ++i) { mManagers[i]->VibrateHaptic(aControllerIdx, aHapticIndex, - aIntensity, aDuration); + aIntensity, aDuration, aPromiseID); } } diff --git a/gfx/vr/VRManager.h b/gfx/vr/VRManager.h index 8ebc0d34d302..fac47e29bba2 100644 --- a/gfx/vr/VRManager.h +++ b/gfx/vr/VRManager.h @@ -50,7 +50,7 @@ public: void GetVRControllerInfo(nsTArray& aControllerInfo); void CreateVRTestSystem(); void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex, - double aIntensity, double aDuration); + double aIntensity, double aDuration, uint32_t aPromiseID); protected: VRManager(); diff --git a/gfx/vr/ipc/PVRManager.ipdl b/gfx/vr/ipc/PVRManager.ipdl index 8d6b7123168a..7a4862c2a7f6 100644 --- a/gfx/vr/ipc/PVRManager.ipdl +++ b/gfx/vr/ipc/PVRManager.ipdl @@ -55,7 +55,7 @@ parent: async ControllerListenerAdded(); async ControllerListenerRemoved(); async VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex, - double aIntensity, double aDuration); + double aIntensity, double aDuration, uint32_t aPromiseID); async CreateVRTestSystem(); async CreateVRServiceTestDisplay(nsCString aID, uint32_t aPromiseID); @@ -82,6 +82,8 @@ child: async NotifyVSync(); async NotifyVRVSync(uint32_t aDisplayID); async GamepadUpdate(GamepadChangeEvent aGamepadEvent); + async ReplyGamepadVibrateHaptic(uint32_t aPromiseID); + async ReplyCreateVRServiceTestDisplay(nsCString aID, uint32_t aPromiseID, uint32_t aDeviceID); async ReplyCreateVRServiceTestController(nsCString aID, uint32_t aPromiseID, diff --git a/gfx/vr/ipc/VRManagerChild.cpp b/gfx/vr/ipc/VRManagerChild.cpp index d33951cb4d77..6a889518a95c 100644 --- a/gfx/vr/ipc/VRManagerChild.cpp +++ b/gfx/vr/ipc/VRManagerChild.cpp @@ -677,5 +677,25 @@ VRManagerChild::HandleFatalError(const char* aName, const char* aMsg) const dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid()); } +void +VRManagerChild::AddPromise(const uint32_t& aID, dom::Promise* aPromise) +{ + MOZ_ASSERT(!mGamepadPromiseList.Get(aID, nullptr)); + mGamepadPromiseList.Put(aID, aPromise); +} + +mozilla::ipc::IPCResult +VRManagerChild::RecvReplyGamepadVibrateHaptic(const uint32_t& aPromiseID) +{ + RefPtr p; + if (!mGamepadPromiseList.Get(aPromiseID, getter_AddRefs(p))) { + MOZ_CRASH("We should always have a promise."); + } + + p->MaybeResolve(true); + mGamepadPromiseList.Remove(aPromiseID); + return IPC_OK(); +} + } // namespace gfx } // namespace mozilla diff --git a/gfx/vr/ipc/VRManagerChild.h b/gfx/vr/ipc/VRManagerChild.h index 2fa71ed887ac..7ec8104c6435 100644 --- a/gfx/vr/ipc/VRManagerChild.h +++ b/gfx/vr/ipc/VRManagerChild.h @@ -17,6 +17,7 @@ namespace mozilla { namespace dom { +class Promise; class GamepadManager; class Navigator; class VRDisplay; @@ -50,6 +51,8 @@ public: int GetInputFrameID(); bool GetVRDisplays(nsTArray >& aDisplays); bool RefreshVRDisplaysWithCallback(uint64_t aWindowId); + void AddPromise(const uint32_t& aID, dom::Promise* aPromise); + void CreateVRServiceTestDisplay(const nsCString& aID, dom::Promise* aPromise); void CreateVRServiceTestController(const nsCString& aID, dom::Promise* aPromise); @@ -120,6 +123,8 @@ protected: virtual mozilla::ipc::IPCResult RecvNotifyVSync() override; virtual mozilla::ipc::IPCResult RecvNotifyVRVSync(const uint32_t& aDisplayID) override; virtual mozilla::ipc::IPCResult RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent) override; + virtual mozilla::ipc::IPCResult RecvReplyGamepadVibrateHaptic(const uint32_t& aPromiseID) override; + virtual mozilla::ipc::IPCResult RecvReplyCreateVRServiceTestDisplay(const nsCString& aID, const uint32_t& aPromiseID, const uint32_t& aDeviceID) override; @@ -186,6 +191,7 @@ private: layers::LayersBackend mBackend; RefPtr mSyncObject; + nsRefPtrHashtable mGamepadPromiseList; // TODO: check if it can merge into one list? uint32_t mPromiseID; nsRefPtrHashtable mPromiseList; RefPtr mVRMockDisplay; diff --git a/gfx/vr/ipc/VRManagerParent.cpp b/gfx/vr/ipc/VRManagerParent.cpp index 9e33850e00f9..2210fd65361b 100644 --- a/gfx/vr/ipc/VRManagerParent.cpp +++ b/gfx/vr/ipc/VRManagerParent.cpp @@ -442,11 +442,12 @@ mozilla::ipc::IPCResult VRManagerParent::RecvVibrateHaptic(const uint32_t& aControllerIdx, const uint32_t& aHapticIndex, const double& aIntensity, - const double& aDuration) + const double& aDuration, + const uint32_t& aPromiseID) { VRManager* vm = VRManager::Get(); vm->VibrateHaptic(aControllerIdx, aHapticIndex, aIntensity, - aDuration); + aDuration, aPromiseID); return IPC_OK(); } diff --git a/gfx/vr/ipc/VRManagerParent.h b/gfx/vr/ipc/VRManagerParent.h index de0ddd228723..8c7ded00d2b7 100644 --- a/gfx/vr/ipc/VRManagerParent.h +++ b/gfx/vr/ipc/VRManagerParent.h @@ -92,7 +92,8 @@ protected: virtual mozilla::ipc::IPCResult RecvControllerListenerAdded() override; virtual mozilla::ipc::IPCResult RecvControllerListenerRemoved() override; virtual mozilla::ipc::IPCResult RecvVibrateHaptic(const uint32_t& aControllerIdx, const uint32_t& aHapticIndex, - const double& aIntensity, const double& aDuration) override; + const double& aIntensity, const double& aDuration, const uint32_t& aPromiseID) override; + virtual mozilla::ipc::IPCResult RecvCreateVRTestSystem() override; virtual mozilla::ipc::IPCResult RecvCreateVRServiceTestDisplay(const nsCString& aID, const uint32_t& aPromiseID) override; virtual mozilla::ipc::IPCResult RecvCreateVRServiceTestController(const nsCString& aID, const uint32_t& aPromiseID) override;