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