Line data Source code
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 :
7 : #ifndef mozilla_dom_GamepadManager_h_
8 : #define mozilla_dom_GamepadManager_h_
9 :
10 : #include "nsIIPCBackgroundChildCreateCallback.h"
11 : #include "nsIObserver.h"
12 : // Needed for GamepadMappingType
13 : #include "mozilla/dom/GamepadBinding.h"
14 : #include "mozilla/dom/GamepadServiceType.h"
15 :
16 : class nsGlobalWindow;
17 :
18 : namespace mozilla {
19 : namespace gfx {
20 : class VRManagerChild;
21 : } // namespace gfx
22 : namespace dom {
23 :
24 : class EventTarget;
25 : class Gamepad;
26 : class GamepadChangeEvent;
27 : class GamepadEventChannelChild;
28 :
29 : class GamepadManager final : public nsIObserver,
30 : public nsIIPCBackgroundChildCreateCallback
31 : {
32 : public:
33 : NS_DECL_ISUPPORTS
34 : NS_DECL_NSIOBSERVER
35 : NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
36 :
37 : // Returns true if we actually have a service up and running
38 : static bool IsServiceRunning();
39 : // Get the singleton service
40 : static already_AddRefed<GamepadManager> GetService();
41 : // Return true if the API is preffed on.
42 : static bool IsAPIEnabled();
43 :
44 : void BeginShutdown();
45 : void StopMonitoring();
46 :
47 : // Indicate that |aWindow| wants to receive gamepad events.
48 : void AddListener(nsGlobalWindow* aWindow);
49 : // Indicate that |aWindow| should no longer receive gamepad events.
50 : void RemoveListener(nsGlobalWindow* aWindow);
51 :
52 : // Add a gamepad to the list of known gamepads.
53 : void AddGamepad(uint32_t aIndex, const nsAString& aID, GamepadMappingType aMapping,
54 : GamepadHand aHand, GamepadServiceType aServiceType,
55 : uint32_t aNumButtons, uint32_t aNumAxes, uint32_t aNumHaptics);
56 :
57 : // Remove the gamepad at |aIndex| from the list of known gamepads.
58 : void RemoveGamepad(uint32_t aIndex, GamepadServiceType aServiceType);
59 :
60 : // Synchronize the state of |aGamepad| to match the gamepad stored at |aIndex|
61 : void SyncGamepadState(uint32_t aIndex, Gamepad* aGamepad);
62 :
63 : // Returns gamepad object if index exists, null otherwise
64 : already_AddRefed<Gamepad> GetGamepad(uint32_t aIndex) const;
65 :
66 : // Receive GamepadChangeEvent messages from parent process to fire DOM events
67 : void Update(const GamepadChangeEvent& aGamepadEvent);
68 :
69 : // Trigger vibrate haptic event to gamepad channels.
70 : already_AddRefed<Promise> VibrateHaptic(uint32_t aControllerIdx, uint32_t aHapticIndex,
71 : double aIntensity, double aDuration,
72 : nsIGlobalObject* aGlobal, ErrorResult& aRv);
73 : // Send stop haptic events to gamepad channels.
74 : void StopHaptics();
75 :
76 : protected:
77 : GamepadManager();
78 0 : ~GamepadManager() {};
79 :
80 : // Fire a gamepadconnected or gamepaddisconnected event for the gamepad
81 : // at |aIndex| to all windows that are listening and have received
82 : // gamepad input.
83 : void NewConnectionEvent(uint32_t aIndex, bool aConnected);
84 :
85 : // Fire a gamepadaxismove event to the window at |aTarget| for |aGamepad|.
86 : void FireAxisMoveEvent(EventTarget* aTarget,
87 : Gamepad* aGamepad,
88 : uint32_t axis,
89 : double value);
90 :
91 : // Fire one of gamepadbutton{up,down} event at the window at |aTarget| for
92 : // |aGamepad|.
93 : void FireButtonEvent(EventTarget* aTarget,
94 : Gamepad* aGamepad,
95 : uint32_t aButton,
96 : double aValue);
97 :
98 : // Fire one of gamepad{connected,disconnected} event at the window at
99 : // |aTarget| for |aGamepad|.
100 : void FireConnectionEvent(EventTarget* aTarget,
101 : Gamepad* aGamepad,
102 : bool aConnected);
103 :
104 : // true if this feature is enabled in preferences
105 : bool mEnabled;
106 : // true if non-standard events are enabled in preferences
107 : bool mNonstandardEventsEnabled;
108 : // true when shutdown has begun
109 : bool mShuttingDown;
110 :
111 : // Gamepad IPDL child
112 : // This pointer is only used by this singleton instance and
113 : // will be destroyed during the IPDL shutdown chain, so we
114 : // don't need to refcount it here.
115 : nsTArray<GamepadEventChannelChild *> mChannelChildren;
116 :
117 : private:
118 :
119 : nsresult Init();
120 :
121 : void MaybeConvertToNonstandardGamepadEvent(const GamepadChangeEvent& aEvent,
122 : nsGlobalWindow* aWindow);
123 :
124 : bool SetGamepadByEvent(const GamepadChangeEvent& aEvent, nsGlobalWindow* aWindow = nullptr);
125 :
126 : bool MaybeWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex);
127 : // Returns true if we have already sent data from this gamepad
128 : // to this window. This should only return true if the user
129 : // explicitly interacted with a gamepad while this window
130 : // was focused, by pressing buttons or similar actions.
131 : bool WindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex) const;
132 : // Indicate that a window has received data from a gamepad.
133 : void SetWindowHasSeenGamepad(nsGlobalWindow* aWindow, uint32_t aIndex,
134 : bool aHasSeen = true);
135 : // Our gamepad index has VR_GAMEPAD_IDX_OFFSET while GamepadChannelType
136 : // is from VRManager.
137 : uint32_t GetGamepadIndexWithServiceType(uint32_t aIndex, GamepadServiceType aServiceType);
138 :
139 : // Gamepads connected to the system. Copies of these are handed out
140 : // to each window.
141 : nsRefPtrHashtable<nsUint32HashKey, Gamepad> mGamepads;
142 : // Inner windows that are listening for gamepad events.
143 : // has been sent to that window.
144 : nsTArray<RefPtr<nsGlobalWindow>> mListeners;
145 : uint32_t mPromiseID;
146 : };
147 :
148 : } // namespace dom
149 : } // namespace mozilla
150 :
151 : #endif // mozilla_dom_GamepadManager_h_
|