Skip to content

Commit 3809301

Browse files
committed
Bug 1299937 - Part 5: Add gamepad extension API tests; r=Lenzak,qdot
MozReview-Commit-ID: ICeDyGUn4XH --HG-- extra : rebase_source : 365b47581bd44c70be9d8bbefdc4236191abb3a9
1 parent c1d89a9 commit 3809301

26 files changed

+362
-24
lines changed

dom/gamepad/GamepadManager.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,12 @@ GamepadManager::VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
686686
aIntensity, aDuration,
687687
mPromiseID);
688688
} else {
689-
// TODO: Bug 680289, implement for standard gamepads
689+
for (const auto& channelChild: mChannelChildren) {
690+
channelChild->AddPromise(mPromiseID, promise);
691+
channelChild->SendVibrateHaptic(aControllerIdx, aHapticIndex,
692+
aIntensity, aDuration,
693+
mPromiseID);
694+
}
690695
}
691696

692697
++mPromiseID;

dom/gamepad/GamepadManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class GamepadManager final : public nsIObserver,
8787
// Trigger vibrate haptic event to gamepad channels.
8888
already_AddRefed<Promise> VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
8989
double aIntensity, double aDuration,
90-
nsIGlobalObject* aGlobal, ErrorResult& aRv);
90+
nsIGlobalObject* aGlobal);
9191

9292
protected:
9393
GamepadManager();

dom/gamepad/GamepadPlatformService.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ GamepadPlatformService::NotifyGamepadChange(const T& aInfo)
8686
uint32_t
8787
GamepadPlatformService::AddGamepad(const char* aID,
8888
GamepadMappingType aMapping,
89-
uint32_t aNumButtons, uint32_t aNumAxes)
89+
GamepadHand aHand,
90+
uint32_t aNumButtons, uint32_t aNumAxes,
91+
uint32_t aHaptics)
9092
{
9193
// This method is called by monitor thread populated in
9294
// platform-dependent backends
@@ -95,8 +97,8 @@ GamepadPlatformService::AddGamepad(const char* aID,
9597

9698
uint32_t index = ++mGamepadIndex;
9799
GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), index,
98-
aMapping, GamepadHand::_empty, GamepadServiceType::Standard,
99-
aNumButtons, aNumAxes, 0);
100+
aMapping, aHand, GamepadServiceType::Standard,
101+
aNumButtons, aNumAxes, aHaptics);
100102

101103
NotifyGamepadChange<GamepadAdded>(a);
102104
return index;
@@ -151,6 +153,19 @@ GamepadPlatformService::NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
151153
NotifyGamepadChange<GamepadAxisInformation>(a);
152154
}
153155

156+
void
157+
GamepadPlatformService::NewPoseEvent(uint32_t aIndex,
158+
const GamepadPoseState& aPose)
159+
{
160+
// This method is called by monitor thread populated in
161+
// platform-dependent backends
162+
MOZ_ASSERT(XRE_IsParentProcess());
163+
MOZ_ASSERT(!NS_IsMainThread());
164+
GamepadPoseInformation a(aIndex, GamepadServiceType::Standard,
165+
aPose);
166+
NotifyGamepadChange<GamepadPoseInformation>(a);
167+
}
168+
154169
void
155170
GamepadPlatformService::ResetGamepadIndexes()
156171
{

dom/gamepad/GamepadPlatformService.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ class GamepadPlatformService final
3838

3939
// Add a gamepad to the list of known gamepads, and return its index.
4040
uint32_t AddGamepad(const char* aID, GamepadMappingType aMapping,
41-
uint32_t aNumButtons, uint32_t aNumAxes);
41+
GamepadHand aHand, uint32_t aNumButtons,
42+
uint32_t aNumAxes, uint32_t aNumHaptics);
4243
// Remove the gamepad at |aIndex| from the list of known gamepads.
4344
void RemoveGamepad(uint32_t aIndex);
4445

@@ -55,6 +56,9 @@ class GamepadPlatformService final
5556
// windows that are listening and visible, and fire a gamepadaxismove
5657
// event at them as well.
5758
void NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis, double aValue);
59+
// Update the state of |aState| for the gamepad at |aIndex| for all
60+
// windows that are listening and visible.
61+
void NewPoseEvent(uint32_t aIndex, const GamepadPoseState& aState);
5862

5963
// When shutting down the platform communications for gamepad, also reset the
6064
// indexes.

