Skip to content

Commit 21043ec

Browse files
committed
Bug 1523351 - Part 3: Handling GamepadTouch and GamepadLightIndicator events in Gamepad service. r=baku
Differential Revision: https://phabricator.services.mozilla.com/D29290 --HG-- extra : moz-landing-system : lando
1 parent fc4437c commit 21043ec

17 files changed

+209
-35
lines changed

dom/gamepad/GamepadManager.cpp

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,17 @@ void GamepadManager::AddGamepad(uint32_t aIndex, const nsAString& aId,
225225
GamepadMappingType aMapping, GamepadHand aHand,
226226
GamepadServiceType aServiceType,
227227
uint32_t aDisplayID, uint32_t aNumButtons,
228-
uint32_t aNumAxes, uint32_t aNumHaptics) {
228+
uint32_t aNumAxes, uint32_t aNumHaptics,
229+
uint32_t aNumLightIndicator,
230+
uint32_t aNumTouchEvents) {
229231
uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
230232

231233
// TODO: bug 852258: get initial button/axis state
232-
RefPtr<Gamepad> gamepad = new Gamepad(nullptr, aId,
233-
0, // index is set by global window
234-
newIndex, aMapping, aHand, aDisplayID,
235-
aNumButtons, aNumAxes, aNumHaptics);
234+
RefPtr<Gamepad> gamepad =
235+
new Gamepad(nullptr, aId,
236+
0, // index is set by global window
237+
newIndex, aMapping, aHand, aDisplayID, aNumButtons, aNumAxes,
238+
aNumHaptics, aNumLightIndicator, aNumTouchEvents);
236239

237240
// We store the gamepad related to its index given by the parent process,
238241
// and no duplicate index is allowed.
@@ -471,7 +474,8 @@ void GamepadManager::Update(const GamepadChangeEvent& aEvent) {
471474
const GamepadAdded& a = body.get_GamepadAdded();
472475
AddGamepad(index, a.id(), static_cast<GamepadMappingType>(a.mapping()),
473476
static_cast<GamepadHand>(a.hand()), serviceType, a.display_id(),
474-
a.num_buttons(), a.num_axes(), a.num_haptics());
477+
a.num_buttons(), a.num_axes(), a.num_haptics(), a.num_lights(),
478+
a.num_touches());
475479
return;
476480
}
477481
if (body.type() == GamepadChangeEventBody::TGamepadRemoved) {
@@ -561,6 +565,25 @@ bool GamepadManager::SetGamepadByEvent(const GamepadChangeEvent& aEvent,
561565
gamepad->SetPose(a.pose_state());
562566
break;
563567
}
568+
case GamepadChangeEventBody::TGamepadLightIndicatorTypeInformation: {
569+
const GamepadLightIndicatorTypeInformation& a =
570+
body.get_GamepadLightIndicatorTypeInformation();
571+
gamepad->SetLightIndicatorType(a.light(), a.type());
572+
break;
573+
}
574+
case GamepadChangeEventBody::TGamepadTouchInformation: {
575+
// Avoid GamepadTouch's touchId be accessed in cross-origin tracking.
576+
for (uint32_t i = 0; i < mListeners.Length(); i++) {
577+
RefPtr<Gamepad> listenerGamepad = mListeners[i]->GetGamepad(index);
578+
if (listenerGamepad && mListeners[i]->IsCurrentInnerWindow() &&
579+
!mListeners[i]->GetOuterWindow()->IsBackground()) {
580+
const GamepadTouchInformation& a =
581+
body.get_GamepadTouchInformation();
582+
listenerGamepad->SetTouchEvent(a.index(), a.touch_state());
583+
}
584+
}
585+
break;
586+
}
564587
case GamepadChangeEventBody::TGamepadHandInformation: {
565588
const GamepadHandInformation& a = body.get_GamepadHandInformation();
566589
gamepad->SetHand(a.hand());
@@ -583,13 +606,12 @@ bool GamepadManager::SetGamepadByEvent(const GamepadChangeEvent& aEvent,
583606
already_AddRefed<Promise> GamepadManager::VibrateHaptic(
584607
uint32_t aControllerIdx, uint32_t aHapticIndex, double aIntensity,
585608
double aDuration, nsIGlobalObject* aGlobal, ErrorResult& aRv) {
586-
const char* kGamepadHapticEnabledPref = "dom.gamepad.haptic_feedback.enabled";
587609
RefPtr<Promise> promise = Promise::Create(aGlobal, aRv);
588610
if (NS_WARN_IF(aRv.Failed())) {
589611
aRv.Throw(NS_ERROR_FAILURE);
590612
return nullptr;
591613
}
592-
if (Preferences::GetBool(kGamepadHapticEnabledPref)) {
614+
if (StaticPrefs::dom_gamepad_haptic_feedback_enabled()) {
593615
if (aControllerIdx >= VR_GAMEPAD_IDX_OFFSET) {
594616
if (gfx::VRManagerChild::IsCreated()) {
595617
const uint32_t index = aControllerIdx - VR_GAMEPAD_IDX_OFFSET;
@@ -612,8 +634,7 @@ already_AddRefed<Promise> GamepadManager::VibrateHaptic(
612634
}
613635

614636
void GamepadManager::StopHaptics() {
615-
const char* kGamepadHapticEnabledPref = "dom.gamepad.haptic_feedback.enabled";
616-
if (!Preferences::GetBool(kGamepadHapticEnabledPref)) {
637+
if (!StaticPrefs::dom_gamepad_haptic_feedback_enabled()) {
617638
return;
618639
}
619640

@@ -633,5 +654,32 @@ void GamepadManager::StopHaptics() {
633654
}
634655
}
635656

657+
already_AddRefed<Promise> GamepadManager::SetLightIndicatorColor(
658+
uint32_t aControllerIdx, uint32_t aLightColorIndex, uint8_t aRed,
659+
uint8_t aGreen, uint8_t aBlue, nsIGlobalObject* aGlobal, ErrorResult& aRv) {
660+
RefPtr<Promise> promise = Promise::Create(aGlobal, aRv);
661+
if (NS_WARN_IF(aRv.Failed())) {
662+
aRv.Throw(NS_ERROR_FAILURE);
663+
return nullptr;
664+
}
665+
if (StaticPrefs::dom_gamepad_extensions_lightindicator()) {
666+
for (auto iter = mGamepads.Iter(); !iter.Done(); iter.Next()) {
667+
const uint32_t gamepadIndex = iter.UserData()->HashKey();
668+
if (gamepadIndex >= VR_GAMEPAD_IDX_OFFSET) {
669+
MOZ_ASSERT(false && "We don't support light indicator in VR.");
670+
} else {
671+
for (auto& channelChild : mChannelChildren) {
672+
channelChild->AddPromise(mPromiseID, promise);
673+
channelChild->SendLightIndicatorColor(aControllerIdx,
674+
aLightColorIndex, aRed, aGreen,
675+
aBlue, mPromiseID);
676+
}
677+
}
678+
}
679+
}
680+
681+
++mPromiseID;
682+
return promise.forget();
683+
}
636684
} // namespace dom
637685
} // namespace mozilla

dom/gamepad/GamepadManager.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class GamepadManager final : public nsIObserver {
4949
void AddGamepad(uint32_t aIndex, const nsAString& aID,
5050
GamepadMappingType aMapping, GamepadHand aHand,
5151
GamepadServiceType aServiceType, uint32_t aDisplayID,
52-
uint32_t aNumButtons, uint32_t aNumAxes,
53-
uint32_t aNumHaptics);
52+
uint32_t aNumButtons, uint32_t aNumAxes, uint32_t aNumHaptics,
53+
uint32_t aNumLightIndicator, uint32_t aNumTouchEvents);
5454

5555
// Remove the gamepad at |aIndex| from the list of known gamepads.
5656
void RemoveGamepad(uint32_t aIndex, GamepadServiceType aServiceType);
@@ -78,6 +78,14 @@ class GamepadManager final : public nsIObserver {
7878
// Send stop haptic events to gamepad channels.
7979
void StopHaptics();
8080

81+
// Set light indicator color event to gamepad channels.
82+
already_AddRefed<Promise> SetLightIndicatorColor(uint32_t aControllerIdx,
83+
uint32_t aLightColorIndex,
84+
uint8_t aRed, uint8_t aGreen,
85+
uint8_t aBlue,
86+
nsIGlobalObject* aGlobal,
87+
ErrorResult& aRv);
88+
8189
protected:
8290
GamepadManager();
8391
~GamepadManager(){};

dom/gamepad/GamepadMonitoring.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ void MaybeStopGamepadMonitoring();
1717
// (linux/LinuxGamepad.cpp, cocoa/CocoaGamepad.cpp, etc)
1818
void StartGamepadMonitoring();
1919
void StopGamepadMonitoring();
20+
void SetGamepadLightIndicatorColor(uint32_t aControllerIdx,
21+
uint32_t aLightColorIndex, uint8_t aRed,
22+
uint8_t aGreen, uint8_t aBlue);
2023

2124
} // namespace dom
2225
} // namespace mozilla

dom/gamepad/GamepadPlatformService.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ void GamepadPlatformService::NotifyGamepadChange(uint32_t aIndex,
7979

8080
uint32_t GamepadPlatformService::AddGamepad(
8181
const char* aID, GamepadMappingType aMapping, GamepadHand aHand,
82-
uint32_t aNumButtons, uint32_t aNumAxes, uint32_t aHaptics) {
82+
uint32_t aNumButtons, uint32_t aNumAxes, uint32_t aHaptics,
83+
uint32_t aNumLightIndicator, uint32_t aNumTouchEvents) {
8384
// This method is called by monitor thread populated in
8485
// platform-dependent backends
8586
MOZ_ASSERT(XRE_IsParentProcess());
@@ -89,7 +90,8 @@ uint32_t GamepadPlatformService::AddGamepad(
8990

9091
// Only VR controllers has displayID, we give 0 to the general gamepads.
9192
GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), aMapping,
92-
aHand, 0, aNumButtons, aNumAxes, aHaptics);
93+
aHand, 0, aNumButtons, aNumAxes, aHaptics, aNumLightIndicator,
94+
aNumTouchEvents);
9395

9496
NotifyGamepadChange<GamepadAdded>(index, a);
9597
return index;
@@ -145,16 +147,38 @@ void GamepadPlatformService::NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
145147
NotifyGamepadChange<GamepadAxisInformation>(aIndex, a);
146148
}
147149

150+
void GamepadPlatformService::NewLightIndicatorTypeEvent(
151+
uint32_t aIndex, uint32_t aLight, GamepadLightIndicatorType aType) {
152+
// This method is called by monitor thread populated in
153+
// platform-dependent backends
154+
MOZ_ASSERT(XRE_IsParentProcess());
155+
MOZ_ASSERT(!NS_IsMainThread());
156+
GamepadLightIndicatorTypeInformation a(aLight, aType);
157+
NotifyGamepadChange<GamepadLightIndicatorTypeInformation>(aIndex, a);
158+
}
159+
148160
void GamepadPlatformService::NewPoseEvent(uint32_t aIndex,
149-
const GamepadPoseState& aPose) {
161+
const GamepadPoseState& aState) {
150162
// This method is called by monitor thread populated in
151163
// platform-dependent backends
152164
MOZ_ASSERT(XRE_IsParentProcess());
153165
MOZ_ASSERT(!NS_IsMainThread());
154-
GamepadPoseInformation a(aPose);
166+
GamepadPoseInformation a(aState);
155167
NotifyGamepadChange<GamepadPoseInformation>(aIndex, a);
156168
}
157169

170+
void GamepadPlatformService::NewMultiTouchEvent(
171+
uint32_t aIndex, uint32_t aTouchArrayIndex,
172+
const GamepadTouchState& aState) {
173+
// This method is called by monitor thread populated in
174+
// platform-dependent backends
175+
MOZ_ASSERT(XRE_IsParentProcess());
176+
MOZ_ASSERT(!NS_IsMainThread());
177+
178+
GamepadTouchInformation a(aTouchArrayIndex, aState);
179+
NotifyGamepadChange<GamepadTouchInformation>(aIndex, a);
180+
}
181+
158182
void GamepadPlatformService::ResetGamepadIndexes() {
159183
// This method is called by monitor thread populated in
160184
// platform-dependent backends

dom/gamepad/GamepadPlatformService.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ class GamepadPlatformService final {
3838
// Add a gamepad to the list of known gamepads, and return its index.
3939
uint32_t AddGamepad(const char* aID, GamepadMappingType aMapping,
4040
GamepadHand aHand, uint32_t aNumButtons,
41-
uint32_t aNumAxes, uint32_t aNumHaptics);
41+
uint32_t aNumAxes, uint32_t aNumHaptics,
42+
uint32_t aNumLightIndicator, uint32_t aNumTouchEvents);
4243
// Remove the gamepad at |aIndex| from the list of known gamepads.
4344
void RemoveGamepad(uint32_t aIndex);
4445

@@ -62,6 +63,14 @@ class GamepadPlatformService final {
6263
// Update the state of |aState| for the gamepad at |aIndex| for all
6364
// windows that are listening and visible.
6465
void NewPoseEvent(uint32_t aIndex, const GamepadPoseState& aState);
66+
// Update the type of |aType| for the gamepad at |aIndex| for all
67+
// windows that are listening and visible.
68+
void NewLightIndicatorTypeEvent(uint32_t aIndex, uint32_t aLight,
69+
GamepadLightIndicatorType aType);
70+
// Update the state of |aState| for the gamepad at |aIndex| with
71+
// |aTouchArrayIndex| for all windows that are listening and visible.
72+
void NewMultiTouchEvent(uint32_t aIndex, uint32_t aTouchArrayIndex,
73+
const GamepadTouchState& aState);
6574

6675
// When shutting down the platform communications for gamepad, also reset the
6776
// indexes.

dom/gamepad/android/AndroidGamepad.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ class AndroidGamepadManager final
2626
if (aAdded) {
2727
const int svc_id = service->AddGamepad(
2828
"android", GamepadMappingType::Standard, GamepadHand::_empty,
29-
kStandardGamepadButtons, kStandardGamepadAxes,
30-
0); // TODO: Bug 680289, implement gamepad haptics for Android
29+
kStandardGamepadButtons, kStandardGamepadAxes, 0, 0,
30+
0); // TODO: Bug 680289, implement gamepad haptics for Android.
31+
// TODO: Bug 1523355, implement gamepad lighindicator and touch for
32+
// Android.
3133
java::AndroidGamepadManager::OnGamepadAdded(aID, svc_id);
3234

3335
} else {

dom/gamepad/cocoa/CocoaGamepad.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,9 @@ void DarwinGamepadService::DeviceAdded(IOHIDDeviceRef device) {
304304
uint32_t index = service->AddGamepad(
305305
buffer, mozilla::dom::GamepadMappingType::_empty,
306306
mozilla::dom::GamepadHand::_empty, (int)mGamepads[slot].numButtons(),
307-
(int)mGamepads[slot].numAxes(),
308-
0); // TODO: Bug 680289, implement gamepad haptics for cocoa
307+
(int)mGamepads[slot].numAxes(), 0, 0,
308+
0); // TODO: Bug 680289, implement gamepad haptics for cocoa.
309+
// TODO: Bug 1523355, implement gamepad lighindicator and touch for cocoa.
309310
mGamepads[slot].mSuperIndex = index;
310311
}
311312

dom/gamepad/ipc/GamepadEventChannelChild.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void GamepadEventChannelChild::AddPromise(const uint32_t& aID,
4343
mPromiseList.Put(aID, aPromise);
4444
}
4545

46-
mozilla::ipc::IPCResult GamepadEventChannelChild::RecvReplyGamepadVibrateHaptic(
46+
mozilla::ipc::IPCResult GamepadEventChannelChild::RecvReplyGamepadPromise(
4747
const uint32_t& aPromiseID) {
4848
RefPtr<dom::Promise> p;
4949
if (!mPromiseList.Get(aPromiseID, getter_AddRefs(p))) {

dom/gamepad/ipc/GamepadEventChannelChild.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ class GamepadEventChannelChild final : public PGamepadEventChannelChild {
1717
~GamepadEventChannelChild() {}
1818
mozilla::ipc::IPCResult RecvGamepadUpdate(
1919
const GamepadChangeEvent& aGamepadEvent);
20-
mozilla::ipc::IPCResult RecvReplyGamepadVibrateHaptic(
21-
const uint32_t& aPromiseID);
20+
mozilla::ipc::IPCResult RecvReplyGamepadPromise(const uint32_t& aPromiseID);
2221
void AddPromise(const uint32_t& aID, dom::Promise* aPromise);
2322

2423
private:

dom/gamepad/ipc/GamepadEventChannelParent.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,37 @@ mozilla::ipc::IPCResult GamepadEventChannelParent::RecvVibrateHaptic(
7676
const uint32_t& aPromiseID) {
7777
// TODO: Bug 680289, implement for standard gamepads
7878

79-
if (SendReplyGamepadVibrateHaptic(aPromiseID)) {
79+
if (SendReplyGamepadPromise(aPromiseID)) {
8080
return IPC_OK();
8181
}
8282

83-
return IPC_FAIL(this, "SendReplyGamepadVibrateHaptic fail.");
83+
return IPC_FAIL(this, "SendReplyGamepadPromise fail.");
8484
}
8585

8686
mozilla::ipc::IPCResult GamepadEventChannelParent::RecvStopVibrateHaptic(
87-
const uint32_t& aGamepadIndex) {
87+
const uint32_t& aControllerIdx) {
8888
// TODO: Bug 680289, implement for standard gamepads
8989
return IPC_OK();
9090
}
9191

92+
mozilla::ipc::IPCResult GamepadEventChannelParent::RecvLightIndicatorColor(
93+
const uint32_t& aControllerIdx, const uint32_t& aLightColorIndex,
94+
const uint8_t& aRed, const uint8_t& aGreen, const uint8_t& aBlue,
95+
const uint32_t& aPromiseID) {
96+
// It may be called because IPDL child side crashed, we'll
97+
// not receive RecvGamepadListenerRemoved in that case
98+
if (mHasGamepadListener) {
99+
SetGamepadLightIndicatorColor(aControllerIdx, aLightColorIndex, aRed,
100+
aGreen, aBlue);
101+
}
102+
103+
if (SendReplyGamepadPromise(aPromiseID)) {
104+
return IPC_OK();
105+
}
106+
107+
return IPC_FAIL(this, "SendReplyGamepadPromise fail.");
108+
}
109+
92110
void GamepadEventChannelParent::ActorDestroy(ActorDestroyReason aWhy) {
93111
AssertIsOnBackgroundThread();
94112

0 commit comments

Comments
 (0)