Bug 1299937 - Part 2: Support gamepad haptic in GamepadManager; r?lenzak800, kip, qdot draft
authorDaosheng Mu <daoshengmu@gmail.com>
Thu, 02 Feb 2017 14:33:18 +0800
changeset 503537 cd2c3cf2d3ca08f439a8bf7413dfd834bfbb3b5f
parent 503536 27d15c244de4b38bd40ce6667d797076a5a01355
child 503538 8bcb21e63223f3f0471ea93184a6c7d6b74d1008
push id50611
push userbmo:dmu@mozilla.com
push dateThu, 23 Mar 2017 09:11:47 +0000
reviewerslenzak800, kip, qdot
bugs1299937
milestone55.0a1
Bug 1299937 - Part 2: Support gamepad haptic in GamepadManager; r?lenzak800, kip, qdot MozReview-Commit-ID: 7duCrsFLVX6
dom/gamepad/GamepadManager.cpp
dom/gamepad/GamepadManager.h
dom/gamepad/GamepadPlatformService.cpp
dom/gamepad/GamepadServiceTest.cpp
dom/gamepad/ipc/GamepadEventTypes.ipdlh
--- 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 {