diff options
Diffstat (limited to 'dom/gamepad/ipc')
-rw-r--r-- | dom/gamepad/ipc/GamepadEventChannelChild.cpp | 42 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadEventChannelChild.h | 24 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadEventChannelParent.cpp | 101 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadEventChannelParent.h | 31 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadEventTypes.ipdlh | 59 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadMessageUtils.h | 82 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadServiceType.h | 20 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadTestChannelChild.cpp | 32 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadTestChannelChild.h | 29 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadTestChannelParent.cpp | 63 | ||||
-rw-r--r-- | dom/gamepad/ipc/GamepadTestChannelParent.h | 33 | ||||
-rw-r--r-- | dom/gamepad/ipc/PGamepadEventChannel.ipdl | 21 | ||||
-rw-r--r-- | dom/gamepad/ipc/PGamepadTestChannel.ipdl | 21 |
13 files changed, 558 insertions, 0 deletions
diff --git a/dom/gamepad/ipc/GamepadEventChannelChild.cpp b/dom/gamepad/ipc/GamepadEventChannelChild.cpp new file mode 100644 index 000000000..4cdb55a92 --- /dev/null +++ b/dom/gamepad/ipc/GamepadEventChannelChild.cpp @@ -0,0 +1,42 @@ +/* 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/. */ +#include "GamepadEventChannelChild.h" +#include "mozilla/dom/GamepadManager.h" + +namespace mozilla { +namespace dom{ + +namespace { + +class GamepadUpdateRunnable final : public Runnable +{ + public: + explicit GamepadUpdateRunnable(const GamepadChangeEvent& aGamepadEvent) + : mEvent(aGamepadEvent) {} + NS_IMETHOD Run() override + { + RefPtr<GamepadManager> svc(GamepadManager::GetService()); + if (svc) { + svc->Update(mEvent); + } + return NS_OK; + } + protected: + GamepadChangeEvent mEvent; +}; + +} // namespace + +bool +GamepadEventChannelChild::RecvGamepadUpdate( + const GamepadChangeEvent& aGamepadEvent) +{ + DebugOnly<nsresult> rv = + NS_DispatchToMainThread(new GamepadUpdateRunnable(aGamepadEvent)); + NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NS_DispatchToMainThread failed"); + return true; +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/gamepad/ipc/GamepadEventChannelChild.h b/dom/gamepad/ipc/GamepadEventChannelChild.h new file mode 100644 index 000000000..686cbd640 --- /dev/null +++ b/dom/gamepad/ipc/GamepadEventChannelChild.h @@ -0,0 +1,24 @@ +/* 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/. */ +#include "mozilla/dom/PGamepadEventChannelChild.h" + +#ifndef mozilla_dom_GamepadEventChannelChild_h_ +#define mozilla_dom_GamepadEventChannelChild_h_ + +namespace mozilla{ +namespace dom{ + +class GamepadEventChannelChild final : public PGamepadEventChannelChild +{ + public: + GamepadEventChannelChild() {} + ~GamepadEventChannelChild() {} + virtual bool + RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent) override; +}; + +}// namespace dom +}// namespace mozilla + +#endif diff --git a/dom/gamepad/ipc/GamepadEventChannelParent.cpp b/dom/gamepad/ipc/GamepadEventChannelParent.cpp new file mode 100644 index 000000000..c3c8fd2c8 --- /dev/null +++ b/dom/gamepad/ipc/GamepadEventChannelParent.cpp @@ -0,0 +1,101 @@ +/* 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/. */ +#include "GamepadEventChannelParent.h" +#include "GamepadPlatformService.h" +#include "mozilla/dom/GamepadMonitoring.h" +#include "nsThreadUtils.h" + +namespace mozilla { +namespace dom { + +using namespace mozilla::ipc; + +namespace { + +class SendGamepadUpdateRunnable final : public Runnable +{ + private: + ~SendGamepadUpdateRunnable() {} + RefPtr<GamepadEventChannelParent> mParent; + GamepadChangeEvent mEvent; + public: + SendGamepadUpdateRunnable(GamepadEventChannelParent* aParent, + GamepadChangeEvent aEvent) + : mEvent(aEvent) + { + MOZ_ASSERT(aParent); + mParent = aParent; + } + NS_IMETHOD Run() override + { + AssertIsOnBackgroundThread(); + if(mParent->HasGamepadListener()) { + Unused << mParent->SendGamepadUpdate(mEvent); + } + return NS_OK; + } +}; + +} // namespace + +GamepadEventChannelParent::GamepadEventChannelParent() + : mHasGamepadListener(false) +{ + RefPtr<GamepadPlatformService> service = + GamepadPlatformService::GetParentService(); + MOZ_ASSERT(service); + service->AddChannelParent(this); + mBackgroundThread = NS_GetCurrentThread(); +} + +bool +GamepadEventChannelParent::RecvGamepadListenerAdded() +{ + AssertIsOnBackgroundThread(); + MOZ_ASSERT(!mHasGamepadListener); + mHasGamepadListener = true; + StartGamepadMonitoring(); + return true; +} + +bool +GamepadEventChannelParent::RecvGamepadListenerRemoved() +{ + AssertIsOnBackgroundThread(); + MOZ_ASSERT(mHasGamepadListener); + mHasGamepadListener = false; + RefPtr<GamepadPlatformService> service = + GamepadPlatformService::GetParentService(); + MOZ_ASSERT(service); + service->RemoveChannelParent(this); + Unused << Send__delete__(this); + return true; +} + +void +GamepadEventChannelParent::ActorDestroy(ActorDestroyReason aWhy) +{ + AssertIsOnBackgroundThread(); + + // It may be called because IPDL child side crashed, we'll + // not receive RecvGamepadListenerRemoved in that case + if (mHasGamepadListener) { + mHasGamepadListener = false; + RefPtr<GamepadPlatformService> service = + GamepadPlatformService::GetParentService(); + MOZ_ASSERT(service); + service->RemoveChannelParent(this); + } + MaybeStopGamepadMonitoring(); +} + +void +GamepadEventChannelParent::DispatchUpdateEvent(const GamepadChangeEvent& aEvent) +{ + mBackgroundThread->Dispatch(new SendGamepadUpdateRunnable(this, aEvent), + NS_DISPATCH_NORMAL); +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/gamepad/ipc/GamepadEventChannelParent.h b/dom/gamepad/ipc/GamepadEventChannelParent.h new file mode 100644 index 000000000..2ba005c35 --- /dev/null +++ b/dom/gamepad/ipc/GamepadEventChannelParent.h @@ -0,0 +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/. */ +#include "mozilla/dom/PGamepadEventChannelParent.h" + +#ifndef mozilla_dom_GamepadEventChannelParent_h_ +#define mozilla_dom_GamepadEventChannelParent_h_ + +namespace mozilla{ +namespace dom{ + +class GamepadEventChannelParent final : public PGamepadEventChannelParent +{ + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GamepadEventChannelParent) + GamepadEventChannelParent(); + virtual void ActorDestroy(ActorDestroyReason aWhy) override; + virtual bool RecvGamepadListenerAdded() override; + virtual bool RecvGamepadListenerRemoved() override; + void DispatchUpdateEvent(const GamepadChangeEvent& aEvent); + bool HasGamepadListener() const { return mHasGamepadListener; } + private: + ~GamepadEventChannelParent() {} + bool mHasGamepadListener; + nsCOMPtr<nsIThread> mBackgroundThread; +}; + +}// namespace dom +}// namespace mozilla + +#endif diff --git a/dom/gamepad/ipc/GamepadEventTypes.ipdlh b/dom/gamepad/ipc/GamepadEventTypes.ipdlh new file mode 100644 index 000000000..68ca36016 --- /dev/null +++ b/dom/gamepad/ipc/GamepadEventTypes.ipdlh @@ -0,0 +1,59 @@ +/* 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::GamepadServiceType from "mozilla/dom/GamepadMessageUtils.h"; +using mozilla::dom::GamepadPoseState from "mozilla/dom/GamepadMessageUtils.h"; + + +namespace mozilla { +namespace dom { + +struct GamepadAdded { + nsString id; + uint32_t index; + // Ideally, mapping should be a GamepadMappingType + // But, we have dependency problems in non MOZ_GAMEPAD + // platforms. Therefore, we make it as an uint32_t here. + uint32_t 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; + GamepadServiceType service_type; + uint32_t axis; + double value; +}; + +struct GamepadButtonInformation { + uint32_t index; + GamepadServiceType service_type; + uint32_t button; + bool pressed; + double value; +}; + +struct GamepadPoseInformation { + uint32_t index; + GamepadServiceType service_type; + GamepadPoseState pose_state; +}; + +union GamepadChangeEvent { + GamepadAdded; + GamepadRemoved; + GamepadAxisInformation; + GamepadButtonInformation; + GamepadPoseInformation; +}; + +} // namespace dom +} // namespace mozilla
\ No newline at end of file diff --git a/dom/gamepad/ipc/GamepadMessageUtils.h b/dom/gamepad/ipc/GamepadMessageUtils.h new file mode 100644 index 000000000..b9af6db9f --- /dev/null +++ b/dom/gamepad/ipc/GamepadMessageUtils.h @@ -0,0 +1,82 @@ + +#ifndef mozilla_dom_gamepad_GamepadMessageUtils_h +#define mozilla_dom_gamepad_GamepadMessageUtils_h + +#include "ipc/IPCMessageUtils.h" +#include "mozilla/dom/GamepadServiceType.h" +#include "mozilla/dom/GamepadPoseState.h" + +namespace IPC { + +template<> +struct ParamTraits<mozilla::dom::GamepadServiceType> : + public ContiguousEnumSerializer<mozilla::dom::GamepadServiceType, + mozilla::dom::GamepadServiceType(0), + mozilla::dom::GamepadServiceType( + mozilla::dom::GamepadServiceType::NumGamepadServiceType)> {}; + +template<> +struct ParamTraits<mozilla::dom::GamepadCapabilityFlags> : + public BitFlagsEnumSerializer<mozilla::dom::GamepadCapabilityFlags, + mozilla::dom::GamepadCapabilityFlags::Cap_All> {}; + +template <> +struct ParamTraits<mozilla::dom::GamepadPoseState> +{ + typedef mozilla::dom::GamepadPoseState paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.flags); + WriteParam(aMsg, aParam.orientation[0]); + WriteParam(aMsg, aParam.orientation[1]); + WriteParam(aMsg, aParam.orientation[2]); + WriteParam(aMsg, aParam.orientation[3]); + WriteParam(aMsg, aParam.position[0]); + WriteParam(aMsg, aParam.position[1]); + WriteParam(aMsg, aParam.position[2]); + WriteParam(aMsg, aParam.angularVelocity[0]); + WriteParam(aMsg, aParam.angularVelocity[1]); + WriteParam(aMsg, aParam.angularVelocity[2]); + WriteParam(aMsg, aParam.angularAcceleration[0]); + WriteParam(aMsg, aParam.angularAcceleration[1]); + WriteParam(aMsg, aParam.angularAcceleration[2]); + WriteParam(aMsg, aParam.linearVelocity[0]); + WriteParam(aMsg, aParam.linearVelocity[1]); + WriteParam(aMsg, aParam.linearVelocity[2]); + WriteParam(aMsg, aParam.linearAcceleration[0]); + WriteParam(aMsg, aParam.linearAcceleration[1]); + WriteParam(aMsg, aParam.linearAcceleration[2]); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) + { + if (!ReadParam(aMsg, aIter, &(aResult->flags)) || + !ReadParam(aMsg, aIter, &(aResult->orientation[0])) || + !ReadParam(aMsg, aIter, &(aResult->orientation[1])) || + !ReadParam(aMsg, aIter, &(aResult->orientation[2])) || + !ReadParam(aMsg, aIter, &(aResult->orientation[3])) || + !ReadParam(aMsg, aIter, &(aResult->position[0])) || + !ReadParam(aMsg, aIter, &(aResult->position[1])) || + !ReadParam(aMsg, aIter, &(aResult->position[2])) || + !ReadParam(aMsg, aIter, &(aResult->angularVelocity[0])) || + !ReadParam(aMsg, aIter, &(aResult->angularVelocity[1])) || + !ReadParam(aMsg, aIter, &(aResult->angularVelocity[2])) || + !ReadParam(aMsg, aIter, &(aResult->angularAcceleration[0])) || + !ReadParam(aMsg, aIter, &(aResult->angularAcceleration[1])) || + !ReadParam(aMsg, aIter, &(aResult->angularAcceleration[2])) || + !ReadParam(aMsg, aIter, &(aResult->linearVelocity[0])) || + !ReadParam(aMsg, aIter, &(aResult->linearVelocity[1])) || + !ReadParam(aMsg, aIter, &(aResult->linearVelocity[2])) || + !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[0])) || + !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[1])) || + !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[2]))) { + return false; + } + return true; + } +}; + +} // namespace IPC + +#endif // mozilla_dom_gamepad_GamepadMessageUtils_h
\ No newline at end of file diff --git a/dom/gamepad/ipc/GamepadServiceType.h b/dom/gamepad/ipc/GamepadServiceType.h new file mode 100644 index 000000000..acc0967d1 --- /dev/null +++ b/dom/gamepad/ipc/GamepadServiceType.h @@ -0,0 +1,20 @@ + +#ifndef mozilla_dom_GamepadServiceType_h_ +#define mozilla_dom_GamepadServiceType_h_ + +namespace mozilla{ +namespace dom{ + +// 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 +}; + +}// namespace dom +}// namespace mozilla + +#endif // mozilla_dom_GamepadServiceType_h_
\ No newline at end of file diff --git a/dom/gamepad/ipc/GamepadTestChannelChild.cpp b/dom/gamepad/ipc/GamepadTestChannelChild.cpp new file mode 100644 index 000000000..3fec9a7ea --- /dev/null +++ b/dom/gamepad/ipc/GamepadTestChannelChild.cpp @@ -0,0 +1,32 @@ +/* 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/. */ + +#include "GamepadTestChannelChild.h" + +namespace mozilla { +namespace dom { + +void +GamepadTestChannelChild::AddPromise(const uint32_t& aID, Promise* aPromise) +{ + MOZ_ASSERT(!mPromiseList.Get(aID, nullptr)); + mPromiseList.Put(aID, aPromise); +} + +bool +GamepadTestChannelChild::RecvReplyGamepadIndex(const uint32_t& aID, + const uint32_t& aIndex) +{ + RefPtr<Promise> p; + if (!mPromiseList.Get(aID, getter_AddRefs(p))) { + MOZ_CRASH("We should always have a promise."); + } + + p->MaybeResolve(aIndex); + mPromiseList.Remove(aID); + return true; +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/gamepad/ipc/GamepadTestChannelChild.h b/dom/gamepad/ipc/GamepadTestChannelChild.h new file mode 100644 index 000000000..f2c771fe3 --- /dev/null +++ b/dom/gamepad/ipc/GamepadTestChannelChild.h @@ -0,0 +1,29 @@ +/* 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/. */ + +#include "mozilla/dom/PGamepadTestChannelChild.h" +#include "mozilla/dom/Promise.h" + +#ifndef mozilla_dom_GamepadTestChannelChild_h_ +#define mozilla_dom_GamepadTestChannelChild_h_ + +namespace mozilla { +namespace dom { + +class GamepadTestChannelChild final : public PGamepadTestChannelChild +{ + public: + GamepadTestChannelChild() {} + ~GamepadTestChannelChild() {} + void AddPromise(const uint32_t& aID, Promise* aPromise); + private: + virtual bool RecvReplyGamepadIndex(const uint32_t& aID, + const uint32_t& aIndex) override; + nsRefPtrHashtable<nsUint32HashKey, Promise> mPromiseList; +}; + +}// namespace dom +}// namespace mozilla + +#endif diff --git a/dom/gamepad/ipc/GamepadTestChannelParent.cpp b/dom/gamepad/ipc/GamepadTestChannelParent.cpp new file mode 100644 index 000000000..421447fe0 --- /dev/null +++ b/dom/gamepad/ipc/GamepadTestChannelParent.cpp @@ -0,0 +1,63 @@ +/* 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/. */ + +#include "GamepadTestChannelParent.h" + +#include "mozilla/dom/GamepadPlatformService.h" +#include "mozilla/Unused.h" + +namespace mozilla { +namespace dom { + +bool +GamepadTestChannelParent::RecvGamepadTestEvent(const uint32_t& aID, + const GamepadChangeEvent& aEvent) +{ + mozilla::ipc::AssertIsOnBackgroundThread(); + 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(), + static_cast<GamepadMappingType>(a.mapping()), + a.num_buttons(), + a.num_axes()); + if (!mShuttingdown) { + Unused << SendReplyGamepadIndex(aID, index); + } + return true; + } + if (aEvent.type() == GamepadChangeEvent::TGamepadRemoved) { + const GamepadRemoved& a = aEvent.get_GamepadRemoved(); + service->RemoveGamepad(a.index()); + return true; + } + if (aEvent.type() == GamepadChangeEvent::TGamepadButtonInformation) { + const GamepadButtonInformation& a = aEvent.get_GamepadButtonInformation(); + service->NewButtonEvent(a.index(), a.button(), a.pressed(), a.value()); + return true; + } + if (aEvent.type() == GamepadChangeEvent::TGamepadAxisInformation) { + const GamepadAxisInformation& a = aEvent.get_GamepadAxisInformation(); + service->NewAxisMoveEvent(a.index(), a.axis(), a.value()); + return true; + } + + NS_WARNING("Unknown event type."); + return false; +} + +bool +GamepadTestChannelParent::RecvShutdownChannel() +{ + mShuttingdown = true; + Unused << Send__delete__(this); + return true; +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/gamepad/ipc/GamepadTestChannelParent.h b/dom/gamepad/ipc/GamepadTestChannelParent.h new file mode 100644 index 000000000..ce66667b8 --- /dev/null +++ b/dom/gamepad/ipc/GamepadTestChannelParent.h @@ -0,0 +1,33 @@ +/* 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/. */ + +#include "mozilla/dom/PGamepadTestChannelParent.h" + +#ifndef mozilla_dom_GamepadTestChannelParent_h_ +#define mozilla_dom_GamepadTestChannelParent_h_ + +namespace mozilla { +namespace dom { + +class GamepadTestChannelParent final : public PGamepadTestChannelParent +{ + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GamepadTestChannelParent) + GamepadTestChannelParent() + : mShuttingdown(false) {} + virtual void ActorDestroy(ActorDestroyReason aWhy) override {} + virtual bool + RecvGamepadTestEvent(const uint32_t& aID, + const GamepadChangeEvent& aGamepadEvent) override; + virtual bool + RecvShutdownChannel() override; + private: + ~GamepadTestChannelParent() {} + bool mShuttingdown; +}; + +}// namespace dom +}// namespace mozilla + +#endif diff --git a/dom/gamepad/ipc/PGamepadEventChannel.ipdl b/dom/gamepad/ipc/PGamepadEventChannel.ipdl new file mode 100644 index 000000000..78e389a91 --- /dev/null +++ b/dom/gamepad/ipc/PGamepadEventChannel.ipdl @@ -0,0 +1,21 @@ +/* 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/. */ +include protocol PBackground; +include GamepadEventTypes; + +namespace mozilla { +namespace dom { + +async protocol PGamepadEventChannel { + manager PBackground; + parent: + async GamepadListenerAdded(); + async GamepadListenerRemoved(); + child: + async __delete__(); + async GamepadUpdate(GamepadChangeEvent aGamepadEvent); +}; + +} +} diff --git a/dom/gamepad/ipc/PGamepadTestChannel.ipdl b/dom/gamepad/ipc/PGamepadTestChannel.ipdl new file mode 100644 index 000000000..57b694acc --- /dev/null +++ b/dom/gamepad/ipc/PGamepadTestChannel.ipdl @@ -0,0 +1,21 @@ +/* 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/. */ +include protocol PBackground; +include GamepadEventTypes; + +namespace mozilla { +namespace dom { + +async protocol PGamepadTestChannel { + manager PBackground; + parent: + async GamepadTestEvent(uint32_t aID, GamepadChangeEvent aGamepadEvent); + async ShutdownChannel(); + child: + async __delete__(); + async ReplyGamepadIndex(uint32_t aID, uint32_t aIndex); +}; + +} +} |