Bug 1299932 - Part 2: Support gamepadPose in GamepadManager; r?kip, lenzak800
MozReview-Commit-ID: 9wKxQIxaPbI
--- 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