blob: 9a852cd9ab56e57bc4f471fc4e50981a69668620 [file] [log] [blame]
// Copyright 2021 The Chromium OS 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 "iioservice/iioservice_simpleclient/query_impl.h"
#include <utility>
#include <base/bind.h>
#include "iioservice/include/common.h"
namespace iioservice {
QueryImpl::ScopedQueryImpl QueryImpl::Create(
scoped_refptr<base::SequencedTaskRunner> ipc_task_runner,
cros::mojom::DeviceType device_type,
std::vector<std::string> attributes,
QuitCallback quit_callback) {
ScopedQueryImpl query(
new QueryImpl(ipc_task_runner, device_type, std::move(attributes),
std::move(quit_callback)),
SensorClientDeleter);
return query;
}
QueryImpl::QueryImpl(scoped_refptr<base::SequencedTaskRunner> ipc_task_runner,
cros::mojom::DeviceType device_type,
std::vector<std::string> attributes,
QuitCallback quit_callback)
: SensorClient(std::move(ipc_task_runner), std::move(quit_callback)),
device_type_(device_type),
attributes_(std::move(attributes)) {
DCHECK(!attributes_.empty());
remotes_.set_disconnect_handler(base::BindRepeating(
&QueryImpl::OnDeviceDisconnect, weak_factory_.GetWeakPtr()));
}
void QueryImpl::Start() {
DCHECK(ipc_task_runner_->RunsTasksInCurrentSequence());
if (device_type_ == cros::mojom::DeviceType::NONE) {
sensor_service_remote_->GetAllDeviceIds(base::BindOnce(
&QueryImpl::GetAllDeviceIdsCallback, weak_factory_.GetWeakPtr()));
return;
}
sensor_service_remote_->GetDeviceIds(
device_type_, base::BindOnce(&QueryImpl::GetDeviceIdsCallback,
weak_factory_.GetWeakPtr()));
}
void QueryImpl::OnDeviceDisconnect(mojo::RemoteSetElementId id) {
DCHECK(ipc_task_runner_->RunsTasksInCurrentSequence());
LOGF(ERROR) << "SensorDevice disconnected with RemoteSetElementId: " << id;
if (remotes_.empty())
Reset();
}
void QueryImpl::GetAllDeviceIdsCallback(
const base::flat_map<int32_t, std::vector<cros::mojom::DeviceType>>&
iio_device_ids_types) {
DCHECK(ipc_task_runner_->RunsTasksInCurrentSequence());
for (const auto& [id, types] : iio_device_ids_types) {
mojo::Remote<cros::mojom::SensorDevice> remote;
sensor_service_remote_->GetDevice(id, remote.BindNewPipeAndPassReceiver());
remote->GetAttributes(
attributes_, base::BindOnce(&QueryImpl::GetAttributesCallback,
weak_factory_.GetWeakPtr(), id, types));
device_ids_[id] = remotes_.Add(std::move(remote));
}
}
void QueryImpl::GetDeviceIdsCallback(
const std::vector<int32_t>& iio_device_ids) {
DCHECK(ipc_task_runner_->RunsTasksInCurrentSequence());
for (const int32_t& id : iio_device_ids) {
mojo::Remote<cros::mojom::SensorDevice> remote;
sensor_service_remote_->GetDevice(id, remote.BindNewPipeAndPassReceiver());
remote->GetAttributes(
attributes_,
base::BindOnce(&QueryImpl::GetAttributesCallback,
weak_factory_.GetWeakPtr(), id,
std::vector<cros::mojom::DeviceType>{device_type_}));
device_ids_[id] = remotes_.Add(std::move(remote));
}
}
void QueryImpl::GetAttributesCallback(
int32_t iio_device_id,
std::vector<cros::mojom::DeviceType> types,
const std::vector<base::Optional<std::string>>& values) {
DCHECK(ipc_task_runner_->RunsTasksInCurrentSequence());
DCHECK(device_ids_.find(iio_device_id) != device_ids_.end());
DCHECK_EQ(attributes_.size(), values.size());
// TODO(gwendal): Please tell me the format of output that's easy to parse in
// the tast test.
LOGF(INFO) << "Device id: " << iio_device_id;
for (auto type : types)
LOGF(INFO) << "Type: " << type;
for (size_t i = 0; i < values.size(); ++i)
LOGF(INFO) << attributes_[i] << ": " << values[i].value_or("");
remotes_.Remove(device_ids_[iio_device_id]);
if (remotes_.empty())
Reset();
}
} // namespace iioservice