GamepadPlatformService.h (6147B)
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_GamepadPlatformService_h_ 8 #define mozilla_dom_GamepadPlatformService_h_ 9 10 #include <map> 11 12 #include "mozilla/Mutex.h" 13 #include "mozilla/StaticPtr.h" 14 #include "mozilla/Vector.h" 15 #include "mozilla/WeakPtr.h" 16 #include "mozilla/dom/GamepadBinding.h" 17 #include "mozilla/dom/GamepadEventTypes.h" 18 #include "mozilla/dom/GamepadHandle.h" 19 20 namespace mozilla::dom { 21 22 class GamepadEventChannelParent; 23 enum class GamepadLightIndicatorType : uint8_t; 24 struct GamepadPoseState; 25 class GamepadTestChannelParent; 26 struct GamepadTouchState; 27 class GamepadPlatformService; 28 29 class GamepadMonitoringState { 30 public: 31 static GamepadMonitoringState& GetSingleton(); 32 33 void AddObserver(GamepadTestChannelParent* aParent); 34 void RemoveObserver(GamepadTestChannelParent* aParent); 35 36 bool IsMonitoring() const; 37 38 GamepadMonitoringState(const GamepadMonitoringState&) = delete; 39 GamepadMonitoringState(GamepadMonitoringState&&) = delete; 40 GamepadMonitoringState& operator=(const GamepadMonitoringState) = delete; 41 GamepadMonitoringState& operator=(GamepadMonitoringState&&) = delete; 42 43 private: 44 GamepadMonitoringState() = default; 45 ~GamepadMonitoringState() = default; 46 47 void Set(bool aIsMonitoring); 48 49 bool mIsMonitoring{false}; 50 Vector<WeakPtr<GamepadTestChannelParent>> mObservers; 51 52 friend class mozilla::dom::GamepadPlatformService; 53 }; 54 55 // Platform Service for building and transmitting IPDL messages 56 // through the HAL sandbox. Used by platform specific 57 // Gamepad implementations 58 // 59 // This class can be accessed by the following 2 threads : 60 // 1. Background thread: 61 // This thread takes charge of IPDL communications 62 // between here and DOM side 63 // 64 // 2. Monitor Thread: 65 // This thread is populated in platform-dependent backends, which 66 // is in charge of processing gamepad hardware events from OS 67 class GamepadPlatformService final { 68 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GamepadPlatformService) 69 public: 70 // Get the singleton service 71 static already_AddRefed<GamepadPlatformService> GetParentService(); 72 73 // Add a gamepad to the list of known gamepads, and return its handle. 74 GamepadHandle AddGamepad(const char* aID, GamepadMappingType aMapping, 75 GamepadHand aHand, uint32_t aNumButtons, 76 uint32_t aNumAxes, uint32_t aNumHaptics, 77 uint32_t aNumLightIndicator, 78 uint32_t aNumTouchEvents); 79 // Remove the gamepad at |aHandle| from the list of known gamepads. 80 void RemoveGamepad(GamepadHandle aHandle); 81 82 // Update the state of |aButton| for the gamepad at |aHandle| for all 83 // windows that are listening and visible, and fire one of 84 // a gamepadbutton{up,down} event at them as well. 85 // aPressed is used for digital buttons, aTouched is for detecting touched 86 // events, aValue is for analog buttons. 87 void NewButtonEvent(GamepadHandle aHandle, uint32_t aButton, bool aPressed, 88 bool aTouched, double aValue); 89 // When only a digital button is available the value will be synthesized. 90 void NewButtonEvent(GamepadHandle aHandle, uint32_t aButton, bool aPressed); 91 // When only a digital button are available the value will be synthesized. 92 void NewButtonEvent(GamepadHandle aHandle, uint32_t aButton, bool aPressed, 93 bool aTouched); 94 // When only a digital button are available the value will be synthesized. 95 void NewButtonEvent(GamepadHandle aHandle, uint32_t aButton, bool aPressed, 96 double aValue); 97 // Update the state of |aAxis| for the gamepad at |aHandle| for all 98 // windows that are listening and visible, and fire a gamepadaxismove 99 // event at them as well. 100 void NewAxisMoveEvent(GamepadHandle aHandle, uint32_t aAxis, double aValue); 101 // Update the state of |aState| for the gamepad at |aHandle| for all 102 // windows that are listening and visible. 103 void NewPoseEvent(GamepadHandle aHandle, const GamepadPoseState& aState); 104 // Update the type of |aType| for the gamepad at |aHandle| for all 105 // windows that are listening and visible. 106 void NewLightIndicatorTypeEvent(GamepadHandle aHandle, uint32_t aLight, 107 GamepadLightIndicatorType aType); 108 // Update the state of |aState| for the gamepad at |aHandle| with 109 // |aTouchArrayIndex| for all windows that are listening and visible. 110 void NewMultiTouchEvent(GamepadHandle aHandle, uint32_t aTouchArrayIndex, 111 const GamepadTouchState& aState); 112 113 // When shutting down the platform communications for gamepad, also reset the 114 // indexes. 115 void ResetGamepadIndexes(); 116 117 // Add IPDL parent instance 118 void AddChannelParent(GamepadEventChannelParent* aParent); 119 120 // Remove IPDL parent instance 121 void RemoveChannelParent(GamepadEventChannelParent* aParent); 122 123 void MaybeShutdown(); 124 125 nsTArray<GamepadAdded> GetAllGamePads() { 126 nsTArray<GamepadAdded> gamepads; 127 128 for (const auto& elem : mGamepadAdded) { 129 gamepads.AppendElement(elem.second); 130 } 131 return gamepads; 132 } 133 134 private: 135 GamepadPlatformService(); 136 ~GamepadPlatformService(); 137 template <class T> 138 void NotifyGamepadChange(GamepadHandle aHandle, const T& aInfo); 139 140 void Cleanup(); 141 142 // mNextGamepadHandleValue can only be accessed by monitor thread 143 uint32_t mNextGamepadHandleValue; 144 145 // mChannelParents stores all the GamepadEventChannelParent instances 146 // which may be accessed by both background thread and monitor thread 147 // simultaneously, so we have a mutex to prevent race condition 148 nsTArray<RefPtr<GamepadEventChannelParent>> mChannelParents; 149 150 // This mutex protects mChannelParents from race condition 151 // between background and monitor thread 152 Mutex mMutex MOZ_UNANNOTATED; 153 154 std::map<GamepadHandle, GamepadAdded> mGamepadAdded; 155 }; 156 157 } // namespace mozilla::dom 158 159 #endif