blob: f28b897ed336cac97c621a37e9d4de1420b882ee [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 "src/camera/bin/device_watcher/device_instance.h"
#include <fuchsia/camera2/hal/cpp/fidl.h>
#include <fuchsia/component/cpp/fidl.h>
#include <fuchsia/process/cpp/fidl.h>
#include <lib/sys/service/cpp/service.h>
#include <lib/syslog/cpp/macros.h>
#include <zircon/errors.h>
#include <zircon/processargs.h>
#include "fuchsia/io/cpp/fidl.h"
#include "lib/fit/function.h"
#include "lib/sys/cpp/service_directory.h"
namespace camera {
fpromise::result<std::unique_ptr<DeviceInstance>, zx_status_t> DeviceInstance::Create(
fuchsia::hardware::camera::DeviceHandle camera, const fuchsia::component::RealmPtr& realm,
async_dispatcher_t* dispatcher, const std::string& collection_name,
const std::string& child_name, const std::string& url) {
auto instance = std::make_unique<DeviceInstance>();
instance->dispatcher_ = dispatcher;
instance->name_ = child_name;
instance->collection_name_ = collection_name;
// Launch the child device.
fuchsia::component::decl::CollectionRef collection;
collection.name = collection_name;
fuchsia::component::decl::Child child;
child.set_name(child_name);
child.set_url(url);
child.set_startup(fuchsia::component::decl::StartupMode::LAZY);
fuchsia::component::CreateChildArgs args;
// Pass the camera DeviceHandle to the child so the child can communicate with the correct
// instance.
fuchsia::process::HandleInfo handle_info;
auto channel = camera.TakeChannel();
zx::handle handle(channel.release());
ZX_ASSERT(handle.is_valid());
handle_info.handle = std::move(handle);
handle_info.id = PA_HND(PA_USER0, 0);
std::vector<fuchsia::process::HandleInfo> numbered_handles;
numbered_handles.push_back(std::move(handle_info));
args.set_numbered_handles(std::move(numbered_handles));
fuchsia::component::Realm::CreateChildCallback cb =
[child_name](fuchsia::component::Realm_CreateChild_Result result) {
if (result.is_err()) {
FX_LOGS(ERROR) << "Failed to create camera device child. Result: "
<< static_cast<long>(result.err());
ZX_ASSERT(false); // Should never happen.
}
FX_LOGS(INFO) << "Created camera device child: " << child_name;
};
realm->CreateChild(std::move(collection), std::move(child), std::move(args), std::move(cb));
// TODO(b/244178394) - Need to have handlers/callbacks for child component exits or crashes.
return fpromise::ok(std::move(instance));
}
} // namespace camera