Skip to content

Commit

Permalink
Bug 1523351 - Part 3: Handling GamepadTouch and GamepadLightIndicator…
Browse files Browse the repository at this point in the history
… events in Gamepad service. r=baku

Differential Revision: https://phabricator.services.mozilla.com/D29290

--HG--
extra : moz-landing-system : lando
  • Loading branch information
daoshengmu committed May 29, 2019
1 parent 304abbd commit fdcc151
Show file tree
Hide file tree
Showing 17 changed files with 209 additions and 35 deletions.
68 changes: 58 additions & 10 deletions dom/gamepad/GamepadManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,17 @@ void GamepadManager::AddGamepad(uint32_t aIndex, const nsAString& aId,
GamepadMappingType aMapping, GamepadHand aHand,
GamepadServiceType aServiceType,
uint32_t aDisplayID, uint32_t aNumButtons,
uint32_t aNumAxes, uint32_t aNumHaptics) {
uint32_t aNumAxes, uint32_t aNumHaptics,
uint32_t aNumLightIndicator,
uint32_t aNumTouchEvents) {
uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);

// TODO: bug 852258: get initial button/axis state
RefPtr<Gamepad> gamepad = new Gamepad(nullptr, aId,
0, // index is set by global window
newIndex, aMapping, aHand, aDisplayID,
aNumButtons, aNumAxes, aNumHaptics);
RefPtr<Gamepad> gamepad =
new Gamepad(nullptr, aId,
0, // index is set by global window
newIndex, aMapping, aHand, aDisplayID, aNumButtons, aNumAxes,
aNumHaptics, aNumLightIndicator, aNumTouchEvents);

