diff --git a/dom/gamepad/GamepadServiceTest.cpp b/dom/gamepad/GamepadServiceTest.cpp index d14a764e88c6..383ab92e8bde 100644 --- a/dom/gamepad/GamepadServiceTest.cpp +++ b/dom/gamepad/GamepadServiceTest.cpp @@ -71,17 +71,16 @@ void GamepadServiceTest::InitPBackgroundActor() { MOZ_CRASH("Failed to create a PBackgroundChild actor!"); } - mChild = GamepadTestChannelChild::Create(); + mChild = new GamepadTestChannelChild(); PGamepadTestChannelChild* initedChild = - actor->SendPGamepadTestChannelConstructor(mChild.get()); + actor->SendPGamepadTestChannelConstructor(mChild); if (NS_WARN_IF(!initedChild)) { MOZ_CRASH("Failed to create a PBackgroundChild actor!"); } } void GamepadServiceTest::DestroyPBackgroundActor() { - MOZ_ASSERT(mChild); - PGamepadTestChannelChild::Send__delete__(mChild); + mChild->SendShutdownChannel(); mChild = nullptr; } diff --git a/dom/gamepad/GamepadServiceTest.h b/dom/gamepad/GamepadServiceTest.h index eacc8bc5fb90..3e97a0438515 100644 --- a/dom/gamepad/GamepadServiceTest.h +++ b/dom/gamepad/GamepadServiceTest.h @@ -70,7 +70,7 @@ class GamepadServiceTest final : public DOMEventTargetHelper { // IPDL Channel for us to send test events to GamepadPlatformService, it // will only be used in this singleton class and deleted during the IPDL // shutdown chain - RefPtr mChild; + GamepadTestChannelChild* MOZ_NON_OWNING_REF mChild; explicit GamepadServiceTest(nsPIDOMWindowInner* aWindow); ~GamepadServiceTest(); diff --git a/dom/gamepad/ipc/GamepadTestChannelChild.cpp b/dom/gamepad/ipc/GamepadTestChannelChild.cpp index adc9182058e8..6c6d47136665 100644 --- a/dom/gamepad/ipc/GamepadTestChannelChild.cpp +++ b/dom/gamepad/ipc/GamepadTestChannelChild.cpp @@ -9,11 +9,6 @@ namespace mozilla { namespace dom { -already_AddRefed GamepadTestChannelChild::Create() { - return RefPtr(new GamepadTestChannelChild()) - .forget(); -} - void GamepadTestChannelChild::AddPromise(const uint32_t& aID, Promise* aPromise) { MOZ_ASSERT(!mPromiseList.Get(aID, nullptr)); diff --git a/dom/gamepad/ipc/GamepadTestChannelChild.h b/dom/gamepad/ipc/GamepadTestChannelChild.h index 8b39c9efab9c..860f2bbca4de 100644 --- a/dom/gamepad/ipc/GamepadTestChannelChild.h +++ b/dom/gamepad/ipc/GamepadTestChannelChild.h @@ -14,28 +14,18 @@ namespace mozilla { namespace dom { class GamepadTestChannelChild final : public PGamepadTestChannelChild { + friend class PGamepadTestChannelChild; + public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GamepadTestChannelChild) - - static already_AddRefed Create(); - - void AddPromise(const uint32_t& aID, Promise* aPromise); - - GamepadTestChannelChild(const GamepadTestChannelChild&) = delete; - GamepadTestChannelChild(GamepadTestChannelChild&&) = delete; - GamepadTestChannelChild& operator=(const GamepadTestChannelChild&) = delete; - GamepadTestChannelChild& operator=(GamepadTestChannelChild&&) = delete; - - private: GamepadTestChannelChild() = default; ~GamepadTestChannelChild() = default; + void AddPromise(const uint32_t& aID, Promise* aPromise); + private: mozilla::ipc::IPCResult RecvReplyGamepadIndex(const uint32_t& aID, const uint32_t& aIndex); nsRefPtrHashtable mPromiseList; - - friend class PGamepadTestChannelChild; }; } // namespace dom diff --git a/dom/gamepad/ipc/GamepadTestChannelParent.cpp b/dom/gamepad/ipc/GamepadTestChannelParent.cpp index 169541b23505..1b79a592e450 100644 --- a/dom/gamepad/ipc/GamepadTestChannelParent.cpp +++ b/dom/gamepad/ipc/GamepadTestChannelParent.cpp @@ -12,21 +12,18 @@ namespace mozilla { namespace dom { -already_AddRefed GamepadTestChannelParent::Create() { - return RefPtr(new GamepadTestChannelParent()) - .forget(); -} - -GamepadTestChannelParent::GamepadTestChannelParent() { +bool GamepadTestChannelParent::Init() { AssertIsOnBackgroundThread(); RefPtr service = GamepadPlatformService::GetParentService(); MOZ_ASSERT(service); service->GetMonitoringState().AddObserver(this); + + return true; } -GamepadTestChannelParent::~GamepadTestChannelParent() { +void GamepadTestChannelParent::ActorDestroy(ActorDestroyReason aWhy) { AssertIsOnBackgroundThread(); RefPtr service = GamepadPlatformService::GetParentService(); @@ -50,8 +47,9 @@ void GamepadTestChannelParent::AddGamepadToPlatformService( gamepadID.get(), static_cast(a.mapping()), a.hand(), a.num_buttons(), a.num_axes(), a.num_haptics(), a.num_lights(), a.num_touches()); - - Unused << SendReplyGamepadIndex(aPromiseId, index); + if (!mShuttingdown) { + Unused << SendReplyGamepadIndex(aPromiseId, index); + } } void GamepadTestChannelParent::OnMonitoringStateChanged(bool aNewState) { @@ -125,5 +123,11 @@ mozilla::ipc::IPCResult GamepadTestChannelParent::RecvGamepadTestEvent( return IPC_FAIL_NO_REASON(this); } +mozilla::ipc::IPCResult GamepadTestChannelParent::RecvShutdownChannel() { + mShuttingdown = true; + Unused << Send__delete__(this); + return IPC_OK(); +} + } // namespace dom } // namespace mozilla diff --git a/dom/gamepad/ipc/GamepadTestChannelParent.h b/dom/gamepad/ipc/GamepadTestChannelParent.h index a89077ffc7fc..95648ce78a56 100644 --- a/dom/gamepad/ipc/GamepadTestChannelParent.h +++ b/dom/gamepad/ipc/GamepadTestChannelParent.h @@ -17,31 +17,24 @@ class GamepadTestChannelParent final : public PGamepadTestChannelParent, public SupportsWeakPtr { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GamepadTestChannelParent) - - static already_AddRefed Create(); - + GamepadTestChannelParent() : mShuttingdown(false) {} + bool Init(); + void ActorDestroy(ActorDestroyReason aWhy) override; mozilla::ipc::IPCResult RecvGamepadTestEvent( const uint32_t& aID, const GamepadChangeEvent& aGamepadEvent); + mozilla::ipc::IPCResult RecvShutdownChannel(); void OnMonitoringStateChanged(bool aNewState); - GamepadTestChannelParent(const GamepadTestChannelParent&) = delete; - GamepadTestChannelParent(GamepadTestChannelParent&&) = delete; - GamepadTestChannelParent& operator=(const GamepadTestChannelParent&) = delete; - GamepadTestChannelParent& operator=(GamepadTestChannelParent&&) = delete; - private: struct DeferredGamepadAdded { uint32_t promiseId; GamepadAdded gamepadAdded; }; - - GamepadTestChannelParent(); - ~GamepadTestChannelParent(); - void AddGamepadToPlatformService(uint32_t aPromiseId, const GamepadAdded& aGamepadAdded); - + ~GamepadTestChannelParent() = default; + bool mShuttingdown; nsTArray mDeferredGamepadAdded; }; diff --git a/dom/gamepad/ipc/PGamepadTestChannel.ipdl b/dom/gamepad/ipc/PGamepadTestChannel.ipdl index 7cbe3f41d5a1..57b694acc369 100644 --- a/dom/gamepad/ipc/PGamepadTestChannel.ipdl +++ b/dom/gamepad/ipc/PGamepadTestChannel.ipdl @@ -7,12 +7,13 @@ include GamepadEventTypes; namespace mozilla { namespace dom { -refcounted protocol PGamepadTestChannel { +async protocol PGamepadTestChannel { manager PBackground; parent: async GamepadTestEvent(uint32_t aID, GamepadChangeEvent aGamepadEvent); - async __delete__(); + async ShutdownChannel(); child: + async __delete__(); async ReplyGamepadIndex(uint32_t aID, uint32_t aIndex); }; diff --git a/ipc/glue/BackgroundChildImpl.cpp b/ipc/glue/BackgroundChildImpl.cpp index 307b134be98c..63501b784926 100644 --- a/ipc/glue/BackgroundChildImpl.cpp +++ b/ipc/glue/BackgroundChildImpl.cpp @@ -619,6 +619,19 @@ bool BackgroundChildImpl::DeallocPGamepadEventChannelChild( return true; } +dom::PGamepadTestChannelChild* +BackgroundChildImpl::AllocPGamepadTestChannelChild() { + MOZ_CRASH("PGamepadTestChannelChild actor should be manually constructed!"); + return nullptr; +} + +bool BackgroundChildImpl::DeallocPGamepadTestChannelChild( + PGamepadTestChannelChild* aActor) { + MOZ_ASSERT(aActor); + delete static_cast(aActor); + return true; +} + mozilla::dom::PClientManagerChild* BackgroundChildImpl::AllocPClientManagerChild() { return mozilla::dom::AllocClientManagerChild(); diff --git a/ipc/glue/BackgroundChildImpl.h b/ipc/glue/BackgroundChildImpl.h index e0c85637efe5..d7234cd6d7f5 100644 --- a/ipc/glue/BackgroundChildImpl.h +++ b/ipc/glue/BackgroundChildImpl.h @@ -229,6 +229,11 @@ class BackgroundChildImpl : public PBackgroundChild, virtual bool DeallocPGamepadEventChannelChild( PGamepadEventChannelChild* aActor) override; + virtual PGamepadTestChannelChild* AllocPGamepadTestChannelChild() override; + + virtual bool DeallocPGamepadTestChannelChild( + PGamepadTestChannelChild* aActor) override; + virtual PClientManagerChild* AllocPClientManagerChild() override; virtual bool DeallocPClientManagerChild(PClientManagerChild* aActor) override; diff --git a/ipc/glue/BackgroundParentImpl.cpp b/ipc/glue/BackgroundParentImpl.cpp index 8aa3e0fa2f04..7b2d7d6a338c 100644 --- a/ipc/glue/BackgroundParentImpl.cpp +++ b/ipc/glue/BackgroundParentImpl.cpp @@ -1120,9 +1120,30 @@ BackgroundParentImpl::RecvPGamepadEventChannelConstructor( return IPC_OK(); } -already_AddRefed +dom::PGamepadTestChannelParent* BackgroundParentImpl::AllocPGamepadTestChannelParent() { - return dom::GamepadTestChannelParent::Create(); + RefPtr parent = + new dom::GamepadTestChannelParent(); + + return parent.forget().take(); +} + +mozilla::ipc::IPCResult +BackgroundParentImpl::RecvPGamepadTestChannelConstructor( + PGamepadTestChannelParent* aActor) { + MOZ_ASSERT(aActor); + if (!static_cast(aActor)->Init()) { + return IPC_FAIL_NO_REASON(this); + } + return IPC_OK(); +} + +bool BackgroundParentImpl::DeallocPGamepadTestChannelParent( + dom::PGamepadTestChannelParent* aActor) { + MOZ_ASSERT(aActor); + RefPtr parent = + dont_AddRef(static_cast(aActor)); + return true; } dom::PWebAuthnTransactionParent* diff --git a/ipc/glue/BackgroundParentImpl.h b/ipc/glue/BackgroundParentImpl.h index 134da3a70ca6..7f0a344bed50 100644 --- a/ipc/glue/BackgroundParentImpl.h +++ b/ipc/glue/BackgroundParentImpl.h @@ -332,8 +332,13 @@ class BackgroundParentImpl : public PBackgroundParent, virtual mozilla::ipc::IPCResult RecvPGamepadEventChannelConstructor( PGamepadEventChannelParent* aActor) override; - virtual already_AddRefed - AllocPGamepadTestChannelParent() override; + virtual PGamepadTestChannelParent* AllocPGamepadTestChannelParent() override; + + virtual mozilla::ipc::IPCResult RecvPGamepadTestChannelConstructor( + PGamepadTestChannelParent* aActor) override; + + virtual bool DeallocPGamepadTestChannelParent( + PGamepadTestChannelParent* aActor) override; virtual PWebAuthnTransactionParent* AllocPWebAuthnTransactionParent() override;