Bug 1299937 - Part 2: Support gamepad haptic in GamepadManager; r?lenzak800, kip, qdot
MozReview-Commit-ID: 7duCrsFLVX6
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -201,54 +201,53 @@ GamepadManager::GetGamepad(uint32_t aInd
uint32_t GamepadManager::GetGamepadIndexWithServiceType(uint32_t aIndex,
GamepadServiceType aServiceType)
{
uint32_t newIndex = 0;
switch (aServiceType) {
case GamepadServiceType::Standard:
- {
- MOZ_ASSERT(aIndex <= VR_GAMEPAD_IDX_OFFSET);
- newIndex = aIndex;
- break;
- }
+ MOZ_ASSERT(aIndex <= VR_GAMEPAD_IDX_OFFSET);
+ newIndex = aIndex;
+ break;
case GamepadServiceType::VR:
- {
- newIndex = aIndex + VR_GAMEPAD_IDX_OFFSET;
- break;
- }
+ newIndex = aIndex + VR_GAMEPAD_IDX_OFFSET;
+ break;
default:
- MOZ_ASSERT(false);
- break;
+ MOZ_ASSERT(false);
+ break;
}
return newIndex;
}
void
GamepadManager::AddGamepad(uint32_t aIndex,
const nsAString& aId,
GamepadMappingType aMapping,
GamepadHand aHand,
GamepadServiceType aServiceType,
uint32_t aNumButtons,
- uint32_t aNumAxes)
+ uint32_t aNumAxes,
+ uint32_t aNumHaptics)
{
+ uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
+
//TODO: bug 852258: get initial button/axis state
RefPtr<Gamepad> gamepad =
new Gamepad(nullptr,
aId,
0, // index is set by global window
+ newIndex,
aMapping,
aHand,
aNumButtons,
- aNumAxes);
-
- uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
+ aNumAxes,
+ aNumHaptics);
// We store the gamepad related to its index given by the parent process,
// and no duplicate index is allowed.
MOZ_ASSERT(!mGamepads.Get(newIndex, nullptr));
mGamepads.Put(newIndex, gamepad);
NewConnectionEvent(newIndex, true);
}
@@ -633,17 +632,18 @@ void
GamepadManager::Update(const GamepadChangeEvent& aEvent)
{
if (aEvent.type() == GamepadChangeEvent::TGamepadAdded) {
const GamepadAdded& a = aEvent.get_GamepadAdded();
AddGamepad(a.index(), a.id(),
static_cast<GamepadMappingType>(a.mapping()),
static_cast<GamepadHand>(a.hand()),
a.service_type(),
- a.num_buttons(), a.num_axes());
+ a.num_buttons(), a.num_axes(),
+ a.num_haptics());
return;
}
if (aEvent.type() == GamepadChangeEvent::TGamepadRemoved) {
const GamepadRemoved& a = aEvent.get_GamepadRemoved();
RemoveGamepad(a.index(), a.service_type());
return;
}
if (aEvent.type() == GamepadChangeEvent::TGamepadButtonInformation) {
@@ -662,16 +662,29 @@ GamepadManager::Update(const GamepadChan
NewPoseEvent(a.index(), a.service_type(), a.pose_state());
return;
}
MOZ_CRASH("We shouldn't be here!");
}
+void
+GamepadManager::VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
+ double aIntensity, double aDuration)
+{
+ if (aControllerIdx >= VR_GAMEPAD_IDX_OFFSET) {
+ uint32_t index = aControllerIdx - VR_GAMEPAD_IDX_OFFSET;
+ mVRChannelChild->SendVibrateHaptic(index, aHapticIndex,
+ aIntensity, aDuration);
+ } else {
+ // TODO: Bug 680289, implement for standard gamepads
+ }
+}
+
//Override nsIIPCBackgroundChildCreateCallback
void
GamepadManager::ActorCreated(PBackgroundChild *aActor)
{
MOZ_ASSERT(aActor);
GamepadEventChannelChild *child = new GamepadEventChannelChild();
PGamepadEventChannelChild *initedChild =
aActor->SendPGamepadEventChannelConstructor(child);
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -47,17 +47,17 @@ class GamepadManager final : public nsIO
// Indicate that |aWindow| wants to receive gamepad events.
void AddListener(nsGlobalWindow* aWindow);
// Indicate that |aWindow| should no longer receive gamepad events.
void RemoveListener(nsGlobalWindow* aWindow);
// Add a gamepad to the list of known gamepads.
void AddGamepad(uint32_t aIndex, const nsAString& aID, GamepadMappingType aMapping,
GamepadHand aHand, GamepadServiceType aServiceType,
- uint32_t aNumButtons, uint32_t aNumAxes);
+ uint32_t aNumButtons, uint32_t aNumAxes, uint32_t aNumHaptics);
// Remove the gamepad at |aIndex| from the list of known gamepads.
void RemoveGamepad(uint32_t aIndex, GamepadServiceType aServiceType);
// Update the state of |aButton| for the gamepad at |aIndex| for all
// windows that are listening and visible, and fire one of
// a gamepadbutton{up,down} event at them as well.
// aPressed is used for digital buttons, aValue is for analog buttons.
@@ -79,16 +79,20 @@ class GamepadManager final : public nsIO
void SyncGamepadState(uint32_t aIndex, Gamepad* aGamepad);
// 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);
+
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.
void NewConnectionEvent(uint32_t aIndex, bool aConnected);
--- a/dom/gamepad/GamepadPlatformService.cpp
+++ b/dom/gamepad/GamepadPlatformService.cpp
@@ -91,17 +91,18 @@ GamepadPlatformService::AddGamepad(const
// This method is called by monitor thread populated in
// platform-dependent backends
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!NS_IsMainThread());
uint32_t index = ++mGamepadIndex;
GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), index,
aMapping, GamepadHand::_empty, GamepadServiceType::Standard,
- aNumButtons, aNumAxes);
+ aNumButtons, aNumAxes, 0);
+
NotifyGamepadChange<GamepadAdded>(a);
return index;
}
void
GamepadPlatformService::RemoveGamepad(uint32_t aIndex)
{
// This method is called by monitor thread populated in
--- a/dom/gamepad/GamepadServiceTest.cpp
+++ b/dom/gamepad/GamepadServiceTest.cpp
@@ -119,17 +119,17 @@ GamepadServiceTest::AddGamepad(const nsA
{
if (mShuttingDown) {
return nullptr;
}
GamepadAdded a(nsString(aID), 0,
aMapping, GamepadHand::_empty,
GamepadServiceType::Standard,
- aNumButtons, aNumAxes);
+ aNumButtons, aNumAxes, 0);
GamepadChangeEvent e(a);
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> p = Promise::Create(go, aRv);
if (aRv.Failed()) {
return nullptr;
}
--- a/dom/gamepad/ipc/GamepadEventTypes.ipdlh
+++ b/dom/gamepad/ipc/GamepadEventTypes.ipdlh
@@ -14,16 +14,17 @@ namespace dom {
struct GamepadAdded {
nsString id;
uint32_t index;
GamepadMappingType mapping;
GamepadHand hand;
GamepadServiceType service_type;
uint32_t num_buttons;
uint32_t num_axes;
+ uint32_t num_haptics;
};
struct GamepadRemoved {
uint32_t index;
GamepadServiceType service_type;
};
struct GamepadAxisInformation {