blob: 10a789f5566efcb162a219f19a7274dda07091fc [file] [log] [blame]
// Copyright 2022 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_DEVICES_BIN_DRIVER_MANAGER_COMPOSITE_NODE_SPEC_COMPOSITE_NODE_SPEC_H_
#define SRC_DEVICES_BIN_DRIVER_MANAGER_COMPOSITE_NODE_SPEC_COMPOSITE_NODE_SPEC_H_
#include <fidl/fuchsia.driver.development/cpp/wire.h>
#include <fidl/fuchsia.driver.index/cpp/fidl.h>
struct DeviceV1Wrapper;
namespace driver_manager {
class Node;
using DeviceOrNode =
std::variant<std::weak_ptr<DeviceV1Wrapper>, std::weak_ptr<driver_manager::Node>>;
using RemoveCompositeNodeCallback = fit::callback<void(zx::result<>)>;
struct CompositeNodeSpecCreateInfo {
std::string name;
std::vector<fuchsia_driver_framework::ParentSpec> parents;
};
// This partially abstract class represents a composite node spec and is responsible for managing
// its state and composite node. The CompositeNodeSpec class will manage the state of its bound
// nodes while its subclasses manage the composite node under the spec. There should be a subclass
// for DFv1 and DFv2.
class CompositeNodeSpec {
public:
explicit CompositeNodeSpec(CompositeNodeSpecCreateInfo create_info);
virtual ~CompositeNodeSpec() = default;
// Called when CompositeNodeManager receives a MatchedNodeRepresentation.
// Returns ZX_ERR_ALREADY_BOUND if it's already bound. See BindParentImpl() for return type
// details.
zx::result<std::optional<DeviceOrNode>> BindParent(
fuchsia_driver_framework::wire::CompositeParent composite_parent,
const DeviceOrNode& device_or_node);
virtual fuchsia_driver_development::wire::CompositeNodeInfo GetCompositeInfo(
fidl::AnyArena& arena) const = 0;
// Remove the underlying composite node and unmatch all of its parents. Called for
// rebind.
void Remove(RemoveCompositeNodeCallback callback);
const std::vector<fuchsia_driver_framework::ParentSpec>& parent_specs() const {
return parent_specs_;
}
// Exposed for testing.
const std::vector<std::optional<DeviceOrNode>>& parent_nodes() const { return parent_nodes_; }
const std::string& name() const { return name_; }
protected:
// Subclass implementation for binding the DeviceOrNode to its composite. If the composite is not
// yet created, the implementation is expected to create one with |info|. In DFv1, it returns
// std::nullopt. In DFv2, if the composite is complete, it returns a pointer to the new node.
// Otherwise, it returns std::nullopt. The lifetime of this node object is managed by
// the parent nodes.
virtual zx::result<std::optional<DeviceOrNode>> BindParentImpl(
fuchsia_driver_framework::wire::CompositeParent composite_parent,
const DeviceOrNode& device_or_node) = 0;
// Subclass implementation for Remove(). Subclasses are expected to remove the underlying
// composite node and unmatch all of the parents from it.
virtual void RemoveImpl(RemoveCompositeNodeCallback callback) = 0;
size_t size() const { return parent_nodes_.size(); }
private:
std::string name_;
std::vector<std::optional<DeviceOrNode>> parent_nodes_;
std::vector<fuchsia_driver_framework::ParentSpec> parent_specs_;
};
} // namespace driver_manager
#endif // SRC_DEVICES_BIN_DRIVER_MANAGER_COMPOSITE_NODE_SPEC_COMPOSITE_NODE_SPEC_H_