// We store the gamepad related to its index given by the parent process,
// and no duplicate index is allowed.
Expand Down Expand Up @@ -471,7 +474,8 @@ void GamepadManager::Update(const GamepadChangeEvent& aEvent) {
const GamepadAdded& a = body.get_GamepadAdded();
AddGamepad(index, a.id(), static_cast<GamepadMappingType>(a.mapping()),
static_cast<GamepadHand>(a.hand()), serviceType, a.display_id(),
a.num_buttons(), a.num_axes(), a.num_haptics());
a.num_buttons(), a.num_axes(), a.num_haptics(), a.num_lights(),
a.num_touches());
return;
}
if (body.type() == GamepadChangeEventBody::TGamepadRemoved) {
Expand Down Expand Up @@ -561,6 +565,25 @@ bool GamepadManager::SetGamepadByEvent(const GamepadChangeEvent& aEvent,
gamepad->SetPose(a.pose_state());
break;
}
case GamepadChangeEventBody::TGamepadLightIndicatorTypeInformation: {
const GamepadLightIndicatorTypeInformation& a =
body.get_GamepadLightIndicatorTypeInformation();
gamepad->SetLightIndicatorType(a.light(), a.type());
break;
}
case GamepadChangeEventBody::TGamepadTouchInformation: {
// Avoid GamepadTouch's touchId be accessed in cross-origin tracking.
for (uint32_t i = 0; i < mListeners.Length(); i++) {
RefPtr<Gamepad> listenerGamepad = mListeners[i]->GetGamepad(index);
if (listenerGamepad && mListeners[i]->IsCurrentInnerWindow() &&
!mListeners[i]->GetOuterWindow()->IsBackground()) {
const GamepadTouchInformation& a =
body.get_GamepadTouchInformation();
listenerGamepad->SetTouchEvent(a.index(), a.touch_state());
}
}
break;
}
case GamepadChangeEventBody::TGamepadHandInformation: {
const GamepadHandInformation& a = body.get_GamepadHandInformation();
gamepad->SetHand(a.hand());
Expand All @@ -583,13 +606,12 @@ bool GamepadManager::SetGamepadByEvent(const GamepadChangeEvent& aEvent,
already_AddRefed<Promise> GamepadManager::VibrateHaptic(
uint32_t aControllerIdx, uint32_t aHapticIndex, double aIntensity,
double aDuration, nsIGlobalObject* aGlobal, ErrorResult& aRv) {
const char* kGamepadHapticEnabledPref = "dom.gamepad.haptic_feedback.enabled";
RefPtr<Promise> promise = Promise::Create(aGlobal, aRv);
if (NS_WARN_IF(aRv.Failed())) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
if (Preferences::GetBool(kGamepadHapticEnabledPref)) {
if (StaticPrefs::dom_gamepad_haptic_feedback_enabled()) {
if (aControllerIdx >= VR_GAMEPAD_IDX_OFFSET) {
if (gfx::VRManagerChild::IsCreated()) {
const uint32_t index = aControllerIdx - VR_GAMEPAD_IDX_OFFSET;
Expand All @@ -612,8 +634,7 @@ already_AddRefed<Promise> GamepadManager::VibrateHaptic(
}

void GamepadManager::StopHaptics() {
const char* kGamepadHapticEnabledPref = "dom.gamepad.haptic_feedback.enabled";
if (!Preferences::GetBool(kGamepadHapticEnabledPref)) {
if (!StaticPrefs::dom_gamepad_haptic_feedback_enabled()) {
return;
}

Expand All @@ -633,5 +654,32 @@ void GamepadManager::StopHaptics() {
}
}

already_AddRefed<Promise> GamepadManager::SetLightIndicatorColor(
uint32_t aControllerIdx, uint32_t aLightColorIndex, uint8_t aRed,
uint8_t aGreen, uint8_t aBlue, nsIGlobalObject* aGlobal, ErrorResult& aRv) {
RefPtr<Promise> promise = Promise::Create(aGlobal, aRv);
if (NS_WARN_IF(aRv.Failed())) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
if (StaticPrefs::dom_gamepad_extensions_lightindicator()) {
for (auto iter = mGamepads.Iter(); !iter.Done(); iter.Next()) {
const uint32_t gamepadIndex = iter.UserData()->HashKey();
if (gamepadIndex >= VR_GAMEPAD_IDX_OFFSET) {
MOZ_ASSERT(false && "We don't support light indicator in VR.");
} else {
for (auto& channelChild : mChannelChildren) {
channelChild->AddPromise(mPromiseID, promise);
channelChild->SendLightIndicatorColor(aControllerIdx,
aLightColorIndex, aRed, aGreen,
aBlue, mPromiseID);
}
}
}
}

++mPromiseID;
return promise.forget();
}
} // namespace dom
} // namespace mozilla
12 changes: 10 additions & 2 deletions dom/gamepad/GamepadManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ class GamepadManager final : public nsIObserver {
void AddGamepad(uint32_t aIndex, const nsAString& aID,
GamepadMappingType aMapping, GamepadHand aHand,
GamepadServiceType aServiceType, uint32_t aDisplayID,
uint32_t aNumButtons, uint32_t aNumAxes,
uint32_t aNumHaptics);
uint32_t aNumButtons, uint32_t aNumAxes, uint32_t aNumHaptics,
uint32_t aNumLightIndicator, uint32_t aNumTouchEvents);

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

// Set light indicator color event to gamepad channels.
already_AddRefed<Promise> SetLightIndicatorColor(uint32_t aControllerIdx,
uint32_t aLightColorIndex,
uint8_t aRed, uint8_t aGreen,
uint8_t aBlue,
nsIGlobalObject* aGlobal,
ErrorResult& aRv);

protected:
GamepadManager();
~GamepadManager(){};
Expand Down
3 changes: 3 additions & 0 deletions dom/gamepad/GamepadMonitoring.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ void MaybeStopGamepadMonitoring();
// (linux/LinuxGamepad.cpp, cocoa/CocoaGamepad.cpp, etc)
void StartGamepadMonitoring();
void StopGamepadMonitoring();
void SetGamepadLightIndicatorColor(uint32_t aControllerIdx,
uint32_t aLightColorIndex, uint8_t aRed,
uint8_t aGreen, uint8_t aBlue);

} // namespace dom
} // namespace mozilla
Expand Down
32 changes: 28 additions & 4 deletions dom/gamepad/GamepadPlatformService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ void GamepadPlatformService::NotifyGamepadChange(uint32_t aIndex,

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

// Only VR controllers has displayID, we give 0 to the general gamepads.
GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), aMapping,
aHand, 0, aNumButtons, aNumAxes, aHaptics);
aHand, 0, aNumButtons, aNumAxes, aHaptics, aNumLightIndicator,
aNumTouchEvents);

NotifyGamepadChange<GamepadAdded>(index, a);
return index;
Expand Down Expand Up @@ -145,16 +147,38 @@ void GamepadPlatformService::NewAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
NotifyGamepadChange<GamepadAxisInformation>(aIndex, a);
}

void GamepadPlatformService::NewLightIndicatorTypeEvent(
uint32_t aIndex, uint32_t aLight, GamepadLightIndicatorType aType) {
// This method is called by monitor thread populated in
// platform-dependent backends
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!NS_IsMainThread());
GamepadLightIndicatorTypeInformation a(aLight, aType);
NotifyGamepadChange<GamepadLightIndicatorTypeInformation>(aIndex, a);
}

void GamepadPlatformService::NewPoseEvent(uint32_t aIndex,
const GamepadPoseState& aPose) {
const GamepadPoseState& aState) {
// This method is called by monitor thread populated in
// platform-dependent backends
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!NS_IsMainThread());
GamepadPoseInformation a(aPose);
GamepadPoseInformation a(aState);
NotifyGamepadChange<GamepadPoseInformation>(aIndex, a);
}

