Bug 1336002 - Part 3: Support button touched in GamepadManager; r?lenzak800
authorDaosheng Mu <daoshengmu@gmail.com>
Thu, 06 Apr 2017 18:58:44 +0800
changeset 1086755 14a19c375923dd9269c9383fd0dc37e21eeef3ee
parent 1086754 92f7b7d2b1ba407fe9cfe78fa81ab639145b266d
child 1086756 443dab15d080cca9881556dbafe99ddf5a3c4f78
push id181020
push userdmu@mozilla.com
push dateThu, 06 Apr 2017 14:26:28 +0000
treeherdertry@a344aa215d16 [default view] [failures only]
reviewerslenzak800
bugs1336002
milestone55.0a1
Bug 1336002 - Part 3: Support button touched in GamepadManager; r?lenzak800 MozReview-Commit-ID: K2rTLdEAbBs
dom/gamepad/GamepadManager.cpp
dom/gamepad/GamepadManager.h
dom/gamepad/GamepadPlatformService.cpp
dom/gamepad/GamepadPlatformService.h
dom/gamepad/GamepadServiceTest.cpp
dom/gamepad/GamepadServiceTest.h
dom/gamepad/android/AndroidGamepad.cpp
dom/gamepad/cocoa/CocoaGamepad.cpp
dom/gamepad/ipc/GamepadEventTypes.ipdlh
dom/gamepad/ipc/GamepadTestChannelParent.cpp
dom/gamepad/linux/LinuxGamepad.cpp
dom/gamepad/windows/WindowsGamepad.cpp
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -264,30 +264,31 @@ GamepadManager::RemoveGamepad(uint32_t a
   }
   gamepad->SetConnected(false);
   NewConnectionEvent(newIndex, false);
   mGamepads.Remove(newIndex);
 }
 
 void
 GamepadManager::NewButtonEvent(uint32_t aIndex, GamepadServiceType aServiceType,
-                               uint32_t aButton, bool aPressed, double aValue)
+                               uint32_t aButton, bool aPressed, bool aTouched,
+                               double aValue)
 {
   if (mShuttingDown) {
     return;
   }
 
   uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
 
   RefPtr<Gamepad> gamepad = GetGamepad(newIndex);
   if (!gamepad) {
     return;
   }
 
-  gamepad->SetButton(aButton, aPressed, aValue);
+  gamepad->SetButton(aButton, aPressed, aTouched, aValue);
 
   // Hold on to listeners in a separate array because firing events
   // can mutate the mListeners array.
   nsTArray<RefPtr<nsGlobalWindow>> listeners(mListeners);
   MOZ_ASSERT(!listeners.IsEmpty());
 
   for (uint32_t i = 0; i < listeners.Length(); i++) {
 
@@ -298,17 +299,17 @@ GamepadManager::NewButtonEvent(uint32_t 
         listeners[i]->GetOuterWindow()->IsBackground()) {
       continue;
     }
 
     bool firstTime = MaybeWindowHasSeenGamepad(listeners[i], newIndex);
 
     RefPtr<Gamepad> listenerGamepad = listeners[i]->GetGamepad(newIndex);
     if (listenerGamepad) {
-      listenerGamepad->SetButton(aButton, aPressed, aValue);
+      listenerGamepad->SetButton(aButton, aPressed, aTouched, aValue);
       if (firstTime) {
         FireConnectionEvent(listeners[i], listenerGamepad, true);
       }
       if (mNonstandardEventsEnabled) {
         // Fire event
         FireButtonEvent(listeners[i], listenerGamepad, aButton, aValue);
       }
     }
@@ -645,17 +646,17 @@ GamepadManager::Update(const GamepadChan
   if (aEvent.type() == GamepadChangeEvent::TGamepadRemoved) {
     const GamepadRemoved& a = aEvent.get_GamepadRemoved();
     RemoveGamepad(a.index(), a.service_type());
     return;
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadButtonInformation) {
     const GamepadButtonInformation& a = aEvent.get_GamepadButtonInformation();
     NewButtonEvent(a.index(), a.service_type(), a.button(),
-                   a.pressed(), a.value());
+                   a.pressed(), a.touched(), a.value());
     return;
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadAxisInformation) {
     const GamepadAxisInformation& a = aEvent.get_GamepadAxisInformation();
     NewAxisMoveEvent(a.index(), a.service_type(), a.axis(), a.value());
     return;
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadPoseInformation) {
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -57,17 +57,17 @@ class GamepadManager final : public nsIO
   // 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.
   void NewButtonEvent(uint32_t aIndex, GamepadServiceType aServiceType, uint32_t aButton,
-                      bool aPressed, double aValue);
+                      bool aPressed, bool aTouched, double aValue);
 
   // Update the state of |aAxis| for the gamepad at |aIndex| for all
   // windows that are listening and visible, and fire a gamepadaxismove
   // event at them as well.
   void NewAxisMoveEvent(uint32_t aIndex, GamepadServiceType aServiceType,
                         uint32_t aAxis, double aValue);
 
   // Update the state of |aState| for the gamepad at |aIndex| for all
--- a/dom/gamepad/GamepadPlatformService.cpp
+++ b/dom/gamepad/GamepadPlatformService.cpp
@@ -112,37 +112,38 @@ GamepadPlatformService::RemoveGamepad(ui
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(!NS_IsMainThread());
   GamepadRemoved a(aIndex, GamepadServiceType::Standard);
   NotifyGamepadChange<GamepadRemoved>(a);
 }
 
 void
 GamepadPlatformService::NewButtonEvent(uint32_t aIndex, uint32_t aButton,
-                                       bool aPressed, double aValue)
+                                       bool aPressed, bool aTouched,
+                                       double aValue)
 {
   // This method is called by monitor thread populated in
   // platform-dependent backends
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(!NS_IsMainThread());
   GamepadButtonInformation a(aIndex, GamepadServiceType::Standard,
-                             aButton, aPressed, aValue);
+                             aButton, aValue, aPressed, aTouched);
   NotifyGamepadChange<GamepadButtonInformation>(a);
 }
 
 void
 GamepadPlatformService::NewButtonEvent(uint32_t aIndex, uint32_t aButton,
-                                       bool aPressed)
+                                       bool aTouched, bool aPressed)
 {
   // This method is called by monitor thread populated in
   // platform-dependent backends
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(!NS_IsMainThread());
   // When only a digital button is available the value will be synthesized.
-  NewButtonEvent(aIndex, aButton, aPressed, aPressed ? 1.0L : 0.0L);
+  NewButtonEvent(aIndex, aButton, aPressed, aTouched, aPressed ? 1.0L : 0.0L);
 }
 
 void
 GamepadPlatformService::NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
                                          double aValue)
 {
   // This method is called by monitor thread populated in
   // platform-dependent backends
--- a/dom/gamepad/GamepadPlatformService.h
+++ b/dom/gamepad/GamepadPlatformService.h
@@ -41,21 +41,23 @@ class GamepadPlatformService final
                       GamepadHand aHand, 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);
 
   // 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.
