Bug 1299937 - Part 4: Handling vibrate haptic promise in VRManager; r?qdot
MozReview-Commit-ID: 3KZ8MNx3Dnq
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -55,17 +55,18 @@ const uint32_t VR_GAMEPAD_IDX_OFFSET = 0
} // namespace
NS_IMPL_ISUPPORTS(GamepadManager, nsIObserver)
GamepadManager::GamepadManager()
: mEnabled(false),
mNonstandardEventsEnabled(false),
- mShuttingDown(false)
+ mShuttingDown(false),
+ mPromiseID(0)
{}
nsresult
GamepadManager::Init()
{
mEnabled = IsAPIEnabled();
mNonstandardEventsEnabled =
Preferences::GetBool(kGamepadEventsEnabledPref, false);
@@ -662,27 +663,39 @@ GamepadManager::Update(const GamepadChan
NewPoseEvent(a.index(), a.service_type(), a.pose_state());
return;
}
MOZ_CRASH("We shouldn't be here!");
}
-void
+already_AddRefed<Promise>
GamepadManager::VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
- double aIntensity, double aDuration)
+ double aIntensity, double aDuration,
+ nsIGlobalObject* aGlobal, ErrorResult& aRv)
{
+ RefPtr<Promise> 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
void
GamepadManager::ActorCreated(PBackgroundChild *aActor)
{
MOZ_ASSERT(aActor);
GamepadEventChannelChild *child = new GamepadEventChannelChild();
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -80,18 +80,19 @@ class GamepadManager final : public nsIO
// Returns gamepad object if index exists, null otherwise
already_AddRefed<Gamepad> GetGamepad(uint32_t aIndex) const;
// Receive GamepadChangeEvent messages from parent process to fire DOM events
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<Promise> VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
+ double aIntensity, double aDuration,
+ nsIGlobalObject* aGlobal, ErrorResult& aRv);
protected:
GamepadManager();
~GamepadManager() {};
// Fire a gamepadconnected or gamepaddisconnected event for the gamepad
// at |aIndex| to all windows that are listening and have received
// gamepad input.
@@ -148,14 +149,15 @@ class GamepadManager final : public nsIO
uint32_t GetGamepadIndexWithServiceType(uint32_t aIndex, GamepadServiceType aServiceType);
// Gamepads connected to the system. Copies of these are handed out
// to each window.
nsRefPtrHashtable<nsUint32HashKey, Gamepad> mGamepads;
// Inner windows that are listening for gamepad events.
// has been sent to that window.
nsTArray<RefPtr<nsGlobalWindow>> mListeners;
+ uint32_t mPromiseID;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_GamepadManager_h_
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -409,18 +409,19 @@ VRManager::NotifyGamepadChange(const T&
for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) {
Unused << iter.Get()->GetKey()->SendGamepadUpdate(e);
}
}
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);
}
}
} // namespace gfx
} // namespace mozilla
--- a/gfx/vr/VRManager.h
+++ b/gfx/vr/VRManager.h
@@ -45,17 +45,17 @@ public:
void SubmitFrame(VRLayerParent* aLayer, layers::PTextureParent* aTexture,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect);
RefPtr<gfx::VRControllerHost> GetController(const uint32_t& aControllerID);
void GetVRControllerInfo(nsTArray<VRControllerInfo>& aControllerInfo);
void CreateVRTestSystem();
void VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
- double aIntensity, double aDuration);
+ double aIntensity, double aDuration, uint32_t aPromiseID);
protected:
VRManager();
~VRManager();
private:
RefPtr<layers::TextureHost> mLastFrame;
--- a/gfx/vr/ipc/PVRManager.ipdl
+++ b/gfx/vr/ipc/PVRManager.ipdl
@@ -54,17 +54,17 @@ parent:
async ResetSensor(uint32_t aDisplayID);
sync GetSensorState(uint32_t aDisplayID) returns(VRHMDSensorState aState);
sync SetHaveEventListener(bool aHaveEventListener);
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);
async CreateVRServiceTestController(nsCString aID, uint32_t aPromiseID);
async SetDisplayInfoToMockDisplay(uint32_t aDeviceID, VRDisplayInfo aDisplayInfo);
async SetSensorStateToMockDisplay(uint32_t aDeviceID, VRHMDSensorState aSensorState);
async NewButtonEventToMockController(uint32_t aDeviceID, long aButton,
@@ -81,16 +81,18 @@ child:
// be sent to all children when the parent receives RefreshDisplays, even
// if no changes have been detected. This ensures that Promises exposed
// through DOM calls are always resolved.
async UpdateDisplayInfo(VRDisplayInfo[] aDisplayUpdates);
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,
uint32_t aDeviceID);
async __delete__();
};
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -682,10 +682,30 @@ VRManagerChild::RemoveListener(dom::VREv
}
void
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<dom::Promise> 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
--- a/gfx/vr/ipc/VRManagerChild.h
+++ b/gfx/vr/ipc/VRManagerChild.h
@@ -12,16 +12,17 @@
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
#include "mozilla/layers/LayersTypes.h" // for LayersBackend
#include "mozilla/layers/TextureForwarder.h"
namespace mozilla {
namespace dom {
+class Promise;
class GamepadManager;
class Navigator;
class VRDisplay;
class VREventObserver;
class VRMockDisplay;
} // namespace dom
namespace layers {
class TextureClient;
@@ -45,16 +46,18 @@ public:
// Indicate that an observer wants to receive VR events.
void AddListener(dom::VREventObserver* aObserver);
// Indicate that an observer should no longer receive VR events.
void RemoveListener(dom::VREventObserver* aObserver);
int GetInputFrameID();
bool GetVRDisplays(nsTArray<RefPtr<VRDisplayClient> >& 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);
static void InitSameProcess();
static void InitWithGPUProcess(Endpoint<PVRManagerChild>&& aEndpoint);
static bool InitForContent(Endpoint<PVRManagerChild>&& aEndpoint);
static bool ReinitForContent(Endpoint<PVRManagerChild>&& aEndpoint);
static void ShutDown();
@@ -115,16 +118,18 @@ protected:
virtual mozilla::ipc::IPCResult RecvUpdateDisplayInfo(nsTArray<VRDisplayInfo>&& aDisplayUpdates) override;
virtual mozilla::ipc::IPCResult RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
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;
virtual mozilla::ipc::IPCResult RecvReplyCreateVRServiceTestController(const nsCString& aID,
const uint32_t& aPromiseID,
const uint32_t& aDeviceID) override;
// ShmemAllocator
@@ -181,16 +186,17 @@ private:
/**
* Hold TextureClients refs until end of their usages on host side.
* It defer calling of TextureClient recycle callback.
*/
nsDataHashtable<nsUint64HashKey, RefPtr<layers::TextureClient> > mTexturesWaitingRecycled;
layers::LayersBackend mBackend;
RefPtr<layers::SyncObject> mSyncObject;
+ nsRefPtrHashtable<nsUint32HashKey, dom::Promise> mGamepadPromiseList; // TODO: check if it can merge into one list?
uint32_t mPromiseID;
nsRefPtrHashtable<nsUint32HashKey, dom::Promise> mPromiseList;
RefPtr<dom::VRMockDisplay> mVRMockDisplay;
DISALLOW_COPY_AND_ASSIGN(VRManagerChild);
};
} // namespace mozilla
--- a/gfx/vr/ipc/VRManagerParent.cpp
+++ b/gfx/vr/ipc/VRManagerParent.cpp
@@ -445,21 +445,22 @@ VRManagerParent::RecvNewPoseMoveToMockCo
controllerPuppet->SetPoseMoveState(pose);
return IPC_OK();
}
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();
}
bool
VRManagerParent::SendGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
{
// GamepadManager only exists at the content process
// or the same process in non-e10s mode.
--- a/gfx/vr/ipc/VRManagerParent.h
+++ b/gfx/vr/ipc/VRManagerParent.h
@@ -88,17 +88,18 @@ protected:
virtual mozilla::ipc::IPCResult RecvRefreshDisplays() override;
virtual mozilla::ipc::IPCResult RecvGetDisplays(nsTArray<VRDisplayInfo> *aDisplays) override;
virtual mozilla::ipc::IPCResult RecvResetSensor(const uint32_t& aDisplayID) override;
virtual mozilla::ipc::IPCResult RecvGetSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState) override;
virtual mozilla::ipc::IPCResult RecvSetHaveEventListener(const bool& aHaveEventListener) override;
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;
virtual mozilla::ipc::IPCResult RecvSetDisplayInfoToMockDisplay(const uint32_t& aDeviceID,
const VRDisplayInfo& aDisplayInfo) override;
virtual mozilla::ipc::IPCResult RecvSetSensorStateToMockDisplay(const uint32_t& aDeviceID,
const VRHMDSensorState& aSensorState) override;
virtual mozilla::ipc::IPCResult RecvNewButtonEventToMockController(const uint32_t& aDeviceID, const long& aButton,