platform_sensor_reader_winrt.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_READER_WINRT_H_
  5. #define SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_READER_WINRT_H_
  6. #include <windows.devices.sensors.h>
  7. #include <windows.foundation.h>
  8. #include <wrl/client.h>
  9. #include <wrl/event.h>
  10. #include <functional>
  11. #include <memory>
  12. #include "base/callback.h"
  13. #include "base/memory/raw_ptr.h"
  14. #include "base/synchronization/lock.h"
  15. #include "base/thread_annotations.h"
  16. #include "base/time/time.h"
  17. #include "services/device/generic_sensor/platform_sensor_reader_win_base.h"
  18. #include "services/device/public/cpp/generic_sensor/sensor_reading.h"
  19. #include "third_party/abseil-cpp/absl/types/optional.h"
  20. #include "ui/gfx/geometry/angle_conversions.h"
  21. namespace device {
  22. namespace mojom {
  23. enum class SensorType;
  24. }
  25. // Helper class used to create PlatformSensorReaderWinrt instances
  26. class PlatformSensorReaderWinrtFactory {
  27. public:
  28. static std::unique_ptr<PlatformSensorReaderWinBase> Create(
  29. mojom::SensorType type);
  30. };
  31. // Base class that contains common helper functions used between all low
  32. // level sensor types based on the Windows.Devices.Sensors API. Derived
  33. // classes will specialize the template into a specific sensor. See
  34. // PlatformSensorReaderWinrtLightSensor as an example of what WinRT
  35. // interfaces should be passed in. The owner of this class must guarantee
  36. // construction and destruction occur on the same thread and that no
  37. // other thread is accessing it during destruction.
  38. // TODO(crbug.com/995594): Change Windows.Devices.Sensors based
  39. // implementation of W3C sensor API to use hardware thresholding.
  40. template <wchar_t const* runtime_class_id,
  41. class ISensorWinrtStatics,
  42. class ISensorWinrtClass,
  43. class ISensorReadingChangedHandler,
  44. class ISensorReadingChangedEventArgs>
  45. class PlatformSensorReaderWinrtBase : public PlatformSensorReaderWinBase {
  46. public:
  47. using GetSensorFactoryFunctor =
  48. base::RepeatingCallback<HRESULT(ISensorWinrtStatics**)>;
  49. // Sets the client to notify changes about. The consumer should always
  50. // ensure the lifetime of the client surpasses the lifetime of this class.
  51. void SetClient(Client* client) override;
  52. // Allows tests to specify their own implementation of the underlying sensor.
  53. // This function should be called before Initialize().
  54. void InitForTesting(GetSensorFactoryFunctor get_sensor_factory_callback) {
  55. get_sensor_factory_callback_ = get_sensor_factory_callback;
  56. }
  57. // Returns true if the underlying WinRT sensor object is valid, meant
  58. // for testing purposes.
  59. bool IsUnderlyingWinrtObjectValidForTesting() { return sensor_; }
  60. [[nodiscard]] bool Initialize();
  61. [[nodiscard]] bool StartSensor(
  62. const PlatformSensorConfiguration& configuration) override;
  63. base::TimeDelta GetMinimalReportingInterval() const override;
  64. void StopSensor() override;
  65. protected:
  66. PlatformSensorReaderWinrtBase();
  67. virtual ~PlatformSensorReaderWinrtBase() { StopSensor(); }
  68. // Derived classes should implement this function to handle sensor specific
  69. // parsing of the sensor reading.
  70. virtual HRESULT OnReadingChangedCallback(
  71. ISensorWinrtClass* sensor,
  72. ISensorReadingChangedEventArgs* reading_changed_args) = 0;
  73. // Helper function which converts the DateTime timestamp format the
  74. // Windows.Devices.Sensors API uses to the second time ticks the
  75. // client expects.
  76. template <class ISensorReading>
  77. HRESULT ConvertSensorReadingTimeStamp(
  78. Microsoft::WRL::ComPtr<ISensorReading> sensor_reading,
  79. base::TimeDelta* timestamp_delta);
  80. // Following class member is protected by lock since SetClient,
  81. // StartSensor, and StopSensor can all be called from different
  82. // threads by PlatformSensorWin.
  83. base::Lock lock_;
  84. // Null if there is no client to notify, non-null otherwise.
  85. raw_ptr<Client> client_ GUARDED_BY(lock_);
  86. // Always report the first sample received after starting the sensor.
  87. bool has_received_first_sample_ = false;
  88. private:
  89. base::TimeDelta GetMinimumReportIntervalFromSensor();
  90. GetSensorFactoryFunctor get_sensor_factory_callback_;
  91. // absl::nullopt if the sensor has not been started, non-empty otherwise.
  92. absl::optional<EventRegistrationToken> reading_callback_token_;
  93. base::TimeDelta minimum_report_interval_;
  94. Microsoft::WRL::ComPtr<ISensorWinrtClass> sensor_;
  95. };
  96. class PlatformSensorReaderWinrtLightSensor final
  97. : public PlatformSensorReaderWinrtBase<
  98. RuntimeClass_Windows_Devices_Sensors_LightSensor,
  99. ABI::Windows::Devices::Sensors::ILightSensorStatics,
  100. ABI::Windows::Devices::Sensors::ILightSensor,
  101. Microsoft::WRL::Implements<
  102. Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
  103. ABI::Windows::Foundation::ITypedEventHandler<
  104. ABI::Windows::Devices::Sensors::LightSensor*,
  105. ABI::Windows::Devices::Sensors::
  106. LightSensorReadingChangedEventArgs*>,
  107. Microsoft::WRL::FtmBase>,
  108. ABI::Windows::Devices::Sensors::ILightSensorReadingChangedEventArgs> {
  109. public:
  110. // Lux scales exponentially with perceived brightness so use a relative
  111. // threshold instead of an absolute one.
  112. static constexpr float kLuxPercentThreshold = 0.2f; // 20%
  113. static std::unique_ptr<PlatformSensorReaderWinBase> Create();
  114. PlatformSensorReaderWinrtLightSensor();
  115. ~PlatformSensorReaderWinrtLightSensor() override = default;
  116. protected:
  117. HRESULT OnReadingChangedCallback(
  118. ABI::Windows::Devices::Sensors::ILightSensor* sensor,
  119. ABI::Windows::Devices::Sensors::ILightSensorReadingChangedEventArgs*
  120. reading_changed_args) override;
  121. private:
  122. float last_reported_lux_ = 0.0f;
  123. PlatformSensorReaderWinrtLightSensor(
  124. const PlatformSensorReaderWinrtLightSensor&) = delete;
  125. PlatformSensorReaderWinrtLightSensor& operator=(
  126. const PlatformSensorReaderWinrtLightSensor&) = delete;
  127. };
  128. class PlatformSensorReaderWinrtAccelerometer final
  129. : public PlatformSensorReaderWinrtBase<
  130. RuntimeClass_Windows_Devices_Sensors_Accelerometer,
  131. ABI::Windows::Devices::Sensors::IAccelerometerStatics,
  132. ABI::Windows::Devices::Sensors::IAccelerometer,
  133. Microsoft::WRL::Implements<
  134. Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
  135. ABI::Windows::Foundation::ITypedEventHandler<
  136. ABI::Windows::Devices::Sensors::Accelerometer*,
  137. ABI::Windows::Devices::Sensors::
  138. AccelerometerReadingChangedEventArgs*>,
  139. Microsoft::WRL::FtmBase>,
  140. ABI::Windows::Devices::Sensors::
  141. IAccelerometerReadingChangedEventArgs> {
  142. public:
  143. static constexpr double kAxisThreshold = 0.1f;
  144. static std::unique_ptr<PlatformSensorReaderWinBase> Create();
  145. PlatformSensorReaderWinrtAccelerometer();
  146. ~PlatformSensorReaderWinrtAccelerometer() override = default;
  147. protected:
  148. HRESULT OnReadingChangedCallback(
  149. ABI::Windows::Devices::Sensors::IAccelerometer* sensor,
  150. ABI::Windows::Devices::Sensors::IAccelerometerReadingChangedEventArgs*
  151. reading_changed_args) override;
  152. private:
  153. double last_reported_x_ = 0.0;
  154. double last_reported_y_ = 0.0;
  155. double last_reported_z_ = 0.0;
  156. PlatformSensorReaderWinrtAccelerometer(
  157. const PlatformSensorReaderWinrtAccelerometer&) = delete;
  158. PlatformSensorReaderWinrtAccelerometer& operator=(
  159. const PlatformSensorReaderWinrtAccelerometer&) = delete;
  160. };
  161. class PlatformSensorReaderWinrtGyrometer final
  162. : public PlatformSensorReaderWinrtBase<
  163. RuntimeClass_Windows_Devices_Sensors_Gyrometer,
  164. ABI::Windows::Devices::Sensors::IGyrometerStatics,
  165. ABI::Windows::Devices::Sensors::IGyrometer,
  166. Microsoft::WRL::Implements<
  167. Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
  168. ABI::Windows::Foundation::ITypedEventHandler<
  169. ABI::Windows::Devices::Sensors::Gyrometer*,
  170. ABI::Windows::Devices::Sensors::
  171. GyrometerReadingChangedEventArgs*>,
  172. Microsoft::WRL::FtmBase>,
  173. ABI::Windows::Devices::Sensors::IGyrometerReadingChangedEventArgs> {
  174. public:
  175. static constexpr double kDegreeThreshold = 0.1;
  176. static std::unique_ptr<PlatformSensorReaderWinBase> Create();
  177. PlatformSensorReaderWinrtGyrometer();
  178. ~PlatformSensorReaderWinrtGyrometer() override = default;
  179. protected:
  180. HRESULT OnReadingChangedCallback(
  181. ABI::Windows::Devices::Sensors::IGyrometer* sensor,
  182. ABI::Windows::Devices::Sensors::IGyrometerReadingChangedEventArgs*
  183. reading_changed_args) override;
  184. private:
  185. double last_reported_x_ = 0.0;
  186. double last_reported_y_ = 0.0;
  187. double last_reported_z_ = 0.0;
  188. PlatformSensorReaderWinrtGyrometer(
  189. const PlatformSensorReaderWinrtGyrometer&) = delete;
  190. PlatformSensorReaderWinrtGyrometer& operator=(
  191. const PlatformSensorReaderWinrtGyrometer&) = delete;
  192. };
  193. class PlatformSensorReaderWinrtMagnetometer final
  194. : public PlatformSensorReaderWinrtBase<
  195. RuntimeClass_Windows_Devices_Sensors_Magnetometer,
  196. ABI::Windows::Devices::Sensors::IMagnetometerStatics,
  197. ABI::Windows::Devices::Sensors::IMagnetometer,
  198. Microsoft::WRL::Implements<
  199. Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
  200. ABI::Windows::Foundation::ITypedEventHandler<
  201. ABI::Windows::Devices::Sensors::Magnetometer*,
  202. ABI::Windows::Devices::Sensors::
  203. MagnetometerReadingChangedEventArgs*>,
  204. Microsoft::WRL::FtmBase>,
  205. ABI::Windows::Devices::Sensors::
  206. IMagnetometerReadingChangedEventArgs> {
  207. public:
  208. static constexpr double kMicroteslaThreshold = 0.1;
  209. static std::unique_ptr<PlatformSensorReaderWinBase> Create();
  210. PlatformSensorReaderWinrtMagnetometer();
  211. ~PlatformSensorReaderWinrtMagnetometer() override = default;
  212. protected:
  213. HRESULT OnReadingChangedCallback(
  214. ABI::Windows::Devices::Sensors::IMagnetometer* sensor,
  215. ABI::Windows::Devices::Sensors::IMagnetometerReadingChangedEventArgs*
  216. reading_changed_args) override;
  217. private:
  218. double last_reported_x_ = 0.0;
  219. double last_reported_y_ = 0.0;
  220. double last_reported_z_ = 0.0;
  221. PlatformSensorReaderWinrtMagnetometer(
  222. const PlatformSensorReaderWinrtMagnetometer&) = delete;
  223. PlatformSensorReaderWinrtMagnetometer& operator=(
  224. const PlatformSensorReaderWinrtMagnetometer&) = delete;
  225. };
  226. class PlatformSensorReaderWinrtAbsOrientationEulerAngles final
  227. : public PlatformSensorReaderWinrtBase<
  228. RuntimeClass_Windows_Devices_Sensors_Inclinometer,
  229. ABI::Windows::Devices::Sensors::IInclinometerStatics,
  230. ABI::Windows::Devices::Sensors::IInclinometer,
  231. Microsoft::WRL::Implements<
  232. Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
  233. ABI::Windows::Foundation::ITypedEventHandler<
  234. ABI::Windows::Devices::Sensors::Inclinometer*,
  235. ABI::Windows::Devices::Sensors::
  236. InclinometerReadingChangedEventArgs*>,
  237. Microsoft::WRL::FtmBase>,
  238. ABI::Windows::Devices::Sensors::
  239. IInclinometerReadingChangedEventArgs> {
  240. public:
  241. static constexpr double kDegreeThreshold = 0.1;
  242. static std::unique_ptr<PlatformSensorReaderWinBase> Create();
  243. PlatformSensorReaderWinrtAbsOrientationEulerAngles();
  244. ~PlatformSensorReaderWinrtAbsOrientationEulerAngles() override = default;
  245. protected:
  246. HRESULT OnReadingChangedCallback(
  247. ABI::Windows::Devices::Sensors::IInclinometer* sensor,
  248. ABI::Windows::Devices::Sensors::IInclinometerReadingChangedEventArgs*
  249. reading_changed_args) override;
  250. private:
  251. double last_reported_x_ = 0.0;
  252. double last_reported_y_ = 0.0;
  253. double last_reported_z_ = 0.0;
  254. PlatformSensorReaderWinrtAbsOrientationEulerAngles(
  255. const PlatformSensorReaderWinrtAbsOrientationEulerAngles&) = delete;
  256. PlatformSensorReaderWinrtAbsOrientationEulerAngles& operator=(
  257. const PlatformSensorReaderWinrtAbsOrientationEulerAngles&) = delete;
  258. };
  259. class PlatformSensorReaderWinrtAbsOrientationQuaternion final
  260. : public PlatformSensorReaderWinrtBase<
  261. RuntimeClass_Windows_Devices_Sensors_OrientationSensor,
  262. ABI::Windows::Devices::Sensors::IOrientationSensorStatics,
  263. ABI::Windows::Devices::Sensors::IOrientationSensor,
  264. Microsoft::WRL::Implements<
  265. Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
  266. ABI::Windows::Foundation::ITypedEventHandler<
  267. ABI::Windows::Devices::Sensors::OrientationSensor*,
  268. ABI::Windows::Devices::Sensors::
  269. OrientationSensorReadingChangedEventArgs*>,
  270. Microsoft::WRL::FtmBase>,
  271. ABI::Windows::Devices::Sensors::
  272. IOrientationSensorReadingChangedEventArgs> {
  273. public:
  274. static constexpr double kRadianThreshold = gfx::DegToRad(0.1);
  275. static std::unique_ptr<PlatformSensorReaderWinBase> Create();
  276. PlatformSensorReaderWinrtAbsOrientationQuaternion();
  277. ~PlatformSensorReaderWinrtAbsOrientationQuaternion() override;
  278. protected:
  279. HRESULT OnReadingChangedCallback(
  280. ABI::Windows::Devices::Sensors::IOrientationSensor* sensor,
  281. ABI::Windows::Devices::Sensors::IOrientationSensorReadingChangedEventArgs*
  282. reading_changed_args) override;
  283. private:
  284. SensorReading last_reported_sample{};
  285. PlatformSensorReaderWinrtAbsOrientationQuaternion(
  286. const PlatformSensorReaderWinrtAbsOrientationQuaternion&) = delete;
  287. PlatformSensorReaderWinrtAbsOrientationQuaternion& operator=(
  288. const PlatformSensorReaderWinrtAbsOrientationQuaternion&) = delete;
  289. };
  290. } // namespace device
  291. #endif // SERVICES_DEVICE_GENERIC_SENSOR_PLATFORM_SENSOR_READER_WINRT_H_