+  // aPressed is used for digital buttons, aTouched is for detecting touch 
+  // aValue is for analog buttons.
   void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed,
-                      double aValue);
+                      bool aTouched, double aValue);
   // When only a digital button is available the value will be synthesized.
-  void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed);
+  void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed,
+                      bool aTouched);
 
   // Update the state of |aAxis| for the gamepad at |aIndex| for all
   // windows that are listening and visible, and fire a gamepadaxismove
   // event at them as well.
   void NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis, double aValue);
   // Update the state of |aState| for the gamepad at |aIndex| for all
   // windows that are listening and visible.
   void NewPoseEvent(uint32_t aIndex, const GamepadPoseState& aState);
--- a/dom/gamepad/GamepadServiceTest.cpp
+++ b/dom/gamepad/GamepadServiceTest.cpp
@@ -163,47 +163,49 @@ GamepadServiceTest::RemoveGamepad(uint32
     PendingOperation op(id, e);
     mPendingOperations.AppendElement(op);
   }
 }
 
 void
 GamepadServiceTest::NewButtonEvent(uint32_t aIndex,
                                    uint32_t aButton,
+                                   bool aTouched,
                                    bool aPressed)
 {
   if (mShuttingDown) {
     return;
   }
 
   GamepadButtonInformation a(aIndex, GamepadServiceType::Standard,
-                             aButton, aPressed, aPressed ? 1.0 : 0);
+                             aButton, aPressed ? 1.0 : 0, aPressed, aTouched);
   GamepadChangeEvent e(a);
 
   uint32_t id = ++mEventNumber;
   if (mChild) {
     mChild->SendGamepadTestEvent(id, e);
   } else {
     PendingOperation op(id, e);
     mPendingOperations.AppendElement(op);
   }
 }
 
 void
 GamepadServiceTest::NewButtonValueEvent(uint32_t aIndex,
                                         uint32_t aButton,
                                         bool aPressed,
+                                        bool aTouched,
                                         double aValue)
 {
   if (mShuttingDown) {
     return;
   }
 
   GamepadButtonInformation a(aIndex, GamepadServiceType::Standard,
-                             aButton, aPressed, aValue);
+                             aButton, aValue, aPressed, aTouched);
   GamepadChangeEvent e(a);
 
   uint32_t id = ++mEventNumber;
   if (mChild) {
     mChild->SendGamepadTestEvent(id, e);
   } else {
     PendingOperation op(id, e);
     mPendingOperations.AppendElement(op);
--- a/dom/gamepad/GamepadServiceTest.h
+++ b/dom/gamepad/GamepadServiceTest.h
@@ -38,18 +38,19 @@ public:
   already_AddRefed<Promise> AddGamepad(const nsAString& aID,
                                        GamepadMappingType aMapping,
                                        GamepadHand aHand,
                                        uint32_t aNumButtons,
                                        uint32_t aNumAxes,
                                        uint32_t aNumHaptics,
                                        ErrorResult& aRv);
   void RemoveGamepad(uint32_t aIndex);
-  void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed);
-  void NewButtonValueEvent(uint32_t aIndex, uint32_t aButton, bool aPressed, double aValue);
+  void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed, bool aTouched);
+  void NewButtonValueEvent(uint32_t aIndex, uint32_t aButton, bool aPressed, bool aTouched,
+                           double aValue);
   void NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis, double aValue);
   void NewPoseMove(uint32_t aIndex,
                    const Nullable<Float32Array>& aOrient,
                    const Nullable<Float32Array>& aPos,
                    const Nullable<Float32Array>& aAngVelocity,
                    const Nullable<Float32Array>& aAngAcceleration,
                    const Nullable<Float32Array>& aLinVelocity,
                    const Nullable<Float32Array>& aLinAcceleration);
