blob: 49b3216f1080b1876a92d2233c575a1d89d7a4fa [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/usb_device/device_impl.h"
#include "src/camera/bin/usb_device/uvc_hack.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::OnClientDisconnected(zx_status_t status) {
FX_PLOGS(INFO, status) << log_prefix_ << "closed connection";
device_.Schedule(device_.RemoveClient(id_));
}
void DeviceImpl::Client::CloseConnection(zx_status_t status) {
binding_.Close(status);
device_.Schedule(device_.RemoveClient(id_));
}
void DeviceImpl::Client::GetIdentifier(GetIdentifierCallback callback) {
FX_LOGS(INFO) << log_prefix_ << "called GetIdentifier()";
std::ostringstream oss;
oss << std::hex << std::uppercase << std::setfill('0');
// Fake vendor ID.
// TODO(ernesthua) - Need to construct this from the device information fetched.
oss << "0000:0000";
callback(oss.str());
}
void DeviceImpl::Client::GetConfigurations(GetConfigurationsCallback callback) {
FX_LOGS(INFO) << log_prefix_ << "called GetConfigurations()";
// Fake configuration.
// TODO(ernesthua) - Need to construct this from the device configurations fetched.
std::vector<fuchsia::camera3::Configuration> configurations;
{
std::vector<fuchsia::camera3::StreamProperties> streams;
{
fuchsia::camera3::StreamProperties stream_properties;
UvcHackGetClientStreamProperties(&stream_properties);
streams.push_back(std::move(stream_properties));
}
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_.Schedule(device_.SetConfiguration(index));
}
void DeviceImpl::Client::WatchMuteState(WatchMuteStateCallback callback) {
FX_LOGS(ERROR) << log_prefix_ << "FIDL call not supported";
}
void DeviceImpl::Client::SetSoftwareMuteState(bool muted, SetSoftwareMuteStateCallback callback) {
FX_LOGS(ERROR) << log_prefix_ << "FIDL call not supported";
}
void DeviceImpl::Client::ConnectToStream(uint32_t index,
fidl::InterfaceRequest<fuchsia::camera3::Stream> request) {
FX_LOGS(INFO) << log_prefix_ << "called ConnectToStream(" << index << ")";
device_.Schedule(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_.Schedule(device_.Bind(std::move(request)));
}
} // namespace camera