123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "chromeos/components/sensors/fake_sensor_device.h"
- #include <utility>
- #include "base/bind.h"
- #include "base/containers/flat_map.h"
- #include "base/numerics/safe_conversions.h"
- #include "base/ranges/algorithm.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- namespace chromeos {
- namespace sensors {
- FakeSensorDevice::ChannelData::ChannelData() = default;
- FakeSensorDevice::ChannelData::ChannelData(
- const FakeSensorDevice::ChannelData&) = default;
- FakeSensorDevice::ChannelData& FakeSensorDevice::ChannelData::operator=(
- const FakeSensorDevice::ChannelData&) = default;
- FakeSensorDevice::ChannelData::~ChannelData() = default;
- FakeSensorDevice::FakeSensorDevice(const std::vector<ChannelData>& channels)
- : channels_(channels) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- for (auto& client : clients_)
- client.second.channels_enabled.assign(channels_.size(), false);
- }
- FakeSensorDevice::~FakeSensorDevice() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- }
- mojo::ReceiverId FakeSensorDevice::AddReceiver(
- mojo::PendingReceiver<mojom::SensorDevice> pending_receiver) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto id = receiver_set_.Add(this, std::move(pending_receiver));
- DCHECK(clients_.find(id) == clients_.end());
- clients_[id].channels_enabled.assign(channels_.size(), false);
- return id;
- }
- void FakeSensorDevice::RemoveReceiver(mojo::ReceiverId id) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(receiver_set_.HasReceiver(id));
- clients_.erase(id);
- receiver_set_.Remove(id);
- }
- void FakeSensorDevice::RemoveReceiverWithReason(
- mojo::ReceiverId id,
- mojom::SensorDeviceDisconnectReason reason,
- const std::string& description) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(receiver_set_.HasReceiver(id));
- uint32_t custom_reason_code = base::checked_cast<uint32_t>(reason);
- auto it = clients_.find(id);
- if (it != clients_.end()) {
- it->second.observer.ResetWithReason(custom_reason_code, description);
- clients_.erase(it);
- }
- receiver_set_.RemoveWithReason(id, custom_reason_code, description);
- }
- void FakeSensorDevice::ClearReceivers() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- clients_.clear();
- receiver_set_.Clear();
- }
- void FakeSensorDevice::ClearReceiversWithReason(
- mojom::SensorDeviceDisconnectReason reason,
- const std::string& description) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- uint32_t custom_reason_code = base::checked_cast<uint32_t>(reason);
- for (auto& client : clients_)
- client.second.observer.ResetWithReason(custom_reason_code, description);
- clients_.clear();
- receiver_set_.ClearWithReason(custom_reason_code, description);
- }
- bool FakeSensorDevice::HasReceivers() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return !receiver_set_.empty();
- }
- size_t FakeSensorDevice::SizeOfReceivers() const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return receiver_set_.size();
- }
- void FakeSensorDevice::SetAttribute(const std::string& attr_name,
- const std::string& attr_value) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- attributes_[attr_name] = attr_value;
- }
- void FakeSensorDevice::ResetObserverRemote(mojo::ReceiverId id) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto it = clients_.find(id);
- if (it == clients_.end())
- return;
- it->second.observer.reset();
- }
- void FakeSensorDevice::ResetObserverRemoteWithReason(
- mojo::ReceiverId id,
- mojom::SensorDeviceDisconnectReason reason,
- const std::string& description) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto it = clients_.find(id);
- if (it == clients_.end())
- return;
- it->second.observer.ResetWithReason(base::checked_cast<uint32_t>(reason),
- description);
- }
- void FakeSensorDevice::SetChannelsEnabledWithId(
- mojo::ReceiverId id,
- const std::vector<int32_t>& iio_chn_indices,
- bool en) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto it = clients_.find(id);
- DCHECK(it != clients_.end());
- for (int32_t index : iio_chn_indices) {
- DCHECK_LT(static_cast<size_t>(index), it->second.channels_enabled.size());
- it->second.channels_enabled[index] = en;
- }
- SendSampleIfReady(it->second);
- }
- void FakeSensorDevice::GetAttributes(const std::vector<std::string>& attr_names,
- GetAttributesCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- std::vector<absl::optional<std::string>> values;
- values.reserve(attr_names.size());
- for (const auto& attr_name : attr_names) {
- auto it = attributes_.find(attr_name);
- if (it != attributes_.end())
- values.push_back(it->second);
- else
- values.push_back(absl::nullopt);
- }
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), std::move(values)));
- }
- void FakeSensorDevice::SetFrequency(double frequency,
- SetFrequencyCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- if (frequency < 0.0)
- frequency = 0.0;
- auto& client = clients_[receiver_set_.current_receiver()];
- client.frequency = frequency;
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), std::move(frequency)));
- SendSampleIfReady(client);
- }
- void FakeSensorDevice::StartReadingSamples(
- mojo::PendingRemote<mojom::SensorDeviceSamplesObserver> observer) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto id = receiver_set_.current_receiver();
- auto& client = clients_[id];
- if (client.observer.is_bound()) {
- mojo::Remote<mojom::SensorDeviceSamplesObserver> remote(
- std::move(observer));
- remote->OnErrorOccurred(mojom::ObserverErrorType::ALREADY_STARTED);
- return;
- }
- client.observer.Bind(std::move(observer));
- client.observer.set_disconnect_handler(base::BindOnce(
- &FakeSensorDevice::ResetObserverRemote, base::Unretained(this), id));
- if (!client.frequency.has_value() || client.frequency.value() <= 0.0) {
- client.observer->OnErrorOccurred(
- mojom::ObserverErrorType::FREQUENCY_INVALID);
- return;
- }
- if (base::ranges::none_of(client.channels_enabled,
- [](bool enabled) { return enabled; })) {
- client.observer->OnErrorOccurred(
- mojom::ObserverErrorType::NO_ENABLED_CHANNELS);
- return;
- }
- SendSampleIfReady(client);
- }
- void FakeSensorDevice::StopReadingSamples() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- clients_[receiver_set_.current_receiver()].observer.reset();
- }
- void FakeSensorDevice::GetAllChannelIds(GetAllChannelIdsCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- std::vector<std::string> channel_ids;
- for (const ChannelData& channel : channels_)
- channel_ids.push_back(channel.id);
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), std::move(channel_ids)));
- }
- void FakeSensorDevice::SetChannelsEnabled(
- const std::vector<int32_t>& iio_chn_indices,
- bool en,
- SetChannelsEnabledCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto& client = clients_[receiver_set_.current_receiver()];
- std::vector<int32_t> failed_indices;
- for (int32_t index : iio_chn_indices) {
- if (static_cast<size_t>(index) >= client.channels_enabled.size()) {
- failed_indices.push_back(index);
- continue;
- }
- client.channels_enabled[index] = en;
- }
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), std::move(failed_indices)));
- SendSampleIfReady(client);
- }
- void FakeSensorDevice::GetChannelsEnabled(
- const std::vector<int32_t>& iio_chn_indices,
- GetChannelsEnabledCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- auto& client = clients_[receiver_set_.current_receiver()];
- std::vector<bool> enabled;
- for (int32_t index : iio_chn_indices) {
- if (static_cast<size_t>(index) >= client.channels_enabled.size()) {
- enabled.push_back(false);
- continue;
- }
- enabled.push_back(client.channels_enabled[index]);
- }
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), std::move(enabled)));
- }
- void FakeSensorDevice::GetChannelsAttributes(
- const std::vector<int32_t>& iio_chn_indices,
- const std::string& attr_name,
- GetChannelsAttributesCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- std::vector<absl::optional<std::string>> attrs;
- for (const ChannelData& channel : channels_) {
- auto it = channel.attrs.find(attr_name);
- if (it == channel.attrs.end()) {
- attrs.push_back(absl::nullopt);
- continue;
- }
- attrs.push_back(it->second);
- }
- base::SequencedTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), std::move(attrs)));
- }
- FakeSensorDevice::ClientData::ClientData() = default;
- FakeSensorDevice::ClientData::~ClientData() = default;
- void FakeSensorDevice::SendSampleIfReady(ClientData& client) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK_EQ(channels_.size(), client.channels_enabled.size());
- if (!client.observer.is_bound())
- return;
- if (!client.frequency.has_value() || client.frequency.value() <= 0.0)
- return;
- base::flat_map<int32_t, int64_t> sample;
- for (size_t i = 0; i < channels_.size(); ++i) {
- if (!client.channels_enabled[i])
- continue;
- sample[i] = channels_[i].sample_data;
- }
- if (sample.empty())
- return;
- client.observer->OnSampleUpdated(std::move(sample));
- }
- } // namespace sensors
- } // namespace chromeos
|