Bug 1356452 - Part 3: Support changing gamepad hand property in GamepadManager; r?Lenzak
MozReview-Commit-ID: KZx2qJqks6f
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -447,16 +447,59 @@ GamepadManager::NewPoseEvent(uint32_t aI
if (firstTime) {
FireConnectionEvent(listeners[i], listenerGamepad, true);
}
}
}
}
void
+GamepadManager::NewHandChangeEvent(uint32_t aIndex, GamepadServiceType aServiceType,
+ GamepadHand aHand)
+{
+ if (mShuttingDown) {
+ return;
+ }
+
+ uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
+
+ RefPtr<Gamepad> gamepad = GetGamepad(newIndex);
+ if (!gamepad) {
+ return;
+ }
+ gamepad->SetHand(aHand);
+
+ // 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->SetHand(aHand);
+ 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) {
@@ -659,16 +702,21 @@ GamepadManager::Update(const GamepadChan
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;
}
+ if (aEvent.type() == GamepadChangeEvent::TGamepadHandInformation) {
+ const GamepadHandInformation& a = aEvent.get_GamepadHandInformation();
+ NewHandChangeEvent(a.index(), a.service_type(), a.hand());
+ return;
+ }
MOZ_CRASH("We shouldn't be here!");
}
already_AddRefed<Promise>
GamepadManager::VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
double aIntensity, double aDuration,
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -70,16 +70,21 @@ class GamepadManager final : public nsIO
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);
+ // Update the hand of |aHand| for the gamepad at |aIndex| for all
+ // windows that are listening and visible.
+ void NewHandChangeEvent(uint32_t aIndex, GamepadServiceType aServiceType,
+ GamepadHand aHand);
+
// 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
@@ -44,18 +44,25 @@ struct GamepadButtonInformation {
};
struct GamepadPoseInformation {
uint32_t index;
GamepadServiceType service_type;
GamepadPoseState pose_state;
};
+struct GamepadHandInformation {
+ uint32_t index;
+ GamepadServiceType service_type;
+ GamepadHand hand;
+};
+
union GamepadChangeEvent {
GamepadAdded;
GamepadRemoved;
GamepadAxisInformation;
GamepadButtonInformation;
GamepadPoseInformation;
+ GamepadHandInformation;
};
} // namespace dom
} // namespace mozilla
\ No newline at end of file