/* * Copyright (C) 2005-2018 Team Kodi * This file is part of Kodi - https://kodi.tv * * SPDX-License-Identifier: GPL-2.0-or-later * See LICENSES/README.md for more information. */ #pragma once #include "peripherals/PeripheralTypes.h" #include "threads/Thread.h" #include #include #include class CFileItemList; namespace KODI { namespace JOYSTICK { class IButtonMap; } // namespace JOYSTICK } // namespace KODI namespace PERIPHERALS { class CPeripheral; class CPeripherals; /*! * @class CPeripheralBus * This represents a bus on the system. By default, this bus instance will scan for changes every 5 * seconds. If this bus only has to be updated after a notification sent by the system, set * m_bNeedsPolling to false in the constructor, and implement the OnDeviceAdded(), OnDeviceChanged() * and OnDeviceRemoved() methods. * * The PerformDeviceScan() method has to be implemented by each specific bus implementation. */ class CPeripheralBus : protected CThread { public: CPeripheralBus(const std::string& threadname, CPeripherals& manager, PeripheralBusType type); ~CPeripheralBus(void) override { Clear(); } /*! * @return The bus type */ PeripheralBusType Type(void) const { return m_type; } /*! * @return True if this bus needs to be polled for changes, false if this bus performs updates via * callbacks */ bool NeedsPolling(void) const { std::unique_lock lock(m_critSection); return m_bNeedsPolling; } /*! * \brief Initialize the properties of a peripheral with a known location */ virtual bool InitializeProperties(CPeripheral& peripheral); /*! * \brief Initialize a joystick buttonmap, if possible */ virtual bool InitializeButtonMap(const CPeripheral& peripheral, KODI::JOYSTICK::IButtonMap& buttonMap) const { return false; } /*! * @brief Get the instance of the peripheral at the given location. * @param strLocation The location. * @return The peripheral or NULL if it wasn't found. */ virtual PeripheralPtr GetPeripheral(const std::string& strLocation) const; /*! * @brief Check whether a peripheral is present at the given location. * @param strLocation The location. * @return True when a peripheral was found, false otherwise. */ virtual bool HasPeripheral(const std::string& strLocation) const; /*! * @brief Check if the bus supports the given feature * @param feature The feature to check for * @return True if the bus supports the feature, false otherwise */ virtual bool SupportsFeature(PeripheralFeature feature) const { return false; } /*! * @brief Get all peripheral instances that have the given feature. * @param results The list of results. * @param feature The feature to search for. * @return The number of devices that have been found. */ virtual unsigned int GetPeripheralsWithFeature(PeripheralVector& results, const PeripheralFeature feature) const; virtual unsigned int GetNumberOfPeripherals() const; virtual unsigned int GetNumberOfPeripheralsWithId(const int iVendorId, const int iProductId) const; /*! * @brief Get all features that are supported by devices on this bus. * @param features All features. */ virtual void GetFeatures(std::vector& features) const; /*! * @brief Check whether there is at least one device present with the given feature. * @param feature The feature to check for. * @return True when at least one device was found with this feature, false otherwise. */ virtual bool HasFeature(const PeripheralFeature feature) const; /*! * @brief Callback method for when a device has been added. Will perform a device scan. * @param strLocation The location of the device that has been added. */ virtual void OnDeviceAdded(const std::string& strLocation); /*! * @brief Callback method for when a device has been changed. Will perform a device scan. * @param strLocation The location of the device that has been changed. */ virtual void OnDeviceChanged(const std::string& strLocation); /*! * @brief Callback method for when a device has been removed. Will perform a device scan. * @param strLocation The location of the device that has been removed. */ virtual void OnDeviceRemoved(const std::string& strLocation); /*! * @brief Initialise this bus and start a polling thread if this bus needs polling. */ virtual void Initialise(void); /*! * @brief Stop the polling thread and clear all known devices on this bus. */ virtual void Clear(void); /*! * @brief Scan for devices. */ virtual void TriggerDeviceScan(void); /*! * @brief Get all fileitems for a path. * @param strPath The path to the directory to get the items from. * @param items The item list. */ virtual void GetDirectory(const std::string& strPath, CFileItemList& items) const; /*! * @brief Get the instance of a peripheral given it's path. * @param strPath The path to the peripheral. * @return The peripheral or NULL if it wasn't found. */ virtual PeripheralPtr GetByPath(const std::string& strPath) const; /*! * @brief Register a new peripheral on this bus. * @param peripheral The peripheral to register. */ virtual void Register(const PeripheralPtr& peripheral); virtual bool FindComPort(std::string& strLocation) { return false; } /*! * \brief Poll for events */ virtual void ProcessEvents(void) {} /*! * \brief Initialize button mapping * \return True if button mapping is enabled for this bus */ virtual void EnableButtonMapping() {} /*! * \brief Power off the specified device * \param strLocation The device's location */ virtual void PowerOff(const std::string& strLocation) {} protected: void Process(void) override; virtual bool ScanForDevices(void); virtual void UnregisterRemovedDevices(const PeripheralScanResults& results); virtual void RegisterNewDevices(const PeripheralScanResults& results); /*! * @brief Scan for devices on this bus and add them to the results list. This will have to be * implemented for each bus. * @param results The result list. * @return True when the scan was successful, false otherwise. */ virtual bool PerformDeviceScan(PeripheralScanResults& results) = 0; PeripheralVector m_peripherals; std::chrono::milliseconds m_iRescanTime; bool m_bNeedsPolling; /*!< true when this bus needs to be polled for new devices, false when it uses callbacks to notify this bus of changed */ CPeripherals& m_manager; const PeripheralBusType m_type; mutable CCriticalSection m_critSection; CEvent m_triggerEvent; }; using PeripheralBusPtr = std::shared_ptr; using PeripheralBusVector = std::vector; } // namespace PERIPHERALS