void GamepadPlatformService::NewMultiTouchEvent(
uint32_t aIndex, uint32_t aTouchArrayIndex,
const GamepadTouchState& aState) {
// This method is called by monitor thread populated in
// platform-dependent backends
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!NS_IsMainThread());

GamepadTouchInformation a(aTouchArrayIndex, aState);
NotifyGamepadChange<GamepadTouchInformation>(aIndex, a);
}

void GamepadPlatformService::ResetGamepadIndexes() {
// This method is called by monitor thread populated in
// platform-dependent backends
Expand Down
11 changes: 10 additions & 1 deletion dom/gamepad/GamepadPlatformService.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class GamepadPlatformService final {
// Add a gamepad to the list of known gamepads, and return its index.
uint32_t AddGamepad(const char* aID, GamepadMappingType aMapping,
GamepadHand aHand, uint32_t aNumButtons,
uint32_t aNumAxes, uint32_t aNumHaptics);
uint32_t aNumAxes, uint32_t aNumHaptics,
uint32_t aNumLightIndicator, uint32_t aNumTouchEvents);
// Remove the gamepad at |aIndex| from the list of known gamepads.
void RemoveGamepad(uint32_t aIndex);

Expand All @@ -62,6 +63,14 @@ class GamepadPlatformService final {
// Update the state of |aState| for the gamepad at |aIndex| for all
// windows that are listening and visible.
void NewPoseEvent(uint32_t aIndex, const GamepadPoseState& aState);
// Update the type of |aType| for the gamepad at |aIndex| for all
// windows that are listening and visible.
void NewLightIndicatorTypeEvent(uint32_t aIndex, uint32_t aLight,
GamepadLightIndicatorType aType);
// Update the state of |aState| for the gamepad at |aIndex| with
// |aTouchArrayIndex| for all windows that are listening and visible.
void NewMultiTouchEvent(uint32_t aIndex, uint32_t aTouchArrayIndex,
const GamepadTouchState& aState);

// When shutting down the platform communications for gamepad, also reset the
// indexes.
Expand Down
6 changes: 4 additions & 2 deletions dom/gamepad/android/AndroidGamepad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ class AndroidGamepadManager final
if (aAdded) {
const int svc_id = service->AddGamepad(
"android", GamepadMappingType::Standard, GamepadHand::_empty,
kStandardGamepadButtons, kStandardGamepadAxes,
0); // TODO: Bug 680289, implement gamepad haptics for Android
kStandardGamepadButtons, kStandardGamepadAxes, 0, 0,
0); // TODO: Bug 680289, implement gamepad haptics for Android.
// TODO: Bug 1523355, implement gamepad lighindicator and touch for
// Android.
java::AndroidGamepadManager::OnGamepadAdded(aID, svc_id);

} else {
Expand Down
5 changes: 3 additions & 2 deletions dom/gamepad/cocoa/CocoaGamepad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,9 @@ void DarwinGamepadService::DeviceAdded(IOHIDDeviceRef device) {
uint32_t index = service->AddGamepad(
buffer, mozilla::dom::GamepadMappingType::_empty,
mozilla::dom::GamepadHand::_empty, (int)mGamepads[slot].numButtons(),
(int)mGamepads[slot].numAxes(),
0); // TODO: Bug 680289, implement gamepad haptics for cocoa
(int)mGamepads[slot].numAxes(), 0, 0,
0); // TODO: Bug 680289, implement gamepad haptics for cocoa.
// TODO: Bug 1523355, implement gamepad lighindicator and touch for cocoa.
mGamepads[slot].mSuperIndex = index;
}

Expand Down
2 changes: 1 addition & 1 deletion dom/gamepad/ipc/GamepadEventChannelChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void GamepadEventChannelChild::AddPromise(const uint32_t& aID,
mPromiseList.Put(aID, aPromise);
}

mozilla::ipc::IPCResult GamepadEventChannelChild::RecvReplyGamepadVibrateHaptic(
mozilla::ipc::IPCResult GamepadEventChannelChild::RecvReplyGamepadPromise(
const uint32_t& aPromiseID) {
RefPtr<dom::Promise> p;
if (!mPromiseList.Get(aPromiseID, getter_AddRefs(p))) {
Expand Down
3 changes: 1 addition & 2 deletions dom/gamepad/ipc/GamepadEventChannelChild.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ class GamepadEventChannelChild final : public PGamepadEventChannelChild {
~GamepadEventChannelChild() {}
mozilla::ipc::IPCResult RecvGamepadUpdate(
const GamepadChangeEvent& aGamepadEvent);
mozilla::ipc::IPCResult RecvReplyGamepadVibrateHaptic(
const uint32_t& aPromiseID);
mozilla::ipc::IPCResult RecvReplyGamepadPromise(const uint32_t& aPromiseID);
void AddPromise(const uint32_t& aID, dom::Promise* aPromise);

private:
Expand Down
24 changes: 21 additions & 3 deletions dom/gamepad/ipc/GamepadEventChannelParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,37 @@ mozilla::ipc::IPCResult GamepadEventChannelParent::RecvVibrateHaptic(
const uint32_t& aPromiseID) {
// TODO: Bug 680289, implement for standard gamepads

if (SendReplyGamepadVibrateHaptic(aPromiseID)) {
if (SendReplyGamepadPromise(aPromiseID)) {
return IPC_OK();
}

return IPC_FAIL(this, "SendReplyGamepadVibrateHaptic fail.");
return IPC_FAIL(this, "SendReplyGamepadPromise fail.");
}

mozilla::ipc::IPCResult GamepadEventChannelParent::RecvStopVibrateHaptic(
const uint32_t& aGamepadIndex) {
const uint32_t& aControllerIdx) {
// TODO: Bug 680289, implement for standard gamepads
return IPC_OK();
}

mozilla::ipc::IPCResult GamepadEventChannelParent::RecvLightIndicatorColor(
const uint32_t& aControllerIdx, const uint32_t& aLightColorIndex,
const uint8_t& aRed, const uint8_t& aGreen, const uint8_t& aBlue,
const uint32_t& aPromiseID) {
// It may be called because IPDL child side crashed, we'll
// not receive RecvGamepadListenerRemoved in that case
if (mHasGamepadListener) {
SetGamepadLightIndicatorColor(aControllerIdx, aLightColorIndex, aRed,
aGreen, aBlue);
}

if (SendReplyGamepadPromise(aPromiseID)) {
return IPC_OK();
}

return IPC_FAIL(this, "SendReplyGamepadPromise fail.");
}

void GamepadEventChannelParent::ActorDestroy(ActorDestroyReason aWhy) {
AssertIsOnBackgroundThread();

Expand Down
6 changes: 5 additions & 1 deletion dom/gamepad/ipc/GamepadEventChannelParent.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ class GamepadEventChannelParent final : public PGamepadEventChannelParent {
const double& aIntensity,
const double& aDuration,
const uint32_t& aPromiseID);
mozilla::ipc::IPCResult RecvStopVibrateHaptic(const uint32_t& aGamepadIndex);
mozilla::ipc::IPCResult RecvStopVibrateHaptic(const uint32_t& aControllerIdx);
mozilla::ipc::IPCResult RecvLightIndicatorColor(
const uint32_t& aControllerIdx, const uint32_t& aLightColorIndex,
const uint8_t& aRed, const uint8_t& aGreen, const uint8_t& aBlue,
const uint32_t& aPromiseID);
void DispatchUpdateEvent(const GamepadChangeEvent& aEvent);
bool HasGamepadListener() const { return mHasGamepadListener; }

Expand Down
18 changes: 17 additions & 1 deletion dom/gamepad/ipc/GamepadEventTypes.ipdlh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

using mozilla::dom::GamepadServiceType from "mozilla/dom/GamepadMessageUtils.h";
using mozilla::dom::GamepadPoseState from "mozilla/dom/GamepadMessageUtils.h";
using mozilla::dom::GamepadTouchState from "mozilla/dom/GamepadMessageUtils.h";
using mozilla::dom::GamepadLightIndicatorType from "mozilla/dom/GamepadMessageUtils.h";
using mozilla::dom::GamepadMappingType from "mozilla/dom/GamepadMessageUtils.h";
using mozilla::dom::GamepadHand from "mozilla/dom/GamepadMessageUtils.h";

Expand All @@ -19,6 +21,8 @@ struct GamepadAdded {
uint32_t num_buttons;
uint32_t num_axes;
uint32_t num_haptics;
uint32_t num_lights;
uint32_t num_touches;
};

struct GamepadRemoved {};
Expand All @@ -39,17 +43,29 @@ struct GamepadPoseInformation {
GamepadPoseState pose_state;
};

struct GamepadLightIndicatorTypeInformation {
uint32_t light;
GamepadLightIndicatorType type;
};

struct GamepadHandInformation {
GamepadHand hand;
};

struct GamepadTouchInformation {
uint32_t index;
GamepadTouchState touch_state;
};

union GamepadChangeEventBody {
GamepadAdded;
GamepadRemoved;
GamepadAxisInformation;
GamepadButtonInformation;
GamepadPoseInformation;
GamepadHandInformation;
GamepadLightIndicatorTypeInformation;
GamepadPoseInformation;
GamepadTouchInformation;
};

struct GamepadChangeEvent {
Expand Down
Loading

0 comments on commit fdcc151

Please sign in to comment.