fake_sensor_device.cc 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // Copyright 2020 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. #include "chromeos/components/sensors/fake_sensor_device.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/containers/flat_map.h"
  8. #include "base/numerics/safe_conversions.h"
  9. #include "base/ranges/algorithm.h"
  10. #include "base/threading/sequenced_task_runner_handle.h"
  11. namespace chromeos {
  12. namespace sensors {
  13. FakeSensorDevice::ChannelData::ChannelData() = default;
  14. FakeSensorDevice::ChannelData::ChannelData(
  15. const FakeSensorDevice::ChannelData&) = default;
  16. FakeSensorDevice::ChannelData& FakeSensorDevice::ChannelData::operator=(
  17. const FakeSensorDevice::ChannelData&) = default;
  18. FakeSensorDevice::ChannelData::~ChannelData() = default;
  19. FakeSensorDevice::FakeSensorDevice(const std::vector<ChannelData>& channels)
  20. : channels_(channels) {
  21. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  22. for (auto& client : clients_)
  23. client.second.channels_enabled.assign(channels_.size(), false);
  24. }
  25. FakeSensorDevice::~FakeSensorDevice() {
  26. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  27. }
  28. mojo::ReceiverId FakeSensorDevice::AddReceiver(
  29. mojo::PendingReceiver<mojom::SensorDevice> pending_receiver) {
  30. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  31. auto id = receiver_set_.Add(this, std::move(pending_receiver));
  32. DCHECK(clients_.find(id) == clients_.end());
  33. clients_[id].channels_enabled.assign(channels_.size(), false);
  34. return id;
  35. }
  36. void FakeSensorDevice::RemoveReceiver(mojo::ReceiverId id) {
  37. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  38. DCHECK(receiver_set_.HasReceiver(id));
  39. clients_.erase(id);
  40. receiver_set_.Remove(id);
  41. }
  42. void FakeSensorDevice::RemoveReceiverWithReason(
  43. mojo::ReceiverId id,
  44. mojom::SensorDeviceDisconnectReason reason,
  45. const std::string& description) {
  46. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  47. DCHECK(receiver_set_.HasReceiver(id));
  48. uint32_t custom_reason_code = base::checked_cast<uint32_t>(reason);
  49. auto it = clients_.find(id);
  50. if (it != clients_.end()) {
  51. it->second.observer.ResetWithReason(custom_reason_code, description);
  52. clients_.erase(it);
  53. }
  54. receiver_set_.RemoveWithReason(id, custom_reason_code, description);
  55. }
  56. void FakeSensorDevice::ClearReceivers() {
  57. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  58. clients_.clear();
  59. receiver_set_.Clear();
  60. }
  61. void FakeSensorDevice::ClearReceiversWithReason(
  62. mojom::SensorDeviceDisconnectReason reason,
  63. const std::string& description) {
  64. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  65. uint32_t custom_reason_code = base::checked_cast<uint32_t>(reason);
  66. for (auto& client : clients_)
  67. client.second.observer.ResetWithReason(custom_reason_code, description);
  68. clients_.clear();
  69. receiver_set_.ClearWithReason(custom_reason_code, description);
  70. }
  71. bool FakeSensorDevice::HasReceivers() const {
  72. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  73. return !receiver_set_.empty();
  74. }
  75. size_t FakeSensorDevice::SizeOfReceivers() const {
  76. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  77. return receiver_set_.size();
  78. }
  79. void FakeSensorDevice::SetAttribute(const std::string& attr_name,
  80. const std::string& attr_value) {
  81. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  82. attributes_[attr_name] = attr_value;
  83. }
  84. void FakeSensorDevice::ResetObserverRemote(mojo::ReceiverId id) {
  85. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  86. auto it = clients_.find(id);
  87. if (it == clients_.end())
  88. return;
  89. it->second.observer.reset();
  90. }
  91. void FakeSensorDevice::ResetObserverRemoteWithReason(
  92. mojo::ReceiverId id,
  93. mojom::SensorDeviceDisconnectReason reason,
  94. const std::string& description) {
  95. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  96. auto it = clients_.find(id);
  97. if (it == clients_.end())
  98. return;
  99. it->second.observer.ResetWithReason(base::checked_cast<uint32_t>(reason),
  100. description);
  101. }
  102. void FakeSensorDevice::SetChannelsEnabledWithId(
  103. mojo::ReceiverId id,
  104. const std::vector<int32_t>& iio_chn_indices,
  105. bool en) {
  106. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  107. auto it = clients_.find(id);
  108. DCHECK(it != clients_.end());
  109. for (int32_t index : iio_chn_indices) {
  110. DCHECK_LT(static_cast<size_t>(index), it->second.channels_enabled.size());
  111. it->second.channels_enabled[index] = en;
  112. }
  113. SendSampleIfReady(it->second);
  114. }
  115. void FakeSensorDevice::GetAttributes(const std::vector<std::string>& attr_names,
  116. GetAttributesCallback callback) {
  117. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  118. std::vector<absl::optional<std::string>> values;
  119. values.reserve(attr_names.size());
  120. for (const auto& attr_name : attr_names) {
  121. auto it = attributes_.find(attr_name);
  122. if (it != attributes_.end())
  123. values.push_back(it->second);
  124. else
  125. values.push_back(absl::nullopt);
  126. }
  127. base::SequencedTaskRunnerHandle::Get()->PostTask(
  128. FROM_HERE, base::BindOnce(std::move(callback), std::move(values)));
  129. }
  130. void FakeSensorDevice::SetFrequency(double frequency,
  131. SetFrequencyCallback callback) {
  132. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  133. if (frequency < 0.0)
  134. frequency = 0.0;
  135. auto& client = clients_[receiver_set_.current_receiver()];
  136. client.frequency = frequency;
  137. base::SequencedTaskRunnerHandle::Get()->PostTask(
  138. FROM_HERE, base::BindOnce(std::move(callback), std::move(frequency)));
  139. SendSampleIfReady(client);
  140. }
  141. void FakeSensorDevice::StartReadingSamples(
  142. mojo::PendingRemote<mojom::SensorDeviceSamplesObserver> observer) {
  143. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  144. auto id = receiver_set_.current_receiver();
  145. auto& client = clients_[id];
  146. if (client.observer.is_bound()) {
  147. mojo::Remote<mojom::SensorDeviceSamplesObserver> remote(
  148. std::move(observer));
  149. remote->OnErrorOccurred(mojom::ObserverErrorType::ALREADY_STARTED);
  150. return;
  151. }
  152. client.observer.Bind(std::move(observer));
  153. client.observer.set_disconnect_handler(base::BindOnce(
  154. &FakeSensorDevice::ResetObserverRemote, base::Unretained(this), id));
  155. if (!client.frequency.has_value() || client.frequency.value() <= 0.0) {
  156. client.observer->OnErrorOccurred(
  157. mojom::ObserverErrorType::FREQUENCY_INVALID);
  158. return;
  159. }
  160. if (base::ranges::none_of(client.channels_enabled,
  161. [](bool enabled) { return enabled; })) {
  162. client.observer->OnErrorOccurred(
  163. mojom::ObserverErrorType::NO_ENABLED_CHANNELS);
  164. return;
  165. }
  166. SendSampleIfReady(client);
  167. }
  168. void FakeSensorDevice::StopReadingSamples() {
  169. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  170. clients_[receiver_set_.current_receiver()].observer.reset();
  171. }
  172. void FakeSensorDevice::GetAllChannelIds(GetAllChannelIdsCallback callback) {
  173. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  174. std::vector<std::string> channel_ids;
  175. for (const ChannelData& channel : channels_)
  176. channel_ids.push_back(channel.id);
  177. base::SequencedTaskRunnerHandle::Get()->PostTask(
  178. FROM_HERE, base::BindOnce(std::move(callback), std::move(channel_ids)));
  179. }
  180. void FakeSensorDevice::SetChannelsEnabled(
  181. const std::vector<int32_t>& iio_chn_indices,
  182. bool en,
  183. SetChannelsEnabledCallback callback) {
  184. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  185. auto& client = clients_[receiver_set_.current_receiver()];
  186. std::vector<int32_t> failed_indices;
  187. for (int32_t index : iio_chn_indices) {
  188. if (static_cast<size_t>(index) >= client.channels_enabled.size()) {
  189. failed_indices.push_back(index);
  190. continue;
  191. }
  192. client.channels_enabled[index] = en;
  193. }
  194. base::SequencedTaskRunnerHandle::Get()->PostTask(
  195. FROM_HERE,
  196. base::BindOnce(std::move(callback), std::move(failed_indices)));
  197. SendSampleIfReady(client);
  198. }
  199. void FakeSensorDevice::GetChannelsEnabled(
  200. const std::vector<int32_t>& iio_chn_indices,
  201. GetChannelsEnabledCallback callback) {
  202. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  203. auto& client = clients_[receiver_set_.current_receiver()];
  204. std::vector<bool> enabled;
  205. for (int32_t index : iio_chn_indices) {
  206. if (static_cast<size_t>(index) >= client.channels_enabled.size()) {
  207. enabled.push_back(false);
  208. continue;
  209. }
  210. enabled.push_back(client.channels_enabled[index]);
  211. }
  212. base::SequencedTaskRunnerHandle::Get()->PostTask(
  213. FROM_HERE, base::BindOnce(std::move(callback), std::move(enabled)));
  214. }
  215. void FakeSensorDevice::GetChannelsAttributes(
  216. const std::vector<int32_t>& iio_chn_indices,
  217. const std::string& attr_name,
  218. GetChannelsAttributesCallback callback) {
  219. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  220. std::vector<absl::optional<std::string>> attrs;
  221. for (const ChannelData& channel : channels_) {
  222. auto it = channel.attrs.find(attr_name);
  223. if (it == channel.attrs.end()) {
  224. attrs.push_back(absl::nullopt);
  225. continue;
  226. }
  227. attrs.push_back(it->second);
  228. }
  229. base::SequencedTaskRunnerHandle::Get()->PostTask(
  230. FROM_HERE, base::BindOnce(std::move(callback), std::move(attrs)));
  231. }
  232. FakeSensorDevice::ClientData::ClientData() = default;
  233. FakeSensorDevice::ClientData::~ClientData() = default;
  234. void FakeSensorDevice::SendSampleIfReady(ClientData& client) {
  235. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  236. DCHECK_EQ(channels_.size(), client.channels_enabled.size());
  237. if (!client.observer.is_bound())
  238. return;
  239. if (!client.frequency.has_value() || client.frequency.value() <= 0.0)
  240. return;
  241. base::flat_map<int32_t, int64_t> sample;
  242. for (size_t i = 0; i < channels_.size(); ++i) {
  243. if (!client.channels_enabled[i])
  244. continue;
  245. sample[i] = channels_[i].sample_data;
  246. }
  247. if (sample.empty())
  248. return;
  249. client.observer->OnSampleUpdated(std::move(sample));
  250. }
  251. } // namespace sensors
  252. } // namespace chromeos