Bug 1299932 - Part 2: Support gamepadPose in GamepadManager; r?kip, lenzak800 draft
authorDaosheng Mu <daoshengmu@gmail.com>
Mon, 24 Oct 2016 18:06:52 +0800
changeset 437653 3b8350df92afc7976d1f8823ab93864722bd4c26
parent 437652 d3b08a829865ef96a515fff4511b74234e1c53ab
child 437654 97011fe269b7215afb5e27b4cdfad7181eeaed7e
push id35476
push userbmo:dmu@mozilla.com
push dateFri, 11 Nov 2016 09:27:20 +0000
reviewerskip, lenzak800
bugs1299932
milestone52.0a1
Bug 1299932 - Part 2: Support gamepadPose in GamepadManager; r?kip, lenzak800 MozReview-Commit-ID: 9wKxQIxaPbI
dom/gamepad/GamepadManager.cpp
dom/gamepad/GamepadManager.h
dom/gamepad/ipc/GamepadEventTypes.ipdlh
dom/gamepad/ipc/GamepadMessageUtils.h
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -401,16 +401,59 @@ GamepadManager::FireAxisMoveEvent(EventT
 
   event->SetTrusted(true);
 
   bool defaultActionEnabled = true;
   aTarget->DispatchEvent(event, &defaultActionEnabled);
 }
 
 void
+GamepadManager::NewPoseEvent(uint32_t aIndex, GamepadServiceType aServiceType,
+                             const GamepadPoseState& aPose)
+{
+  if (mShuttingDown) {
+    return;
+  }
+
+  uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
+
+  RefPtr<Gamepad> gamepad = GetGamepad(newIndex);
+  if (!gamepad) {
+    return;
+  }
+  gamepad->SetPose(aPose);
+
+  // 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++) {
+
+    MOZ_ASSERT(listeners[i]->IsInnerWindow());
+
+    // Only send events to non-background windows
+    if (!listeners[i]->AsInner()->IsCurrentInnerWindow() ||
+        listeners[i]->GetOuterWindow()->IsBackground()) {
+      continue;
+    }
+
+    bool firstTime = MaybeWindowHasSeenGamepad(listeners[i], newIndex);
+
+    RefPtr<Gamepad> listenerGamepad = listeners[i]->GetGamepad(newIndex);
+    if (listenerGamepad) {
+      listenerGamepad->SetPose(aPose);
+      if (firstTime) {
+        FireConnectionEvent(listeners[i], listenerGamepad, true);
+      }
+    }
+  }
+}
+
+void
 GamepadManager::NewConnectionEvent(uint32_t aIndex, bool aConnected)
 {
   if (mShuttingDown) {
     return;
   }
 
   RefPtr<Gamepad> gamepad = GetGamepad(aIndex);
   if (!gamepad) {
@@ -606,16 +649,21 @@ GamepadManager::Update(const GamepadChan
                    a.pressed(), 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) {
+    const GamepadPoseInformation& a = aEvent.get_GamepadPoseInformation();
+    NewPoseEvent(a.index(), a.service_type(), a.pose_state());
+    return;
+  }
 
   MOZ_CRASH("We shouldn't be here!");
 
 }
 
 //Override nsIIPCBackgroundChildCreateCallback
 void
 GamepadManager::ActorCreated(PBackgroundChild *aActor)
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -64,16 +64,21 @@ class GamepadManager final : public nsIO
                       bool aPressed, 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
+  // windows that are listening and visible.
+  void NewPoseEvent(uint32_t aIndex, GamepadServiceType aServiceType,
+                    const GamepadPoseState& aState);
+
   // Synchronize the state of |aGamepad| to match the gamepad stored at |aIndex|
   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);
