blob: 755eae64663ca6f59656cebc880ca5e4d6393033 [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 <fuchsia/camera2/hal/cpp/fidl.h>
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/executor.h>
#include <lib/async/cpp/wait.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/cpp/log_settings.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/trace-provider/provider.h>
#include <string>
#include "src/camera/bin/device/device_impl.h"
#include "src/camera/bin/device/metrics_reporter.h"
int main(int argc, char* argv[]) {
syslog::SetLogSettings({.min_log_level = CAMERA_MIN_LOG_LEVEL}, {"camera", "camera_device"});
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
async::Executor executor(loop.dispatcher());
trace::TraceProviderWithFdio trace_provider(loop.dispatcher());
auto context = sys::ComponentContext::Create();
// Verify arguments.
if (argc != 2 || argv[1][0] == '\0') {
FX_PLOGS(FATAL, ZX_ERR_INVALID_ARGS)
<< "Component must be initialized with outgoing service name.";
return EXIT_FAILURE;
}
std::string outgoing_service_name = argv[1];
// Connect to required environment services.
fuchsia::camera2::hal::ControllerHandle controller;
zx_status_t status = context->svc()->Connect(controller.NewRequest());
if (status != ZX_OK) {
FX_PLOGS(FATAL, status) << "Failed to request controller service.";
return EXIT_FAILURE;
}
fuchsia::sysmem::AllocatorHandle allocator;
status = context->svc()->Connect(allocator.NewRequest());
if (status != ZX_OK) {
FX_PLOGS(FATAL, status) << "Failed to request allocator service.";
return EXIT_FAILURE;
}
fuchsia::ui::policy::DeviceListenerRegistryHandle registry;
status = context->svc()->Connect(registry.NewRequest());
if (status != ZX_OK) {
FX_PLOGS(FATAL, status) << "Failed to request registry service.";
return EXIT_FAILURE;
}
// Post a quit task in the event the device enters a bad state.
zx::event event;
FX_CHECK(zx::event::create(0, &event) == ZX_OK);
async::Wait wait(event.get(), ZX_EVENT_SIGNALED, 0,
[&](async_dispatcher_t* dispatcher, async::Wait* wait, zx_status_t status,
const zx_packet_signal_t* signal) {
FX_LOGS(FATAL) << "Device signaled bad state.";
loop.Quit();
});
ZX_ASSERT(wait.Begin(loop.dispatcher()) == ZX_OK);
// Create our metrics reporter.
camera::MetricsReporter metrics(*context);
// Create the device and publish its service.
auto result = camera::DeviceImpl::Create(loop.dispatcher(), executor, std::move(metrics),
std::move(controller), std::move(allocator),
std::move(registry), std::move(event));
std::unique_ptr<camera::DeviceImpl> device;
executor.schedule_task(
result.then([&context, &device, &loop, &outgoing_service_name](
fit::result<std::unique_ptr<camera::DeviceImpl>, zx_status_t>& result) {
if (result.is_error()) {
FX_PLOGS(FATAL, result.error()) << "Failed to create device.";
loop.Quit();
return;
}
device = result.take_value();
// TODO(fxbug.dev/44628): publish discoverable service name once supported
zx_status_t status =
context->outgoing()->AddPublicService(device->GetHandler(), outgoing_service_name);
if (status != ZX_OK) {
FX_PLOGS(FATAL, status) << "Failed to publish service.";
loop.Quit();
return;
}
context->outgoing()->ServeFromStartupInfo();
}));
loop.Run();
return EXIT_SUCCESS;
}