dom/gamepad/GamepadServiceTest.cpp

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,20 @@ GamepadServiceTest::DestroyPBackgroundActor()
113113
already_AddRefed<Promise>
114114
GamepadServiceTest::AddGamepad(const nsAString& aID,
115115
GamepadMappingType aMapping,
116+
GamepadHand aHand,
116117
uint32_t aNumButtons,
117118
uint32_t aNumAxes,
119+
uint32_t aNumHaptics,
118120
ErrorResult& aRv)
119121
{
120122
if (mShuttingDown) {
121123
return nullptr;
122124
}
123125

124126
GamepadAdded a(nsString(aID), 0,
125-
aMapping, GamepadHand::_empty,
127+
aMapping, aHand,
126128
GamepadServiceType::Standard,
127-
aNumButtons, aNumAxes, 0);
129+
aNumButtons, aNumAxes, aNumHaptics);
128130
GamepadChangeEvent e(a);
129131
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
130132

@@ -230,6 +232,87 @@ GamepadServiceTest::NewAxisMoveEvent(uint32_t aIndex,
230232
}
231233
}
232234

235+
void
236+
GamepadServiceTest::NewPoseMove(uint32_t aIndex,
237+
const Nullable<Float32Array>& aOrient,
238+
const Nullable<Float32Array>& aPos,
239+
const Nullable<Float32Array>& aAngVelocity,
240+
const Nullable<Float32Array>& aAngAcceleration,
241+
const Nullable<Float32Array>& aLinVelocity,
242+
const Nullable<Float32Array>& aLinAcceleration)
243+
{
244+
if (mShuttingDown) {
245+
return;
246+
}
247+
248+
GamepadPoseState poseState;
249+
poseState.flags = GamepadCapabilityFlags::Cap_Orientation |
250+
GamepadCapabilityFlags::Cap_Position |
251+
GamepadCapabilityFlags::Cap_AngularAcceleration |
252+
GamepadCapabilityFlags::Cap_LinearAcceleration;
253+
if (!aOrient.IsNull()) {
254+
const Float32Array& value = aOrient.Value();
255+
value.ComputeLengthAndData();
256+
MOZ_ASSERT(value.Length() == 4);
257+
poseState.orientation[0] = value.Data()[0];
258+
poseState.orientation[1] = value.Data()[1];
259+
poseState.orientation[2] = value.Data()[2];
260+
poseState.orientation[3] = value.Data()[3];
261+
}
262+
if (!aPos.IsNull()) {
263+
const Float32Array& value = aPos.Value();
264+
value.ComputeLengthAndData();
265+
MOZ_ASSERT(value.Length() == 3);
266+
poseState.position[0] = value.Data()[0];
267+
poseState.position[1] = value.Data()[1];
268+
poseState.position[2] = value.Data()[2];
269+
}
270+
if (!aAngVelocity.IsNull()) {
271+
const Float32Array& value = aAngVelocity.Value();
272+
value.ComputeLengthAndData();
273+
MOZ_ASSERT(value.Length() == 3);
274+
poseState.angularVelocity[0] = value.Data()[0];
275+
poseState.angularVelocity[1] = value.Data()[1];
276+
poseState.angularVelocity[2] = value.Data()[2];
277+
}
278+
if (!aAngAcceleration.IsNull()) {
279+
const Float32Array& value = aAngAcceleration.Value();
280+
value.ComputeLengthAndData();
281+
MOZ_ASSERT(value.Length() == 3);
282+
poseState.angularAcceleration[0] = value.Data()[0];
283+
poseState.angularAcceleration[1] = value.Data()[1];
284+
poseState.angularAcceleration[2] = value.Data()[2];
285+
}
286+
if (!aLinVelocity.IsNull()) {
287+
const Float32Array& value = aLinVelocity.Value();
288+
value.ComputeLengthAndData();
289+
MOZ_ASSERT(value.Length() == 3);
290+
poseState.linearVelocity[0] = value.Data()[0];
291+
poseState.linearVelocity[1] = value.Data()[1];
292+
poseState.linearVelocity[2] = value.Data()[2];
293+
}
294+
if (!aLinAcceleration.IsNull()) {
295+
const Float32Array& value = aLinAcceleration.Value();
296+
value.ComputeLengthAndData();
297+
MOZ_ASSERT(value.Length() == 3);
298+
poseState.linearAcceleration[0] = value.Data()[0];
299+
poseState.linearAcceleration[1] = value.Data()[1];
300+
poseState.linearAcceleration[2] = value.Data()[2];
301+
}
302+
303+
GamepadPoseInformation a(aIndex, GamepadServiceType::Standard,
304+
poseState);
305+
GamepadChangeEvent e(a);
306+
307+
uint32_t id = ++mEventNumber;
308+
if (mChild) {
309+
mChild->SendGamepadTestEvent(id, e);
310+
} else {
311+
PendingOperation op(id, e);
312+
mPendingOperations.AppendElement(op);
313+
}
314+
}
315+
233316
void
234317
GamepadServiceTest::FlushPendingOperations()
235318
{

dom/gamepad/GamepadServiceTest.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,28 @@ class GamepadServiceTest final : public DOMEventTargetHelper,
3131

3232
GamepadMappingType NoMapping() const { return GamepadMappingType::_empty; }
3333
GamepadMappingType StandardMapping() const { return GamepadMappingType::Standard; }
34+
GamepadHand NoHand() const { return GamepadHand::_empty; }
35+
GamepadHand LeftHand() const { return GamepadHand::Left; }
36+
GamepadHand RightHand() const { return GamepadHand::Right; }
3437

3538
already_AddRefed<Promise> AddGamepad(const nsAString& aID,
3639
GamepadMappingType aMapping,
40+
GamepadHand aHand,
3741
uint32_t aNumButtons,
3842
uint32_t aNumAxes,
43+
uint32_t aNumHaptics,
3944
ErrorResult& aRv);
4045
void RemoveGamepad(uint32_t aIndex);
4146
void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed);
4247
void NewButtonValueEvent(uint32_t aIndex, uint32_t aButton, bool aPressed, double aValue);
4348
void NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis, double aValue);
49+
void NewPoseMove(uint32_t aIndex,
50+
const Nullable<Float32Array>& aOrient,
51+
const Nullable<Float32Array>& aPos,
52+
const Nullable<Float32Array>& aAngVelocity,
53+
const Nullable<Float32Array>& aAngAcceleration,
54+
const Nullable<Float32Array>& aLinVelocity,
55+
const Nullable<Float32Array>& aLinAcceleration);
4456
void Shutdown();
4557