--- a/dom/gamepad/ipc/GamepadEventTypes.ipdlh
+++ b/dom/gamepad/ipc/GamepadEventTypes.ipdlh
@@ -1,13 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 using mozilla::dom::GamepadServiceType from "mozilla/dom/GamepadMessageUtils.h";
+using mozilla::dom::GamepadPoseState from "mozilla/dom/GamepadMessageUtils.h";
 
 
 namespace mozilla {
 namespace dom {
 
 struct GamepadAdded {
   nsString id;
   uint32_t index;
@@ -35,17 +36,24 @@ struct GamepadAxisInformation {
 struct GamepadButtonInformation {
   uint32_t index;
   GamepadServiceType service_type;
   uint32_t button;
   bool pressed;
   double value;
 };
 
+struct GamepadPoseInformation {
+  uint32_t index;
+  GamepadServiceType service_type;
+  GamepadPoseState pose_state;
+};
+
 union GamepadChangeEvent {
   GamepadAdded;
   GamepadRemoved;
   GamepadAxisInformation;
   GamepadButtonInformation;
+  GamepadPoseInformation;
 };
 
 } // namespace dom
 } // namespace mozilla
\ No newline at end of file
--- a/dom/gamepad/ipc/GamepadMessageUtils.h
+++ b/dom/gamepad/ipc/GamepadMessageUtils.h
@@ -9,11 +9,74 @@
 namespace IPC {
 
 template<>
 struct ParamTraits<mozilla::dom::GamepadServiceType> :
   public ContiguousEnumSerializer<mozilla::dom::GamepadServiceType,
                                   mozilla::dom::GamepadServiceType(0),
                                   mozilla::dom::GamepadServiceType(
                                   mozilla::dom::GamepadServiceType::NumGamepadServiceType)> {};
+
+template<>
+struct ParamTraits<mozilla::dom::GamepadCapabilityFlags> :
+  public BitFlagsEnumSerializer<mozilla::dom::GamepadCapabilityFlags,
+                                mozilla::dom::GamepadCapabilityFlags::Cap_All> {};
+
+template <>
+struct ParamTraits<mozilla::dom::GamepadPoseState>
+{
+  typedef mozilla::dom::GamepadPoseState paramType;
+
+  static void Write(Message* aMsg, const paramType& aParam)
+  {
+    WriteParam(aMsg, aParam.flags);
+    WriteParam(aMsg, aParam.orientation[0]);
+    WriteParam(aMsg, aParam.orientation[1]);
+    WriteParam(aMsg, aParam.orientation[2]);
+    WriteParam(aMsg, aParam.orientation[3]);
+    WriteParam(aMsg, aParam.position[0]);
+    WriteParam(aMsg, aParam.position[1]);
+    WriteParam(aMsg, aParam.position[2]);
+    WriteParam(aMsg, aParam.angularVelocity[0]);
+    WriteParam(aMsg, aParam.angularVelocity[1]);
+    WriteParam(aMsg, aParam.angularVelocity[2]);
+    WriteParam(aMsg, aParam.angularAcceleration[0]);
+    WriteParam(aMsg, aParam.angularAcceleration[1]);
+    WriteParam(aMsg, aParam.angularAcceleration[2]);
+    WriteParam(aMsg, aParam.linearVelocity[0]);
+    WriteParam(aMsg, aParam.linearVelocity[1]);
+    WriteParam(aMsg, aParam.linearVelocity[2]);
+    WriteParam(aMsg, aParam.linearAcceleration[0]);
+    WriteParam(aMsg, aParam.linearAcceleration[1]);
+    WriteParam(aMsg, aParam.linearAcceleration[2]);
+  }
+
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+  {
+    if (!ReadParam(aMsg, aIter, &(aResult->flags)) ||
+        !ReadParam(aMsg, aIter, &(aResult->orientation[0])) ||
+        !ReadParam(aMsg, aIter, &(aResult->orientation[1])) ||
+        !ReadParam(aMsg, aIter, &(aResult->orientation[2])) ||
+        !ReadParam(aMsg, aIter, &(aResult->orientation[3])) ||
+        !ReadParam(aMsg, aIter, &(aResult->position[0])) ||
+        !ReadParam(aMsg, aIter, &(aResult->position[1])) ||
+        !ReadParam(aMsg, aIter, &(aResult->position[2])) ||
+        !ReadParam(aMsg, aIter, &(aResult->angularVelocity[0])) ||
+        !ReadParam(aMsg, aIter, &(aResult->angularVelocity[1])) ||
+        !ReadParam(aMsg, aIter, &(aResult->angularVelocity[2])) ||
+        !ReadParam(aMsg, aIter, &(aResult->angularAcceleration[0])) ||
+        !ReadParam(aMsg, aIter, &(aResult->angularAcceleration[1])) ||
+        !ReadParam(aMsg, aIter, &(aResult->angularAcceleration[2])) ||
+        !ReadParam(aMsg, aIter, &(aResult->linearVelocity[0])) ||
+        !ReadParam(aMsg, aIter, &(aResult->linearVelocity[1])) ||
+        !ReadParam(aMsg, aIter, &(aResult->linearVelocity[2])) ||
+        !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[0])) ||
+        !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[1])) ||
+        !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[2]))) {
+      return false;
+    }
+    return true;
+  }
+};
+
 } // namespace IPC
 
 #endif // mozilla_dom_gamepad_GamepadMessageUtils_h
\ No newline at end of file