Bug 1299937 - Part 2: Support gamepad haptic in GamepadManager; r=kip,Lenzak,qdot
authorDaosheng Mu <daoshengmu@gmail.com>
Thu, 02 Feb 2017 14:33:18 +0800
changeset 349316 691a5be9ff0d942abf71dfe73714c51fba04f55d
parent 349315 56e2fa280d2a9f00e37238c3c2532caa01c3b2a5
child 349317 ed20b557e9a5745a37fce239dcff94cb35b90c2c
push id39455
push userdmu@mozilla.com
push dateFri, 24 Mar 2017 03:25:06 +0000
treeherderautoland@5d8e162ef5f7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskip, Lenzak, qdot
bugs1299937
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1299937 - Part 2: Support gamepad haptic in GamepadManager; r=kip,Lenzak,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 {