4658
static already_AddRefed<GamepadServiceTest> CreateTestService(nsPIDOMWindowInner* aWindow);

dom/gamepad/android/AndroidGamepad.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ class AndroidGamepadManager final
2929
if (aAdded) {
3030
const int svc_id = service->AddGamepad(
3131
"android", GamepadMappingType::Standard,
32-
kStandardGamepadButtons, kStandardGamepadAxes);
32+
GamepadHand::_empty, kStandardGamepadButtons,
33+
kStandardGamepadAxes, 0); // TODO: Bug 680289, implement gamepad haptics for Android
3334
java::AndroidGamepadManager::OnGamepadAdded(aID, svc_id);
3435

3536
} else {

dom/gamepad/cocoa/CocoaGamepad.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,10 @@ DarwinGamepadService::DeviceAdded(IOHIDDeviceRef device)
284284
sprintf(buffer, "%x-%x-%s", vendorId, productId, product_name);
285285
uint32_t index = service->AddGamepad(buffer,
286286
mozilla::dom::GamepadMappingType::_empty,
287+
mozilla::dom::GamepadHand::_empty,
287288
(int)mGamepads[slot].numButtons(),
288-
(int)mGamepads[slot].numAxes());
289+
(int)mGamepads[slot].numAxes(),
290+
0); // TODO: Bug 680289, implement gamepad haptics for cocoa
289291
mGamepads[slot].mSuperIndex = index;
290292
}
291293

dom/gamepad/ipc/GamepadEventChannelChild.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,25 @@ GamepadEventChannelChild::RecvGamepadUpdate(
3838
return IPC_OK();
3939
}
4040

41+
void
42+
GamepadEventChannelChild::AddPromise(const uint32_t& aID, dom::Promise* aPromise)
43+
{
44+
MOZ_ASSERT(!mPromiseList.Get(aID, nullptr));
45+
mPromiseList.Put(aID, aPromise);
46+
}
47+
48+
mozilla::ipc::IPCResult
49+
GamepadEventChannelChild::RecvReplyGamepadVibrateHaptic(const uint32_t& aPromiseID)
50+
{
51+
RefPtr<dom::Promise> p;
52+
if (!mPromiseList.Get(aPromiseID, getter_AddRefs(p))) {
53+
MOZ_CRASH("We should always have a promise.");
54+
}
55+
56+
p->MaybeResolve(true);
57+
mPromiseList.Remove(aPromiseID);
58+
return IPC_OK();
59+
}
60+
4161
} // namespace dom
4262
} // namespace mozilla

dom/gamepad/ipc/GamepadEventChannelChild.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ namespace dom{
1111

1212
class GamepadEventChannelChild final : public PGamepadEventChannelChild
1313
{
14-
public:
14+
public:
1515
GamepadEventChannelChild() {}
1616
~GamepadEventChannelChild() {}
1717
virtual mozilla::ipc::IPCResult
1818
RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent) override;
19+
virtual mozilla::ipc::IPCResult
20+
RecvReplyGamepadVibrateHaptic(const uint32_t& aPromiseID) override;
21+
void AddPromise(const uint32_t& aID, dom::Promise* aPromise);
22+
23+
private:
24+
nsRefPtrHashtable<nsUint32HashKey, dom::Promise> mPromiseList;
1925
};
2026

2127
}// namespace dom

