blob: b60a629d5f84a035e6759f2a59cd2f21786dce13 [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.
#ifndef SRC_CAMERA_BIN_DEVICE_UTIL_H_
#define SRC_CAMERA_BIN_DEVICE_UTIL_H_
#include <fuchsia/camera2/hal/cpp/fidl.h>
#include <fuchsia/camera3/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fit/result.h>
#include <lib/syslog/cpp/logger.h>
#include <zircon/status.h>
// Safely unbinds a client connection, doing so on the connection's thread if it differs from the
// caller's thread.
template <class T>
inline void Unbind(fidl::InterfacePtr<T>& p) {
if (!p) {
return;
}
if (p.dispatcher() == async_get_default_dispatcher()) {
p.Unbind();
return;
}
async::PostTask(p.dispatcher(), [&]() { p.Unbind(); });
}
// Converts a camera2.hal.Config to a camera3.Configuration
inline fit::result<fuchsia::camera3::Configuration, zx_status_t> Convert(
const fuchsia::camera2::hal::Config& config) {
if (config.stream_configs.empty()) {
FX_PLOGS(ERROR, ZX_ERR_INTERNAL) << "Config reported no streams.";
return fit::error(ZX_ERR_INTERNAL);
}
fuchsia::camera3::Configuration ret{};
for (const auto& stream_config : config.stream_configs) {
if (stream_config.image_formats.empty()) {
FX_PLOGS(ERROR, ZX_ERR_INTERNAL) << "Stream reported no image formats.";
return fit::error(ZX_ERR_INTERNAL);
}
fuchsia::camera3::StreamProperties stream_properties{};
stream_properties.frame_rate.numerator = stream_config.frame_rate.frames_per_sec_numerator;
stream_properties.frame_rate.denominator = stream_config.frame_rate.frames_per_sec_denominator;
stream_properties.image_format = stream_config.image_formats[0];
ret.streams.push_back(std::move(stream_properties));
}
return fit::ok(std::move(ret));
}
// Waits until |deadline| for |event| to signal all bits in |signals_all| or any bits in
// |signals_any|, accumulating signaled bits into |pending|.
inline zx_status_t WaitMixed(const zx::event& event, zx_signals_t signals_all,
zx_signals_t signals_any, zx::time deadline, zx_signals_t* pending) {
ZX_ASSERT(pending);
*pending = ZX_SIGNAL_NONE;
zx_status_t status = ZX_OK;
while (status == ZX_OK) {
zx_signals_t signaled{};
status = event.wait_one(signals_all | signals_any, deadline, &signaled);
*pending |= signaled;
if ((*pending & signals_all) == signals_all) {
return status;
}
if ((*pending & signals_any) != ZX_SIGNAL_NONE) {
return status;
}
}
return status;
}
#endif // SRC_CAMERA_BIN_DEVICE_UTIL_H_