1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "GamepadEventChannelParent.h"
7 #include "GamepadPlatformService.h"
8 #include "mozilla/dom/GamepadMonitoring.h"
9 #include "mozilla/ipc/BackgroundParent.h"
10 #include "nsThreadUtils.h"
11 
12 namespace mozilla::dom {
13 
14 using namespace mozilla::ipc;
15 
16 namespace {
17 
18 class SendGamepadUpdateRunnable final : public Runnable {
19  private:
20   ~SendGamepadUpdateRunnable() = default;
21   RefPtr<GamepadEventChannelParent> mParent;
22   GamepadChangeEvent mEvent;
23 
24  public:
SendGamepadUpdateRunnable(GamepadEventChannelParent * aParent,GamepadChangeEvent aEvent)25   SendGamepadUpdateRunnable(GamepadEventChannelParent* aParent,
26                             GamepadChangeEvent aEvent)
27       : Runnable("dom::SendGamepadUpdateRunnable"),
28         mParent(aParent),
29         mEvent(aEvent) {
30     MOZ_ASSERT(mParent);
31   }
Run()32   NS_IMETHOD Run() override {
33     AssertIsOnBackgroundThread();
34     Unused << mParent->SendGamepadUpdate(mEvent);
35     return NS_OK;
36   }
37 };
38 
39 }  // namespace
40 
41 already_AddRefed<GamepadEventChannelParent>
Create()42 GamepadEventChannelParent::Create() {
43   return RefPtr<GamepadEventChannelParent>(new GamepadEventChannelParent())
44       .forget();
45 }
46 
GamepadEventChannelParent()47 GamepadEventChannelParent::GamepadEventChannelParent() : mIsShutdown{false} {
48   MOZ_DIAGNOSTIC_ASSERT(IsOnBackgroundThread());
49 
50   mBackgroundEventTarget = GetCurrentEventTarget();
51 
52   RefPtr<GamepadPlatformService> service =
53       GamepadPlatformService::GetParentService();
54   MOZ_ASSERT(service);
55 
56   service->AddChannelParent(this);
57 }
58 
ActorDestroy(ActorDestroyReason aWhy)59 void GamepadEventChannelParent::ActorDestroy(ActorDestroyReason aWhy) {
60   MOZ_DIAGNOSTIC_ASSERT(IsOnBackgroundThread());
61   MOZ_DIAGNOSTIC_ASSERT(!mIsShutdown);
62 
63   mIsShutdown = true;
64 
65   RefPtr<GamepadPlatformService> service =
66       GamepadPlatformService::GetParentService();
67   MOZ_ASSERT(service);
68   service->RemoveChannelParent(this);
69 }
70 
RecvVibrateHaptic(const Tainted<GamepadHandle> & aHandle,const Tainted<uint32_t> & aHapticIndex,const Tainted<double> & aIntensity,const Tainted<double> & aDuration,const uint32_t & aPromiseID)71 mozilla::ipc::IPCResult GamepadEventChannelParent::RecvVibrateHaptic(
72     const Tainted<GamepadHandle>& aHandle,
73     const Tainted<uint32_t>& aHapticIndex, const Tainted<double>& aIntensity,
74     const Tainted<double>& aDuration, const uint32_t& aPromiseID) {
75   // TODO: Bug 680289, implement for standard gamepads
76 
77   if (SendReplyGamepadPromise(aPromiseID)) {
78     return IPC_OK();
79   }
80 
81   return IPC_FAIL(this, "SendReplyGamepadPromise fail.");
82 }
83 
RecvStopVibrateHaptic(const Tainted<GamepadHandle> & aHandle)84 mozilla::ipc::IPCResult GamepadEventChannelParent::RecvStopVibrateHaptic(
85     const Tainted<GamepadHandle>& aHandle) {
86   // TODO: Bug 680289, implement for standard gamepads
87   return IPC_OK();
88 }
89 
RecvLightIndicatorColor(const Tainted<GamepadHandle> & aHandle,const Tainted<uint32_t> & aLightColorIndex,const uint8_t & aRed,const uint8_t & aGreen,const uint8_t & aBlue,const uint32_t & aPromiseID)90 mozilla::ipc::IPCResult GamepadEventChannelParent::RecvLightIndicatorColor(
91     const Tainted<GamepadHandle>& aHandle,
92     const Tainted<uint32_t>& aLightColorIndex, const uint8_t& aRed,
93     const uint8_t& aGreen, const uint8_t& aBlue, const uint32_t& aPromiseID) {
94   SetGamepadLightIndicatorColor(aHandle, aLightColorIndex, aRed, aGreen, aBlue);
95 
96   if (SendReplyGamepadPromise(aPromiseID)) {
97     return IPC_OK();
98   }
99 
100   return IPC_FAIL(this, "SendReplyGamepadPromise fail.");
101 }
102 
DispatchUpdateEvent(const GamepadChangeEvent & aEvent)103 void GamepadEventChannelParent::DispatchUpdateEvent(
104     const GamepadChangeEvent& aEvent) {
105   mBackgroundEventTarget->Dispatch(new SendGamepadUpdateRunnable(this, aEvent),
106                                    NS_DISPATCH_NORMAL);
107 }
108 
109 }  // namespace mozilla::dom
110