blob: b77f973cc4cbd13e4f9446be01ad52b25411548b [file] [log] [blame]
// Copyright 2021 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 "data_processor_fidl.h"
#include <lib/fdio/fd.h>
#include <lib/syslog/cpp/macros.h>
#include "common.h"
namespace ftest_debug = fuchsia::test::debug;
using DataProcessorInitializer =
fit::function<std::unique_ptr<AbstractDataProcessor>(fbl::unique_fd)>;
DataProcessorFidl::DataProcessorFidl(
fidl::InterfaceRequest<ftest_debug::DebugDataProcessor> request, OnDoneCallback callback,
DataProcessorInitializer initializer, async_dispatcher_t* dispatcher)
: binding_(this),
on_done_(std::move(callback)),
processor_initializer_(std::move(initializer)),
dispatcher_(dispatcher) {
binding_.set_error_handler([this](zx_status_t status) { TearDown(status); });
binding_.Bind(std::move(request), dispatcher);
}
void DataProcessorFidl::SetDirectory(fidl::InterfaceHandle<fuchsia::io::Directory> directory) {
fbl::unique_fd fd;
auto status = fdio_fd_create(directory.TakeChannel().release(), fd.reset_and_get_address());
if (status != ZX_OK) {
FX_LOGS(ERROR) << "Failed to create file descriptor: " << status;
TearDown(ZX_ERR_NO_RESOURCES);
return;
}
std::unique_ptr<AbstractDataProcessor> processor = processor_initializer_(std::move(fd));
data_processor_.swap(processor);
}
void DataProcessorFidl::AddDebugVmos(::std::vector<::fuchsia::test::debug::DebugVmo> vmos,
AddDebugVmosCallback callback) {
if (!data_processor_) {
FX_LOGS(ERROR) << "Debug VMOs sent before directory set";
TearDown(ZX_ERR_INVALID_ARGS);
return;
}
for (auto& debug_vmo : vmos) {
DataSinkDump dump{.data_sink = std::move(debug_vmo.data_sink), .vmo = std::move(debug_vmo.vmo)};
data_processor_->ProcessData(std::move(debug_vmo.test_url), std::move(dump));
}
callback();
}
void DataProcessorFidl::Finish(FinishCallback callback) {
wait_for_completion_.set_object(data_processor_->GetIdleEvent()->get());
wait_for_completion_.set_trigger(IDLE_SIGNAL);
wait_for_completion_.Begin(
dispatcher_, [&, this, callback = std::move(callback)](
async_dispatcher_t* dispatcher, async::WaitOnce* wait, zx_status_t status,
const zx_packet_signal_t* signal) {
callback();
FX_LOGS(INFO) << "finish returned";
TearDown(ZX_ERR_PEER_CLOSED);
});
}
void DataProcessorFidl::TearDown(zx_status_t epitaph) {
binding_.Close(epitaph);
if (on_done_) {
on_done_();
}
}