summaryrefslogtreecommitdiffstats
path: root/xbmc/peripherals/bus/PeripheralBus.h
blob: c23abff7b7b306d7a450fdd854c05e5a245a56ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
 *  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 <memory>
#include <mutex>
#include <vector>

class CFileItemList;

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<CCriticalSection> lock(m_critSection);
    return m_bNeedsPolling;
  }

  /*!
   * \brief Initialize the properties of a peripheral with a known location
   */
  virtual bool InitializeProperties(CPeripheral& peripheral);

  /*!
   * @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<PeripheralFeature>& 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<CPeripheralBus>;
using PeripheralBusVector = std::vector<PeripheralBusPtr>;
} // namespace PERIPHERALS