--- a/dom/gamepad/android/AndroidGamepad.cpp
+++ b/dom/gamepad/android/AndroidGamepad.cpp
@@ -42,17 +42,17 @@ public:
   OnButtonChange(int32_t aID, int32_t aButton, bool aPressed, float aValue)
   {
     RefPtr<GamepadPlatformService> service =
         GamepadPlatformService::GetParentService();
     if (!service) {
       return;
     }
 
-    service->NewButtonEvent(aID, aButton, aPressed, aValue);
+    service->NewButtonEvent(aID, aButton, aPressed, aPressed, aValue);
   }
 
   static void
   OnAxisChange(int32_t aID, jni::BooleanArray::Param aValid,
                jni::FloatArray::Param aValues)
   {
     RefPtr<GamepadPlatformService> service =
         GamepadPlatformService::GetParentService();
--- a/dom/gamepad/cocoa/CocoaGamepad.cpp
+++ b/dom/gamepad/cocoa/CocoaGamepad.cpp
@@ -375,16 +375,17 @@ DarwinGamepadService::InputValueChanged(
                    IOHIDElementGetLogicalMin(element),
                    IOHIDElementGetLogicalMax(element),
                    newState);
         const int numButtons = gamepad.numButtons();
         for (unsigned b = 0; b < ArrayLength(newState); b++) {
           if (newState[b] != oldState[b]) {
             service->NewButtonEvent(gamepad.mSuperIndex,
                                     numButtons - 4 + b,
+                                    newState[b],
                                     newState[b]);
           }
         }
         gamepad.setDpadState(newState);
       } else if (const Axis* axis = gamepad.lookupAxis(element)) {
         double d = IOHIDValueGetIntegerValue(value);
         double v = 2.0f * (d - axis->min) /
           (double)(axis->max - axis->min) - 1.0f;
@@ -394,17 +395,18 @@ DarwinGamepadService::InputValueChanged(
         bool pressed = iv != 0;
         double v = 0;
         if (button->analog) {
           double dv = iv;
           v = (dv - button->min) / (double)(button->max - button->min);
         } else {
           v = pressed ? 1.0 : 0.0;
         }
-        service->NewButtonEvent(gamepad.mSuperIndex, button->id, pressed, v);
+        service->NewButtonEvent(gamepad.mSuperIndex, button->id, pressed, pressed,
+                                v);
       }
       return;
     }
   }
 }
 
 void
 DarwinGamepadService::DeviceAddedCallback(void* data, IOReturn result,
--- a/dom/gamepad/ipc/GamepadEventTypes.ipdlh
+++ b/dom/gamepad/ipc/GamepadEventTypes.ipdlh
@@ -33,18 +33,19 @@ struct GamepadAxisInformation {
   uint32_t axis;
   double value;
 };
 
 struct GamepadButtonInformation {
   uint32_t index;
   GamepadServiceType service_type;
   uint32_t button;
+  double value;
   bool pressed;
-  double value;
+  bool touched;
 };
 
 struct GamepadPoseInformation {
   uint32_t index;
   GamepadServiceType service_type;
   GamepadPoseState pose_state;
 };
 
--- a/dom/gamepad/ipc/GamepadTestChannelParent.cpp
+++ b/dom/gamepad/ipc/GamepadTestChannelParent.cpp
@@ -35,17 +35,18 @@ GamepadTestChannelParent::RecvGamepadTes
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadRemoved) {
     const GamepadRemoved& a = aEvent.get_GamepadRemoved();
     service->RemoveGamepad(a.index());
     return IPC_OK();
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadButtonInformation) {
     const GamepadButtonInformation& a = aEvent.get_GamepadButtonInformation();
-    service->NewButtonEvent(a.index(), a.button(), a.pressed(), a.value());
+    service->NewButtonEvent(a.index(), a.button(), a.pressed(), a.touched(),
+                            a.value());
     return IPC_OK();
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadAxisInformation) {
     const GamepadAxisInformation& a = aEvent.get_GamepadAxisInformation();
     service->NewAxisMoveEvent(a.index(), a.axis(), a.value());
     return IPC_OK();
   }
   if (aEvent.type() == GamepadChangeEvent::TGamepadPoseInformation) {
--- a/dom/gamepad/linux/LinuxGamepad.cpp
+++ b/dom/gamepad/linux/LinuxGamepad.cpp
@@ -334,17 +334,17 @@ LinuxGamepadService::OnGamepadData(GIOCh
 
     //TODO: store device state?
     if (event.type & JS_EVENT_INIT) {
       continue;
     }
 
     switch (event.type) {
     case JS_EVENT_BUTTON:
-      service->NewButtonEvent(index, event.number, !!event.value);
+      service->NewButtonEvent(index, event.number, !!event.value, !!event.value);
       break;
     case JS_EVENT_AXIS:
       service->NewAxisMoveEvent(index, event.number,
                                 ((float)event.value) / kMaxAxisValue);
       break;
     }
   }
 
--- a/dom/gamepad/windows/WindowsGamepad.cpp
+++ b/dom/gamepad/windows/WindowsGamepad.cpp
@@ -574,36 +574,36 @@ void WindowsGamepadService::CheckXInputC
   if (!service) {
     return;
   }
   // Handle digital buttons first
   for (size_t b = 0; b < kNumMappings; b++) {
     if (state.Gamepad.wButtons & kXIButtonMap[b].button &&
         !(gamepad.state.Gamepad.wButtons & kXIButtonMap[b].button)) {
       // Button pressed
-      service->NewButtonEvent(gamepad.id, kXIButtonMap[b].mapped, true);
+      service->NewButtonEvent(gamepad.id, kXIButtonMap[b].mapped, true, true);
     } else if (!(state.Gamepad.wButtons & kXIButtonMap[b].button) &&
                gamepad.state.Gamepad.wButtons & kXIButtonMap[b].button) {
       // Button released
-      service->NewButtonEvent(gamepad.id, kXIButtonMap[b].mapped, false);
+      service->NewButtonEvent(gamepad.id, kXIButtonMap[b].mapped, false, false);
     }
   }
 
   // Then triggers
   if (state.Gamepad.bLeftTrigger != gamepad.state.Gamepad.bLeftTrigger) {
     bool pressed =
       state.Gamepad.bLeftTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
     service->NewButtonEvent(gamepad.id, kButtonLeftTrigger,
-                            pressed, state.Gamepad.bLeftTrigger / 255.0);
+                            pressed, pressed, state.Gamepad.bLeftTrigger / 255.0);
   }
   if (state.Gamepad.bRightTrigger != gamepad.state.Gamepad.bRightTrigger) {
     bool pressed =
       state.Gamepad.bRightTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
     service->NewButtonEvent(gamepad.id, kButtonRightTrigger,
-                            pressed, state.Gamepad.bRightTrigger / 255.0);
+                            pressed, pressed, state.Gamepad.bRightTrigger / 255.0);
   }
 
   // Finally deal with analog sticks
   // TODO: bug 1001955 - Support deadzones.
   if (state.Gamepad.sThumbLX != gamepad.state.Gamepad.sThumbLX) {
     service->NewAxisMoveEvent(gamepad.id, kLeftStickXAxis,
                               state.Gamepad.sThumbLX / 32767.0);
   }
@@ -864,17 +864,17 @@ WindowsGamepadService::HandleRawInput(HR
     ULONG value;
     if (mHID.mHidP_GetUsageValue(HidP_Input, gamepad->dpadCaps.UsagePage, 0, gamepad->dpadCaps.Range.UsageMin, &value, parsed, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid) == HIDP_STATUS_SUCCESS) {
       UnpackDpad(static_cast<LONG>(value), gamepad, buttons);
     }
   }
 
   for (unsigned i = 0; i < gamepad->numButtons; i++) {
     if (gamepad->buttons[i] != buttons[i]) {
-      service->NewButtonEvent(gamepad->id, i, buttons[i]);
+      service->NewButtonEvent(gamepad->id, i, buttons[i], buttons[i]);
       gamepad->buttons[i] = buttons[i];
     }
   }
 
   // Get all axis values.
   for (unsigned i = 0; i < gamepad->numAxes; i++) {
     double new_value;
     if (gamepad->axes[i].caps.LogicalMin < 0) {