1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "IEventScannerCallback.h" 12 #include "bus/PeripheralBus.h" 13 #include "devices/Peripheral.h" 14 #include "interfaces/IAnnouncer.h" 15 #include "messaging/IMessageTarget.h" 16 #include "settings/lib/ISettingCallback.h" 17 #include "threads/CriticalSection.h" 18 #include "threads/Thread.h" 19 #include "utils/Observer.h" 20 21 #include <memory> 22 #include <vector> 23 24 class CFileItemList; 25 class CInputManager; 26 class CSetting; 27 class CSettingsCategory; 28 class TiXmlElement; 29 class CAction; 30 class CKey; 31 32 namespace KODI 33 { 34 namespace GAME 35 { 36 class CControllerManager; 37 } 38 39 namespace JOYSTICK 40 { 41 class IButtonMapper; 42 } 43 } // namespace KODI 44 45 namespace PERIPHERALS 46 { 47 class CEventScanner; 48 49 class CPeripherals : public ISettingCallback, 50 public Observable, 51 public KODI::MESSAGING::IMessageTarget, 52 public IEventScannerCallback, 53 public ANNOUNCEMENT::IAnnouncer 54 { 55 public: 56 explicit CPeripherals(CInputManager& inputManager, 57 KODI::GAME::CControllerManager& controllerProfiles); 58 59 ~CPeripherals() override; 60 61 /*! 62 * @brief Initialise the peripherals manager. 63 */ 64 void Initialise(); 65 66 /*! 67 * @brief Clear all data known by the peripherals manager. 68 */ 69 void Clear(); 70 71 /*! 72 * @brief Get the instance of the peripheral at the given location. 73 * @param strLocation The location. 74 * @param busType The bus to query. Default (PERIPHERAL_BUS_UNKNOWN) searches all busses. 75 * @return The peripheral or NULL if it wasn't found. 76 */ 77 PeripheralPtr GetPeripheralAtLocation(const std::string& strLocation, 78 PeripheralBusType busType = PERIPHERAL_BUS_UNKNOWN) const; 79 80 /*! 81 * @brief Check whether a peripheral is present at the given location. 82 * @param strLocation The location. 83 * @param busType The bus to query. Default (PERIPHERAL_BUS_UNKNOWN) searches all busses. 84 * @return True when a peripheral was found, false otherwise. 85 */ 86 bool HasPeripheralAtLocation(const std::string& strLocation, 87 PeripheralBusType busType = PERIPHERAL_BUS_UNKNOWN) const; 88 89 /*! 90 * @brief Get the bus that holds the device with the given location. 91 * @param strLocation The location. 92 * @return The bus or NULL if no device was found. 93 */ 94 PeripheralBusPtr GetBusWithDevice(const std::string& strLocation) const; 95 96 /*! 97 * @brief Check if any busses support the given feature 98 * @param feature The feature to check for 99 * @return True if a bus supports the feature, false otherwise 100 */ 101 bool SupportsFeature(PeripheralFeature feature) const; 102 103 /*! 104 * @brief Get all peripheral instances that have the given feature. 105 * @param results The list of results. 106 * @param feature The feature to search for. 107 * @param busType The bus to query. Default (PERIPHERAL_BUS_UNKNOWN) searches all busses. 108 * @return The number of devices that have been found. 109 */ 110 int GetPeripheralsWithFeature(PeripheralVector& results, 111 const PeripheralFeature feature, 112 PeripheralBusType busType = PERIPHERAL_BUS_UNKNOWN) const; 113 114 size_t GetNumberOfPeripherals() const; 115 116 /*! 117 * @brief Check whether there is at least one device present with the given feature. 118 * @param feature The feature to check for. 119 * @param busType The bus to query. Default (PERIPHERAL_BUS_UNKNOWN) searches all busses. 120 * @return True when at least one device was found with this feature, false otherwise. 121 */ 122 bool HasPeripheralWithFeature(const PeripheralFeature feature, 123 PeripheralBusType busType = PERIPHERAL_BUS_UNKNOWN) const; 124 125 /*! 126 * @brief Called when a device has been added to a bus. 127 * @param bus The bus the device was added to. 128 * @param peripheral The peripheral that has been added. 129 */ 130 void OnDeviceAdded(const CPeripheralBus& bus, const CPeripheral& peripheral); 131 132 /*! 133 * @brief Called when a device has been deleted from a bus. 134 * @param bus The bus from which the device removed. 135 * @param peripheral The peripheral that has been removed. 136 */ 137 void OnDeviceDeleted(const CPeripheralBus& bus, const CPeripheral& peripheral); 138 139 /*! 140 * @brief Creates a new instance of a peripheral. 141 * @param bus The bus on which this peripheral is present. 142 * @param result The scan result from the device scanning code. 143 * @return The new peripheral or NULL if it could not be created. 144 */ 145 void CreatePeripheral(CPeripheralBus& bus, const PeripheralScanResult& result); 146 147 /*! 148 * @brief Add the settings that are defined in the mappings file to the peripheral (if there is 149 * anything defined). 150 * @param peripheral The peripheral to get the settings for. 151 */ 152 void GetSettingsFromMapping(CPeripheral& peripheral) const; 153 154 /*! 155 * @brief Trigger a device scan on all known busses 156 */ 157 void TriggerDeviceScan(const PeripheralBusType type = PERIPHERAL_BUS_UNKNOWN); 158 159 /*! 160 * @brief Get the instance of a bus given it's type. 161 * @param type The bus type. 162 * @return The bus or NULL if it wasn't found. 163 */ 164 PeripheralBusPtr GetBusByType(const PeripheralBusType type) const; 165 166 /*! 167 * @brief Get all fileitems for a path. 168 * @param strPath The path to the directory to get the items from. 169 * @param items The item list. 170 */ 171 void GetDirectory(const std::string& strPath, CFileItemList& items) const; 172 173 /*! 174 * @brief Get the instance of a peripheral given it's path. 175 * @param strPath The path to the peripheral. 176 * @return The peripheral or NULL if it wasn't found. 177 */ 178 PeripheralPtr GetByPath(const std::string& strPath) const; 179 180 /*! 181 * @brief Try to let one of the peripherals handle an action. 182 * @param action The change to handle. 183 * @return True when this change was handled by a peripheral (and should not be handled by 184 * anything else), false otherwise. 185 */ 186 bool OnAction(const CAction& action); 187 188 /*! 189 * @brief Check whether there's a peripheral that reports to be muted. 190 * @return True when at least one peripheral reports to be muted, false otherwise. 191 */ 192 bool IsMuted(); 193 194 /*! 195 * @brief Try to toggle the mute status via a peripheral. 196 * @return True when this change was handled by a peripheral (and should not be handled by 197 * anything else), false otherwise. 198 */ 199 bool ToggleMute(); 200 201 /*! 202 * @brief Try to toggle the playing device state via a peripheral. 203 * @param mode Whether to activate, put on standby or toggle the source. 204 * @return True when the playing device has been switched on, false otherwise. 205 */ 206 bool ToggleDeviceState(const CecStateChange mode = STATE_SWITCH_TOGGLE); 207 208 /*! 209 * @brief Try to mute the audio via a peripheral. 210 * @return True when this change was handled by a peripheral (and should not be handled by 211 * anything else), false otherwise. 212 */ Mute()213 bool Mute() 214 { 215 return ToggleMute(); 216 } //! @todo CEC only supports toggling the mute status at this time 217 218 /*! 219 * @brief Try to unmute the audio via a peripheral. 220 * @return True when this change was handled by a peripheral (and should not be handled by 221 * anything else), false otherwise. 222 */ UnMute()223 bool UnMute() 224 { 225 return ToggleMute(); 226 } //! @todo CEC only supports toggling the mute status at this time 227 228 /*! 229 * @brief Try to get a keypress from a peripheral. 230 * @param frameTime The current frametime. 231 * @param key The fetched key. 232 * @return True when a keypress was fetched, false otherwise. 233 */ 234 bool GetNextKeypress(float frameTime, CKey& key); 235 236 /*! 237 * @brief Register with the event scanner to control scan timing 238 * @return A handle that unregisters itself when expired 239 */ 240 EventPollHandlePtr RegisterEventPoller(); 241 242 /*! 243 * @brief Register with the event scanner to disable event processing 244 * @return A handle that unregisters itself when expired 245 */ 246 EventLockHandlePtr RegisterEventLock(); 247 248 /*! 249 * 250 */ 251 void OnUserNotification(); 252 253 /*! 254 * @brief Request peripherals with the specified feature to perform a quick test 255 * @return true if any peripherals support the feature, false otherwise 256 */ 257 void TestFeature(PeripheralFeature feature); 258 259 /*! 260 * \brief Request all devices with power-off support to power down 261 */ 262 void PowerOffDevices(); 263 SupportsCEC()264 bool SupportsCEC() const 265 { 266 #if defined(HAVE_LIBCEC) 267 return true; 268 #else 269 return false; 270 #endif 271 } 272 273 // implementation of IEventScannerCallback 274 void ProcessEvents(void) override; 275 276 /*! 277 * \brief Initialize button mapping 278 * 279 * This command enables button mapping on all busses. Button maps allow 280 * connect events from the driver to the higher-level features used by 281 * controller profiles. 282 * 283 * If user input is required, a blocking dialog may be shown. 284 */ 285 void EnableButtonMapping(); 286 287 /*! 288 * \brief Get an add-on that can provide button maps for a device 289 * \return An add-on that provides button maps, or empty if no add-on is found 290 */ 291 PeripheralAddonPtr GetAddonWithButtonMap(const CPeripheral* device); 292 293 /*! 294 * \brief Reset all button maps to the defaults for all devices and the given controller 295 * \param controllerId The controller profile to reset 296 * @todo Add a device parameter to allow resetting button maps per-device 297 */ 298 void ResetButtonMaps(const std::string& controllerId); 299 300 /*! 301 * \brief Register a button mapper interface 302 * \param mapper The button mapper 303 * 304 * Clients implementing the IButtonMapper interface call 305 * \ref CPeripherals::RegisterJoystickButtonMapper to register themselves 306 * as eligible for button mapping commands. 307 * 308 * When registering the mapper is forwarded to all peripherals. See 309 * \ref CPeripheral::RegisterJoystickButtonMapper for what is done to the 310 * mapper after being given to the peripheral. 311 */ 312 void RegisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper); 313 314 /*! 315 * \brief Unregister a button mapper interface 316 * \param mapper The button mapper 317 */ 318 void UnregisterJoystickButtonMapper(KODI::JOYSTICK::IButtonMapper* mapper); 319 320 // implementation of ISettingCallback 321 void OnSettingChanged(const std::shared_ptr<const CSetting>& setting) override; 322 void OnSettingAction(const std::shared_ptr<const CSetting>& setting) override; 323 324 // implementation of IMessageTarget 325 void OnApplicationMessage(KODI::MESSAGING::ThreadMessage* pMsg) override; 326 int GetMessageMask() override; 327 328 // implementation of IAnnouncer 329 void Announce(ANNOUNCEMENT::AnnouncementFlag flag, 330 const std::string& sender, 331 const std::string& message, 332 const CVariant& data) override; 333 334 /*! 335 * \brief Access the input manager passed to the constructor 336 */ GetInputManager()337 CInputManager& GetInputManager() { return m_inputManager; } 338 339 /*! 340 * \brief Access controller profiles through the construction parameter 341 */ GetControllerProfiles()342 KODI::GAME::CControllerManager& GetControllerProfiles() { return m_controllerProfiles; } 343 344 private: 345 bool LoadMappings(); 346 bool GetMappingForDevice(const CPeripheralBus& bus, PeripheralScanResult& result) const; 347 static void GetSettingsFromMappingsFile( 348 TiXmlElement* xmlNode, std::map<std::string, PeripheralDeviceSetting>& m_settings); 349 350 void OnDeviceChanged(); 351 352 // Construction parameters 353 CInputManager& m_inputManager; 354 KODI::GAME::CControllerManager& m_controllerProfiles; 355 356 #if !defined(HAVE_LIBCEC) 357 bool m_bMissingLibCecWarningDisplayed = false; 358 #endif 359 std::vector<PeripheralBusPtr> m_busses; 360 std::vector<PeripheralDeviceMapping> m_mappings; 361 std::unique_ptr<CEventScanner> m_eventScanner; 362 mutable CCriticalSection m_critSectionBusses; 363 mutable CCriticalSection m_critSectionMappings; 364 }; 365 } // namespace PERIPHERALS 366