dom/gamepad/ipc/GamepadEventChannelParent.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,22 @@ GamepadEventChannelParent::RecvGamepadListenerRemoved()
7373
return IPC_OK();
7474
}
7575

76+
mozilla::ipc::IPCResult
77+
GamepadEventChannelParent::RecvVibrateHaptic(const uint32_t& aControllerIdx,
78+
const uint32_t& aHapticIndex,
79+
const double& aIntensity,
80+
const double& aDuration,
81+
const uint32_t& aPromiseID)
82+
{
83+
// TODO: Bug 680289, implement for standard gamepads
84+
85+
if (SendReplyGamepadVibrateHaptic(aPromiseID)) {
86+
return IPC_OK();
87+
}
88+
89+
return IPC_FAIL(this, "SendReplyGamepadVibrateHaptic fail.");
90+
}
91+
7692
void
7793
GamepadEventChannelParent::ActorDestroy(ActorDestroyReason aWhy)
7894
{

dom/gamepad/ipc/GamepadEventChannelParent.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ class GamepadEventChannelParent final : public PGamepadEventChannelParent
1717
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
1818
virtual mozilla::ipc::IPCResult RecvGamepadListenerAdded() override;
1919
virtual mozilla::ipc::IPCResult RecvGamepadListenerRemoved() override;
20+
virtual mozilla::ipc::IPCResult RecvVibrateHaptic(const uint32_t& aControllerIdx,
21+
const uint32_t& aHapticIndex,
22+
const double& aIntensity,
23+
const double& aDuration,
24+
const uint32_t& aPromiseID) override;
2025
void DispatchUpdateEvent(const GamepadChangeEvent& aEvent);
2126
bool HasGamepadListener() const { return mHasGamepadListener; }
2227
private:

dom/gamepad/ipc/GamepadTestChannelChild.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ class GamepadTestChannelChild final : public PGamepadTestChannelChild
2020
private:
2121
virtual mozilla::ipc::IPCResult RecvReplyGamepadIndex(const uint32_t& aID,
2222
const uint32_t& aIndex) override;
23-
nsRefPtrHashtable<nsUint32HashKey, Promise> mPromiseList;
23+
24+
nsRefPtrHashtable<nsUint32HashKey, dom::Promise> mPromiseList;
2425
};
2526

2627
}// namespace dom

dom/gamepad/ipc/GamepadTestChannelParent.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ GamepadTestChannelParent::RecvGamepadTestEvent(const uint32_t& aID,
2424
LossyCopyUTF16toASCII(a.id(), gamepadID);
2525
uint32_t index = service->AddGamepad(gamepadID.get(),
2626
static_cast<GamepadMappingType>(a.mapping()),
27+
a.hand(),
2728
a.num_buttons(),
28-
a.num_axes());
29+
a.num_axes(),
30+
a.num_haptics());
2931
if (!mShuttingdown) {
3032
Unused << SendReplyGamepadIndex(aID, index);
3133
}
@@ -46,6 +48,11 @@ GamepadTestChannelParent::RecvGamepadTestEvent(const uint32_t& aID,
4648
service->NewAxisMoveEvent(a.index(), a.axis(), a.value());
4749
return IPC_OK();
4850
}
51+
if (aEvent.type() == GamepadChangeEvent::TGamepadPoseInformation) {
52+
const GamepadPoseInformation& a = aEvent.get_GamepadPoseInformation();
53+
service->NewPoseEvent(a.index(), a.pose_state());
54+
return IPC_OK();
55+
}
4956

5057
NS_WARNING("Unknown event type.");
5158
return IPC_FAIL_NO_REASON(this);

dom/gamepad/ipc/PGamepadEventChannel.ipdl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ async protocol PGamepadEventChannel {
1212
parent:
1313
async GamepadListenerAdded();
1414
async GamepadListenerRemoved();
15+
async VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
16+
double aIntensity, double aDuration, uint32_t aPromiseID);
1517
child:
1618
async __delete__();
1719
async GamepadUpdate(GamepadChangeEvent aGamepadEvent);
20+
async ReplyGamepadVibrateHaptic(uint32_t aPromiseID);
1821
};
1922

2023
}

dom/gamepad/linux/LinuxGamepad.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ LinuxGamepadService::AddDevice(struct udev_device* dev)
147147

148148
gamepad.index = service->AddGamepad(gamepad.idstring,
149149
mozilla::dom::GamepadMappingType::_empty,
150+
mozilla::dom::GamepadHand::_empty,
150151
gamepad.numButtons,
151-
gamepad.numAxes);
152+
gamepad.numAxes,
153+
0); // TODO: Bug 680289, implement gamepad haptics for Linux.
152154

153155
gamepad.source_id =
154156
g_io_add_watch(channel,

0 commit comments

Comments
 (0)