accelerometer_samples_observer.cc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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 "ash/accelerometer/accelerometer_samples_observer.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. namespace ash {
  8. namespace {
  9. constexpr int kTimeoutToleranceInMilliseconds = 500;
  10. constexpr double kReadFrequencyInHz = 10.0;
  11. } // namespace
  12. AccelerometerSamplesObserver::AccelerometerSamplesObserver(
  13. int iio_device_id,
  14. mojo::Remote<chromeos::sensors::mojom::SensorDevice> sensor_device_remote,
  15. float scale,
  16. OnSampleUpdatedCallback on_sample_updated_callback)
  17. : iio_device_id_(iio_device_id),
  18. sensor_device_remote_(std::move(sensor_device_remote)),
  19. scale_(scale),
  20. on_sample_updated_callback_(std::move(on_sample_updated_callback)) {
  21. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  22. DCHECK(sensor_device_remote_.is_bound());
  23. sensor_device_remote_->GetAllChannelIds(
  24. base::BindOnce(&AccelerometerSamplesObserver::GetAllChannelIdsCallback,
  25. weak_factory_.GetWeakPtr()));
  26. }
  27. AccelerometerSamplesObserver::~AccelerometerSamplesObserver() = default;
  28. void AccelerometerSamplesObserver::SetEnabled(bool enabled) {
  29. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  30. if (enabled_ == enabled)
  31. return;
  32. enabled_ = enabled;
  33. UpdateSensorDeviceFrequency();
  34. }
  35. void AccelerometerSamplesObserver::OnSampleUpdated(
  36. const base::flat_map<int32_t, int64_t>& sample) {
  37. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  38. if (sample.size() != kNumberOfAxes) {
  39. LOG(ERROR) << "Invalid sample with size: " << sample.size();
  40. OnErrorOccurred(chromeos::sensors::mojom::ObserverErrorType::READ_FAILED);
  41. return;
  42. }
  43. auto it = sample.begin();
  44. std::vector<float> output_sample;
  45. for (size_t axes = 0; axes < kNumberOfAxes; ++axes) {
  46. if (axes != 0)
  47. ++it;
  48. if (it == sample.end() || it->first != channel_indices_[axes])
  49. it = sample.find(channel_indices_[axes]);
  50. if (it == sample.end()) {
  51. LOG(ERROR) << "Missing channel: " << kAccelerometerChannels[axes]
  52. << " in sample";
  53. OnErrorOccurred(chromeos::sensors::mojom::ObserverErrorType::READ_FAILED);
  54. return;
  55. }
  56. output_sample.push_back(it->second * scale_);
  57. }
  58. on_sample_updated_callback_.Run(iio_device_id_, output_sample);
  59. }
  60. void AccelerometerSamplesObserver::OnErrorOccurred(
  61. chromeos::sensors::mojom::ObserverErrorType type) {
  62. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  63. switch (type) {
  64. case chromeos::sensors::mojom::ObserverErrorType::ALREADY_STARTED:
  65. LOG(ERROR) << "Device " << iio_device_id_
  66. << ": Another observer has already started to read samples";
  67. Reset();
  68. break;
  69. case chromeos::sensors::mojom::ObserverErrorType::FREQUENCY_INVALID:
  70. if (!enabled_) // It's normal if this observer is not enabled
  71. break;
  72. LOG(ERROR) << "Device " << iio_device_id_
  73. << ": Observer started with an invalid frequency";
  74. UpdateSensorDeviceFrequency();
  75. break;
  76. case chromeos::sensors::mojom::ObserverErrorType::NO_ENABLED_CHANNELS:
  77. LOG(ERROR) << "Device " << iio_device_id_
  78. << ": Observer started with no channels enabled";
  79. if (sensor_device_remote_.is_bound()) {
  80. sensor_device_remote_->SetChannelsEnabled(
  81. std::vector<int32_t>(channel_indices_,
  82. channel_indices_ + kNumberOfAxes),
  83. /*enable=*/true,
  84. base::BindOnce(
  85. &AccelerometerSamplesObserver::SetChannelsEnabledCallback,
  86. weak_factory_.GetWeakPtr()));
  87. }
  88. break;
  89. case chromeos::sensors::mojom::ObserverErrorType::SET_FREQUENCY_IO_FAILED:
  90. LOG(ERROR) << "Device " << iio_device_id_
  91. << ": Failed to set frequency to the physical device";
  92. break;
  93. case chromeos::sensors::mojom::ObserverErrorType::GET_FD_FAILED:
  94. LOG(ERROR) << "Device " << iio_device_id_
  95. << ": Failed to get the device's fd to poll on";
  96. break;
  97. case chromeos::sensors::mojom::ObserverErrorType::READ_FAILED:
  98. LOG(ERROR) << "Device " << iio_device_id_ << ": Failed to read a sample";
  99. break;
  100. case chromeos::sensors::mojom::ObserverErrorType::READ_TIMEOUT:
  101. LOG(ERROR) << "Device " << iio_device_id_ << ": A read timed out";
  102. break;
  103. default:
  104. LOG(ERROR) << "Device " << iio_device_id_ << ": error "
  105. << static_cast<int>(type);
  106. break;
  107. }
  108. }
  109. void AccelerometerSamplesObserver::Reset() {
  110. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  111. LOG(ERROR) << "Resetting AccelerometerSamplesObserver: " << iio_device_id_;
  112. receiver_.reset();
  113. sensor_device_remote_.reset();
  114. }
  115. void AccelerometerSamplesObserver::GetAllChannelIdsCallback(
  116. const std::vector<std::string>& iio_channel_ids) {
  117. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  118. DCHECK(sensor_device_remote_.is_bound());
  119. iio_channel_ids_ = std::move(iio_channel_ids);
  120. for (size_t axis = 0; axis < kNumberOfAxes; ++axis) {
  121. bool found = false;
  122. for (size_t channel_index = 0; channel_index < iio_channel_ids_.size();
  123. ++channel_index) {
  124. if (iio_channel_ids_[channel_index].compare(
  125. kAccelerometerChannels[axis]) == 0) {
  126. found = true;
  127. channel_indices_[axis] = channel_index;
  128. break;
  129. }
  130. }
  131. if (!found) {
  132. LOG(ERROR) << "Missing channel: " << kAccelerometerChannels[axis];
  133. Reset();
  134. return;
  135. }
  136. }
  137. sensor_device_remote_->SetChannelsEnabled(
  138. std::vector<int32_t>(channel_indices_, channel_indices_ + kNumberOfAxes),
  139. /*enable=*/true,
  140. base::BindOnce(&AccelerometerSamplesObserver::SetChannelsEnabledCallback,
  141. weak_factory_.GetWeakPtr()));
  142. StartReading();
  143. }
  144. void AccelerometerSamplesObserver::StartReading() {
  145. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  146. DCHECK(sensor_device_remote_.is_bound());
  147. sensor_device_remote_->SetTimeout(kTimeoutToleranceInMilliseconds);
  148. sensor_device_remote_->StartReadingSamples(GetPendingRemote());
  149. }
  150. void AccelerometerSamplesObserver::UpdateSensorDeviceFrequency() {
  151. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  152. if (!sensor_device_remote_.is_bound())
  153. return;
  154. sensor_device_remote_->SetFrequency(
  155. enabled_ ? kReadFrequencyInHz : 0.0,
  156. base::BindOnce(&AccelerometerSamplesObserver::SetFrequencyCallback,
  157. weak_factory_.GetWeakPtr(), enabled_));
  158. }
  159. mojo::PendingRemote<chromeos::sensors::mojom::SensorDeviceSamplesObserver>
  160. AccelerometerSamplesObserver::GetPendingRemote() {
  161. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  162. auto pending_remote = receiver_.BindNewPipeAndPassRemote();
  163. receiver_.set_disconnect_handler(
  164. base::BindOnce(&AccelerometerSamplesObserver::OnObserverDisconnect,
  165. weak_factory_.GetWeakPtr()));
  166. return pending_remote;
  167. }
  168. void AccelerometerSamplesObserver::OnObserverDisconnect() {
  169. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  170. LOG(ERROR) << "OnObserverDisconnect error, assuming IIO Service crashes and "
  171. "waiting for its relaunch.";
  172. // Don't reset |sensor_device_remote_| so that AccelerometerProviderMojo can
  173. // get the disconnection.
  174. receiver_.reset();
  175. }
  176. void AccelerometerSamplesObserver::SetFrequencyCallback(
  177. bool enabled,
  178. double result_frequency) {
  179. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  180. if (enabled != enabled_) {
  181. // As the current configuration (required frequency) is different now,
  182. // ignore the result of this deprecated |SensorDevice::SetFrequency|.
  183. return;
  184. }
  185. if ((result_frequency > 0.0 && enabled_) ||
  186. (result_frequency == 0.0 && !enabled_)) {
  187. return;
  188. }
  189. LOG(ERROR) << "Failed to set frequency: " << result_frequency
  190. << " with the samples observer enabled: "
  191. << (enabled_ ? "true" : "false");
  192. Reset();
  193. }
  194. void AccelerometerSamplesObserver::SetChannelsEnabledCallback(
  195. const std::vector<int32_t>& failed_indices) {
  196. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  197. for (int32_t index : failed_indices)
  198. LOG(ERROR) << "Failed to enable " << iio_channel_ids_[index];
  199. if (!failed_indices.empty())
  200. Reset();
  201. }
  202. } // namespace ash