blob: 3a571a5f0a07dee4bd0f25ff4ca39a8eeb22defa [file] [log] [blame]
// Copyright 2020 The Fuchsia 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 <lib/async/cpp/task.h>
#include <lib/syslog/cpp/macros.h>
#include <iomanip>
#include <sstream>
#include "src/camera/bin/device/device_impl.h"
namespace camera {
DeviceImpl::Client::Client(DeviceImpl& device, uint64_t id,
fidl::InterfaceRequest<fuchsia::camera3::Device> request)
: device_(device), id_(id), binding_(this, std::move(request)) {
log_prefix_ = "device client (koid = " + std::to_string(GetRelatedKoid(binding_)) + "): ";
FX_LOGS(INFO) << log_prefix_ << "new device client, id = " << id_;
binding_.set_error_handler(fit::bind_member(this, &DeviceImpl::Client::OnClientDisconnected));
}
DeviceImpl::Client::~Client() = default;
void DeviceImpl::Client::ConfigurationUpdated(uint32_t index) { configuration_.Set(index); }
void DeviceImpl::Client::MuteUpdated(MuteState mute_state) { mute_state_.Set(mute_state); }
void DeviceImpl::Client::OnClientDisconnected(zx_status_t status) {
FX_PLOGS(INFO, status) << log_prefix_ << "closed connection";
device_.RemoveClient(id_);
}
void DeviceImpl::Client::CloseConnection(zx_status_t status) {
binding_.Close(status);
device_.RemoveClient(id_);
}
void DeviceImpl::Client::GetIdentifier(GetIdentifierCallback callback) {
FX_LOGS(INFO) << log_prefix_ << "called GetIdentifier()";
if (!device_.device_info_.has_vendor_id() || !device_.device_info_.has_product_id()) {
callback(cpp17::nullopt);
return;
}
std::ostringstream oss;
oss << std::hex << std::uppercase << std::setfill('0');
oss << std::setw(4) << device_.device_info_.vendor_id();
oss << std::setw(4) << device_.device_info_.product_id();
callback(oss.str());
}
void DeviceImpl::Client::GetConfigurations(GetConfigurationsCallback callback) {
FX_LOGS(INFO) << log_prefix_ << "called GetConfigurations()";
std::vector<fuchsia::camera3::Configuration> configurations;
for (const auto& configuration : device_.configurations_) {
std::vector<fuchsia::camera3::StreamProperties> streams;
for (const auto& stream : configuration.streams()) {
streams.push_back(Convert(stream));
}
configurations.push_back({.streams = std::move(streams)});
}
callback(std::move(configurations));
}
void DeviceImpl::Client::GetConfigurations2(GetConfigurations2Callback callback) {
FX_LOGS(INFO) << log_prefix_ << "called GetConfigurations2()";
callback(fidl::Clone(device_.configurations_));
}
void DeviceImpl::Client::WatchCurrentConfiguration(WatchCurrentConfigurationCallback callback) {
FX_LOGS(INFO) << log_prefix_ << "called WatchCurrentConfiguration()";
if (configuration_.Get(std::move(callback))) {
CloseConnection(ZX_ERR_BAD_STATE);
}
}
void DeviceImpl::Client::SetCurrentConfiguration(uint32_t index) {
FX_LOGS(INFO) << log_prefix_ << "called SetCurrentConfiguration(" << index << ")";
if (index < 0 || index >= device_.configurations_.size()) {
CloseConnection(ZX_ERR_OUT_OF_RANGE);
return;
}
device_.SetConfiguration(index);
}
void DeviceImpl::Client::WatchMuteState(WatchMuteStateCallback callback) {
FX_LOGS(INFO) << log_prefix_ << "called WatchMuteState()";
if (mute_state_.Get([callback = std::move(callback)](MuteState mute_state) {
callback(mute_state.software_muted, mute_state.hardware_muted);
})) {
CloseConnection(ZX_ERR_BAD_STATE);
}
}
void DeviceImpl::Client::SetSoftwareMuteState(bool muted, SetSoftwareMuteStateCallback callback) {
FX_LOGS(INFO) << log_prefix_ << "called SetSoftwareMuteState(" << muted << ")";
if (!muted) {
callback();
callback = [] {};
}
device_.SetSoftwareMuteState(muted, std::move(callback));
}
void DeviceImpl::Client::ConnectToStream(uint32_t index,
fidl::InterfaceRequest<fuchsia::camera3::Stream> request) {
FX_LOGS(INFO) << log_prefix_ << "called ConnectToStream(" << index << ")";
device_.ConnectToStream(index, std::move(request));
}
void DeviceImpl::Client::Rebind(fidl::InterfaceRequest<fuchsia::camera3::Device> request) {
FX_LOGS(INFO) << log_prefix_ << "called Rebind(koid = " << GetRelatedKoid(request) << ")";
device_.Bind(std::move(request));
}
} // namespace camera