Bug 1299928 - Part 1: Make GamepadManager knows the gamepad is from VRController when adding gamepads; r?kip, lenzak800
MozReview-Commit-ID: IBFqj2JTHxh
--- a/dom/gamepad/Gamepad.h
+++ b/dom/gamepad/Gamepad.h
@@ -28,16 +28,25 @@ const int kStandardGamepadAxes = 4;
const int kButtonLeftTrigger = 6;
const int kButtonRightTrigger = 7;
const int kLeftStickXAxis = 0;
const int kLeftStickYAxis = 1;
const int kRightStickXAxis = 2;
const int kRightStickYAxis = 3;
+// Standard channel is used for managing gamepads that
+// are from GamepadPlatformService. VR channel
+// is for gamepads that are from VRManagerChild.
+enum class GamepadServiceType : uint16_t {
+ Standard,
+ VR,
+ NumGamepadServiceType
+};
+
class Gamepad final : public nsISupports,
public nsWrapperCache
{
public:
Gamepad(nsISupports* aParent,
const nsAString& aID, uint32_t aIndex,
GamepadMappingType aMapping,
uint32_t aNumButtons, uint32_t aNumAxes);
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -45,16 +45,17 @@ const char* kGamepadEventsEnabledPref =
"dom.gamepad.non_standard_events.enabled";
const nsTArray<RefPtr<nsGlobalWindow>>::index_type NoIndex =
nsTArray<RefPtr<nsGlobalWindow>>::NoIndex;
bool sShutdown = false;
StaticRefPtr<GamepadManager> gGamepadManagerSingleton;
+const uint32_t VR_GAMEPAD_IDX_OFFSET = 0x01 << 16;
} // namespace
NS_IMPL_ISUPPORTS(GamepadManager, nsIObserver)
GamepadManager::GamepadManager()
: mEnabled(false),
mNonstandardEventsEnabled(false),
@@ -183,50 +184,80 @@ GamepadManager::GetGamepad(uint32_t aInd
RefPtr<Gamepad> gamepad;
if (mGamepads.Get(aIndex, getter_AddRefs(gamepad))) {
return gamepad.forget();
}
return nullptr;
}
+uint32_t GamepadManager::GetGamepadIndexWithServiceType(uint32_t aIndex,
+ GamepadServiceType aServiceType)
+{
+ uint32_t newIndex = 0;
+
+ switch (aServiceType) {
+ case GamepadServiceType::Standard:
+ {
+ MOZ_ASSERT(aIndex <= VR_GAMEPAD_IDX_OFFSET);
+ newIndex = aIndex;
+ break;
+ }
+ case GamepadServiceType::VR:
+ {
+ newIndex = aIndex + VR_GAMEPAD_IDX_OFFSET;
+ break;
+ }
+ default:
+ MOZ_ASSERT(false);
+ break;
+ }
+
+ return newIndex;
+}
+
void
GamepadManager::AddGamepad(uint32_t aIndex,
const nsAString& aId,
GamepadMappingType aMapping,
+ GamepadServiceType aServiceType,
uint32_t aNumButtons,
uint32_t aNumAxes)
{
//TODO: bug 852258: get initial button/axis state
RefPtr<Gamepad> gamepad =
new Gamepad(nullptr,
aId,
0, // index is set by global window
aMapping,
aNumButtons,
aNumAxes);
+ uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
+
// We store the gamepad related to its index given by the parent process,
// and no duplicate index is allowed.
- MOZ_ASSERT(!mGamepads.Get(aIndex, nullptr));
- mGamepads.Put(aIndex, gamepad);
- NewConnectionEvent(aIndex, true);
+ MOZ_ASSERT(!mGamepads.Get(newIndex, nullptr));
+ mGamepads.Put(newIndex, gamepad);
+ NewConnectionEvent(newIndex, true);
}
void
-GamepadManager::RemoveGamepad(uint32_t aIndex)
+GamepadManager::RemoveGamepad(uint32_t aIndex, GamepadServiceType aServiceType)
{
- RefPtr<Gamepad> gamepad = GetGamepad(aIndex);
+ uint32_t newIndex = GetGamepadIndexWithServiceType(aIndex, aServiceType);
+
+ RefPtr<Gamepad> gamepad = GetGamepad(newIndex);
if (!gamepad) {
NS_WARNING("Trying to delete gamepad with invalid index");
return;
}
gamepad->SetConnected(false);
- NewConnectionEvent(aIndex, false);
- mGamepads.Remove(aIndex);
+ NewConnectionEvent(newIndex, false);
+ mGamepads.Remove(newIndex);
}
void
GamepadManager::NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed,
double aValue)
{
if (mShuttingDown) {
return;
@@ -539,23 +570,23 @@ GamepadManager::SetWindowHasSeenGamepad(
}
void
GamepadManager::Update(const GamepadChangeEvent& aEvent)
{
if (aEvent.type() == GamepadChangeEvent::TGamepadAdded) {
const GamepadAdded& a = aEvent.get_GamepadAdded();
AddGamepad(a.index(), a.id(),
- static_cast<GamepadMappingType>(a.mapping()),
+ a.mapping(), a.service_type(),
a.num_buttons(), a.num_axes());
return;
}
if (aEvent.type() == GamepadChangeEvent::TGamepadRemoved) {
const GamepadRemoved& a = aEvent.get_GamepadRemoved();
- RemoveGamepad(a.index());
+ RemoveGamepad(a.index(), a.service_type());
return;
}
if (aEvent.type() == GamepadChangeEvent::TGamepadButtonInformation) {
const GamepadButtonInformation& a = aEvent.get_GamepadButtonInformation();
NewButtonEvent(a.index(), a.button(), a.pressed(), a.value());
return;
}
if (aEvent.type() == GamepadChangeEvent::TGamepadAxisInformation) {
--- a/dom/gamepad/GamepadManager.h
+++ b/dom/gamepad/GamepadManager.h
@@ -42,20 +42,20 @@ class GamepadManager final : public nsIO
// Indicate that |aWindow| wants to receive gamepad events.
void AddListener(nsGlobalWindow* aWindow);
// Indicate that |aWindow| should no longer receive gamepad events.
void RemoveListener(nsGlobalWindow* aWindow);
// Add a gamepad to the list of known gamepads.
void AddGamepad(uint32_t aIndex, const nsAString& aID, GamepadMappingType aMapping,
- uint32_t aNumButtons, uint32_t aNumAxes);
+ GamepadServiceType aServiceType, uint32_t aNumButtons, uint32_t aNumAxes);
// Remove the gamepad at |aIndex| from the list of known gamepads.
- void RemoveGamepad(uint32_t aIndex);
+ void RemoveGamepad(uint32_t aIndex, GamepadServiceType aServiceType);
// Update the state of |aButton| for the gamepad at |aIndex| for all
// windows that are listening and visible, and fire one of
// a gamepadbutton{up,down} event at them as well.
// aPressed is used for digital buttons, aValue is for analog buttons.
void NewButtonEvent(uint32_t aIndex, uint32_t aButton, bool aPressed,
double aValue);
@@ -122,16 +122,19 @@ class GamepadManager final : public nsIO
// Returns true if we have already sent data from this gamepad
// to this window. This should only return true if the user
// explicitly interacted with a gamepad while this window
// was focused, by pressing buttons or similar actions.
bool WindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex) const;
// Indicate that a window has received data from a gamepad.
void SetWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex,
bool aHasSeen = true);
+ // Our gamepad index has VR_GAMEPAD_IDX_OFFSET while GamepadChannelType
+ // is from VRManager.
+ uint32_t GetGamepadIndexWithServiceType(uint32_t aIndex, GamepadServiceType aServiceType);
// Gamepads connected to the system. Copies of these are handed out
// to each window.
nsRefPtrHashtable<nsUint32HashKey, Gamepad> mGamepads;
// Inner windows that are listening for gamepad events.
// has been sent to that window.
nsTArray<RefPtr<nsGlobalWindow>> mListeners;
};
--- a/dom/gamepad/GamepadPlatformService.cpp
+++ b/dom/gamepad/GamepadPlatformService.cpp
@@ -82,29 +82,29 @@ GamepadPlatformService::AddGamepad(const
{
// This method is called by monitor thread populated in
// platform-dependent backends
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!NS_IsMainThread());
uint32_t index = ++mGamepadIndex;
GamepadAdded a(NS_ConvertUTF8toUTF16(nsDependentCString(aID)), index,
- (uint32_t)aMapping, aNumButtons, aNumAxes);
+ aMapping, GamepadServiceType::Standard, aNumButtons, aNumAxes);
NotifyGamepadChange<GamepadAdded>(a);
return index;
}
void
GamepadPlatformService::RemoveGamepad(uint32_t aIndex)
{
// This method is called by monitor thread populated in
// platform-dependent backends
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(!NS_IsMainThread());
- GamepadRemoved a(aIndex);
+ GamepadRemoved a(aIndex, GamepadServiceType::Standard);
NotifyGamepadChange<GamepadRemoved>(a);
}
void
GamepadPlatformService::NewButtonEvent(uint32_t aIndex, uint32_t aButton,
bool aPressed, double aValue)
{
// This method is called by monitor thread populated in
--- a/dom/gamepad/GamepadServiceTest.cpp
+++ b/dom/gamepad/GamepadServiceTest.cpp
@@ -117,18 +117,22 @@ GamepadServiceTest::AddGamepad(const nsA
uint32_t aNumButtons,
uint32_t aNumAxes,
ErrorResult& aRv)
{
if (mShuttingDown) {
return nullptr;
}
+ // Because GamepadServiceTest::AddGamepad() is opened for Web API,
+ // we need to convert aMapping from uint32_t to GamepadMappingType here.
GamepadAdded a(nsString(aID), 0,
- (uint32_t)aMapping, aNumButtons, aNumAxes);
+ static_cast<GamepadMappingType>(aMapping),
+ GamepadServiceType::Standard,
+ aNumButtons, aNumAxes);
GamepadChangeEvent e(a);
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
RefPtr<Promise> p = Promise::Create(go, aRv);
if (aRv.Failed()) {
return nullptr;
}
@@ -145,17 +149,17 @@ GamepadServiceTest::AddGamepad(const nsA
void
GamepadServiceTest::RemoveGamepad(uint32_t aIndex)
{
if (mShuttingDown) {
return;
}
- GamepadRemoved a(aIndex);
+ GamepadRemoved a(aIndex, GamepadServiceType::Standard);
GamepadChangeEvent e(a);
uint32_t id = ++mEventNumber;
if (mChild) {
mChild->SendGamepadTestEvent(id, e);
} else {
PendingOperation op(id, e);
mPendingOperations.AppendElement(op);
--- a/dom/gamepad/GamepadServiceTest.h
+++ b/dom/gamepad/GamepadServiceTest.h
@@ -3,16 +3,17 @@
/* 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/. */
#ifndef mozilla_dom_GamepadServiceTest_h_
#define mozilla_dom_GamepadServiceTest_h_
#include "nsIIPCBackgroundChildCreateCallback.h"
+#include "mozilla/dom/GamepadBinding.h"
namespace mozilla {
namespace dom {
class GamepadChangeEvent;
class GamepadManager;
class GamepadTestChannelChild;
class Promise;
--- a/dom/gamepad/ipc/GamepadEventTypes.ipdlh
+++ b/dom/gamepad/ipc/GamepadEventTypes.ipdlh
@@ -1,25 +1,31 @@
/* 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::GamepadMappingType from "mozilla/dom/GamepadMessageUtils.h";
+using mozilla::dom::GamepadServiceType from "mozilla/dom/GamepadMessageUtils.h";
+
+
namespace mozilla {
namespace dom {
struct GamepadAdded {
nsString id;
uint32_t index;
- uint32_t mapping;
+ GamepadMappingType mapping;
+ GamepadServiceType service_type;
uint32_t num_buttons;
uint32_t num_axes;
};
struct GamepadRemoved {
uint32_t index;
+ GamepadServiceType service_type;
};
struct GamepadAxisInformation {
uint32_t index;
uint32_t axis;
double value;
};
new file mode 100644
--- /dev/null
+++ b/dom/gamepad/ipc/GamepadMessageUtils.h
@@ -0,0 +1,24 @@
+
+#ifndef mozilla_dom_gamepad_GamepadMessageUtils_h
+#define mozilla_dom_gamepad_GamepadMessageUtils_h
+
+#include "ipc/IPCMessageUtils.h"
+#include "mozilla/dom/Gamepad.h"
+
+namespace IPC {
+
+template<>
+struct ParamTraits<mozilla::dom::GamepadMappingType> :
+ public ContiguousEnumSerializer<mozilla::dom::GamepadMappingType,
+ mozilla::dom::GamepadMappingType(mozilla::dom::GamepadMappingType::_empty),
+ mozilla::dom::GamepadMappingType(mozilla::dom::GamepadMappingType::EndGuard_)> {};
+
+template<>
+struct ParamTraits<mozilla::dom::GamepadServiceType> :
+ public ContiguousEnumSerializer<mozilla::dom::GamepadServiceType,
+ mozilla::dom::GamepadServiceType(0),
+ mozilla::dom::GamepadServiceType(
+ mozilla::dom::GamepadServiceType::NumGamepadServiceType)> {};
+} // namespace IPC
+
+#endif // mozilla_dom_gamepad_GamepadMessageUtils_h
\ No newline at end of file
--- a/dom/gamepad/ipc/GamepadTestChannelParent.cpp
+++ b/dom/gamepad/ipc/GamepadTestChannelParent.cpp
@@ -18,17 +18,17 @@ GamepadTestChannelParent::RecvGamepadTes
RefPtr<GamepadPlatformService> service =
GamepadPlatformService::GetParentService();
MOZ_ASSERT(service);
if (aEvent.type() == GamepadChangeEvent::TGamepadAdded) {
const GamepadAdded& a = aEvent.get_GamepadAdded();
nsCString gamepadID;
LossyCopyUTF16toASCII(a.id(), gamepadID);
uint32_t index = service->AddGamepad(gamepadID.get(),
- (GamepadMappingType)a.mapping(),
+ a.mapping(),
a.num_buttons(),
a.num_axes());
if (!mShuttingdown) {
Unused << SendReplyGamepadIndex(aID, index);
}
return true;
}
if (aEvent.type() == GamepadChangeEvent::TGamepadRemoved) {
--- a/dom/gamepad/moz.build
+++ b/dom/gamepad/moz.build
@@ -15,16 +15,17 @@ if CONFIG['MOZ_GAMEPAD']:
'Gamepad.h',
'GamepadButton.h',
'GamepadManager.h',
'GamepadMonitoring.h',
'GamepadPlatformService.h',
'GamepadServiceTest.h',
'ipc/GamepadEventChannelChild.h',
'ipc/GamepadEventChannelParent.h',
+ 'ipc/GamepadMessageUtils.h',
'ipc/GamepadTestChannelChild.h',
'ipc/GamepadTestChannelParent.h'
]
UNIFIED_SOURCES = [
'Gamepad.cpp',
'GamepadButton.cpp',
'GamepadManager.cpp',
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -32,16 +32,17 @@ static StaticRefPtr<VRManagerParent> sVR
void ReleaseVRManagerParentSingleton() {
sVRManagerParentSingleton = nullptr;
}
VRManagerChild::VRManagerChild()
: TextureForwarder()
, mDisplaysInitialized(false)
+ , mGamepadManager(nullptr)
, mInputFrameID(-1)
, mMessageLoop(MessageLoop::current())
, mFrameRequestCallbackCounter(0)
, mBackend(layers::LayersBackend::LAYERS_NONE)
{
MOZ_COUNT_CTOR(VRManagerChild);
MOZ_ASSERT(NS_IsMainThread());