// Copyright 2019 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_DRIVER_MANAGER_DEVICE_H_
#define SRC_DEVICES_DRIVER_MANAGER_DEVICE_H_

#include <fuchsia/device/manager/c/fidl.h>
#include <fuchsia/device/manager/cpp/fidl.h>
#include <fuchsia/device/manager/llcpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/async/cpp/wait.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>

#include <memory>
#include <variant>

#include <ddk/device.h>
#include <fbl/array.h>
#include <fbl/auto_lock.h>
#include <fbl/mutex.h>
#include <fbl/ref_counted.h>
#include <fbl/string.h>

#include "async-loop-ref-counted-rpc-handler.h"
#include "composite-device.h"
#include "driver-test-reporter.h"
#include "metadata.h"

namespace devmgr {

class Coordinator;
class Devhost;
struct Devnode;
class InitTask;
class RemoveTask;
class SuspendContext;
class SuspendTask;
class ResumeTask;
class UnbindTask;
struct UnbindTaskOpts;

// clang-format off

// This device is never destroyed
#define DEV_CTX_IMMORTAL           0x01

// This device requires that children are created in a
// new devhost attached to a proxy device
#define DEV_CTX_MUST_ISOLATE       0x02

// This device may be bound multiple times
#define DEV_CTX_MULTI_BIND         0x04

// This device is bound and not eligible for binding
// again until unbound.  Not allowed on MULTI_BIND ctx.
#define DEV_CTX_BOUND              0x08

// Device has been remove()'d
#define DEV_CTX_DEAD               0x10

// This device is a component of a composite device and
// can be part of multiple composite devices.
#define DEV_CTX_ALLOW_MULTI_COMPOSITE    0x20

// Device is a proxy -- its "parent" is the device it's
// a proxy to.
#define DEV_CTX_PROXY              0x40

// Device is not visible in devfs or bindable.
// Devices may be created in this state, but may not
// return to this state once made visible.
#define DEV_CTX_INVISIBLE          0x80

// Signals used on the test event
#define TEST_BIND_DONE_SIGNAL ZX_USER_SIGNAL_0
#define TEST_SUSPEND_DONE_SIGNAL ZX_USER_SIGNAL_1
#define TEST_RESUME_DONE_SIGNAL ZX_USER_SIGNAL_2
#define TEST_REMOVE_DONE_SIGNAL ZX_USER_SIGNAL_3

constexpr zx::duration kDefaultTestTimeout = zx::sec(5);

// clang-format on

class Device : public fbl::RefCounted<Device>,
               public llcpp::fuchsia::device::manager::Coordinator::Interface,
               public AsyncLoopRefCountedRpcHandler<Device> {
 public:
  void AddDevice(::zx::channel coordinator, ::zx::channel device_controller,
                 ::fidl::VectorView<uint64_t> props, ::fidl::StringView name, uint32_t protocol_id,
                 ::fidl::StringView driver_path, ::fidl::StringView args,
                 llcpp::fuchsia::device::manager::AddDeviceConfig device_add_config, bool has_init,
                 ::zx::channel client_remote, AddDeviceCompleter::Sync _completer) override;
  void ScheduleRemove(bool unbind_self, ScheduleRemoveCompleter::Sync _completer) override;
  void AddCompositeDevice(::fidl::StringView name,
                          llcpp::fuchsia::device::manager::CompositeDeviceDescriptor comp_desc,
                          AddCompositeDeviceCompleter::Sync _completer) override;
  void PublishMetadata(::fidl::StringView device_path, uint32_t key,
                       ::fidl::VectorView<uint8_t> data,
                       PublishMetadataCompleter::Sync _completer) override;
  void AddDeviceInvisible(::zx::channel coordinator, ::zx::channel device_controller,
                          ::fidl::VectorView<uint64_t> props, ::fidl::StringView name,
                          uint32_t protocol_id, ::fidl::StringView driver_path,
                          ::fidl::StringView args, bool has_init, ::zx::channel client_remote,
                          AddDeviceInvisibleCompleter::Sync _completer) override;
  void MakeVisible(MakeVisibleCompleter::Sync _completer) override;
  void BindDevice(::fidl::StringView driver_path, BindDeviceCompleter::Sync _completer) override;
  void GetTopologicalPath(GetTopologicalPathCompleter::Sync _completer) override;
  void LoadFirmware(::fidl::StringView fw_path, LoadFirmwareCompleter::Sync _completer) override;
  void GetMetadata(uint32_t key, GetMetadataCompleter::Sync _completer) override;
  void GetMetadataSize(uint32_t key, GetMetadataSizeCompleter::Sync _completer) override;
  void AddMetadata(uint32_t key, ::fidl::VectorView<uint8_t> data,
                   AddMetadataCompleter::Sync _completer) override;
  void ScheduleUnbindChildren(ScheduleUnbindChildrenCompleter::Sync _completer) override;
  void RunCompatibilityTests(int64_t hook_wait_time,
                             RunCompatibilityTestsCompleter::Sync _completer) override;
  void DirectoryWatch(uint32_t mask, uint32_t options, ::zx::channel watcher,
                      DirectoryWatchCompleter::Sync _completer) override;

  // Node for entry in device child list
  struct Node {
    static fbl::DoublyLinkedListNodeState<Device*>& node_state(Device& obj) { return obj.node_; }
  };

  struct DevhostNode {
    static fbl::DoublyLinkedListNodeState<Device*>& node_state(Device& obj) {
      return obj.devhost_node_;
    }
  };

  struct AllDevicesNode {
    static fbl::DoublyLinkedListNodeState<Device*>& node_state(Device& obj) {
      return obj.all_devices_node_;
    }
  };

  // This iterator provides access to a list of devices that does not provide
  // mechanisms for mutating that list.  With this, a user can get mutable
  // access to a device in the list.  This is achieved by making the linked
  // list iterator opaque. It is not safe to modify the underlying list while
  // this iterator is in use.
  template <typename IterType, typename DeviceType>
  class ChildListIterator {
   public:
    ChildListIterator() : state_(Done{}) {}
    explicit ChildListIterator(DeviceType* device)
        : state_(device->children_.begin()), device_(device) {
      SkipInvalidStates();
    }
    ChildListIterator operator++(int) {
      auto other = *this;
      ++*this;
      return other;
    }
    bool operator==(const ChildListIterator& other) const { return state_ == other.state_; }
    bool operator!=(const ChildListIterator& other) const { return !(state_ == other.state_); }

    // The iterator implementation for the child list.  This is the source of truth
    // for what devices are children of the device.
    ChildListIterator& operator++() {
      std::visit(
          [this](auto&& arg) {
            using T = std::decay_t<decltype(arg)>;
            if constexpr (std::is_same_v<T, IterType>) {
              ++arg;
            } else if constexpr (std::is_same_v<T, Composite>) {
              ++arg;
            } else if constexpr (std::is_same_v<T, Done>) {
              state_ = Done{};
            }
          },
          state_);
      SkipInvalidStates();
      return *this;
    }

    DeviceType& operator*() const {
      return std::visit(
          [](auto&& arg) -> DeviceType& {
            using T = std::decay_t<decltype(arg)>;
            if constexpr (std::is_same_v<T, IterType>) {
              return *arg;
            } else if constexpr (std::is_same_v<T, Composite>) {
              return *(arg->composite()->device());
            } else {
              __builtin_trap();
            }
          },
          state_);
    }

   private:
    // Advance the iterator to the next valid state or reach the done state.
    // This is used to handle advancement between the different state variants.
    void SkipInvalidStates() {
      bool more = true;
      while (more) {
        more = std::visit(
            [this](auto&& arg) {
              using T = std::decay_t<decltype(arg)>;
              if constexpr (std::is_same_v<T, IterType>) {
                // Check if there are any more children in the list.  If
                // there are, we're in a valid state and can stop.
                // Otherwise, advance to the next variant and check if
                // it's a valid state.
                if (arg != device_->children_.end()) {
                  return false;
                }
                // If there are no more children, run through the Composite
                // state next.
                if (device_->parent_) {
                  state_ = Composite{device_->parent_->components().begin()};
                } else {
                  state_ = Composite{};
                }
                return true;
              } else if constexpr (std::is_same_v<T, Composite>) {
                // Check if this device is an internal component device
                // that bound to a composite component.  If it is, and
                // the composite has been constructed, the iterator
                // should yield the composite.
                if (device_->parent_) {
                  if (arg != device_->parent_->components().end() &&
                      arg->composite()->device() != nullptr) {
                    return false;
                  }
                }
                state_ = Done{};
                return false;
              } else if constexpr (std::is_same_v<T, Done>) {
                return false;
              }
            },
            state_);
      }
    }

    using Composite = fbl::DoublyLinkedList<CompositeDeviceComponent*,
                                            CompositeDeviceComponent::DeviceNode>::iterator;
    struct Done {
      bool operator==(Done) const { return true; }
    };
    std::variant<IterType, Composite, Done> state_;
    DeviceType* device_;
  };

  // This class exists to allow consumers of the Device class to write
  //   for (auto& child : dev->children())
  // and get mutable access to the children without getting mutable access to
  // the list.
  template <typename DeviceType, typename IterType>
  class ChildListIteratorFactory {
   public:
    explicit ChildListIteratorFactory(DeviceType* device) : device_(device) {}

    IterType begin() const { return IterType(device_); }
    IterType end() const { return IterType(); }

    bool is_empty() const { return begin() == end(); }

   private:
    DeviceType* device_;
  };

  Device(Coordinator* coord, fbl::String name, fbl::String libname, fbl::String args,
         fbl::RefPtr<Device> parent, uint32_t protocol_id, zx::channel client_remote,
         bool wait_make_visible = false);
  ~Device();

  // Create a new device with the given parameters.  This sets up its
  // relationship with its parent and devhost and adds its RPC channel to the
  // coordinator's async loop.  This does not add the device to the
  // coordinator's devices_ list, or trigger publishing
  static zx_status_t Create(Coordinator* coordinator, const fbl::RefPtr<Device>& parent,
                            fbl::String name, fbl::String driver_path, fbl::String args,
                            uint32_t protocol_id, fbl::Array<zx_device_prop_t> props,
                            zx::channel coordinator_rpc, zx::channel device_controller_rpc,
                            bool wait_make_visible, bool want_init_task, zx::channel client_remote,
                            fbl::RefPtr<Device>* device);
  static zx_status_t CreateComposite(Coordinator* coordinator, Devhost* devhost,
                                     const CompositeDevice& composite, zx::channel coordinator_rpc,
                                     zx::channel device_controller_rpc,
                                     fbl::RefPtr<Device>* device);
  zx_status_t CreateProxy();

  static void HandleRpc(fbl::RefPtr<Device>&& dev, async_dispatcher_t* dispatcher,
                        async::WaitBase* wait, zx_status_t status,
                        const zx_packet_signal_t* signal);

  // We do not want to expose the list itself for mutation, even if the
  // children are allowed to be mutated.  We manage this by making the
  // iterator opaque.
  using NonConstChildListIterator =
      ChildListIterator<fbl::DoublyLinkedList<Device*, Node>::iterator, Device>;
  using ConstChildListIterator =
      ChildListIterator<fbl::DoublyLinkedList<Device*, Node>::const_iterator, const Device>;
  using NonConstChildListIteratorFactory =
      ChildListIteratorFactory<Device, NonConstChildListIterator>;
  using ConstChildListIteratorFactory =
      ChildListIteratorFactory<const Device, ConstChildListIterator>;
  NonConstChildListIteratorFactory children() { return NonConstChildListIteratorFactory(this); }
  ConstChildListIteratorFactory children() const { return ConstChildListIteratorFactory(this); }

  // Signal that this device is ready for bind to happen.  This should happen
  // either immediately after the device is created, if it's created visible,
  // or after it becomes visible.
  zx_status_t SignalReadyForBind(zx::duration delay = zx::sec(0));

  using InitCompletion = fit::callback<void(zx_status_t)>;
  // Issue an Init request to this device.  When the response comes in, the
  // given completion will be invoked.
  zx_status_t SendInit(InitCompletion completion);

  using SuspendCompletion = fit::callback<void(zx_status_t)>;
  // Issue a Suspend request to this device.  When the response comes in, the
  // given completion will be invoked.
  zx_status_t SendSuspend(uint32_t flags, SuspendCompletion completion);

  using ResumeCompletion = fit::callback<void(zx_status_t)>;
  // Issue a Resume request to this device.  When the response comes in, the
  // given completion will be invoked.
  zx_status_t SendResume(uint32_t target_system_state, ResumeCompletion completion);

  using UnbindCompletion = fit::callback<void(zx_status_t)>;
  using RemoveCompletion = fit::callback<void(zx_status_t)>;
  // Issue an Unbind request to this device, which will run the unbind hook.
  // When the response comes in, the given completion will be invoked.
  zx_status_t SendUnbind(UnbindCompletion completion);
  // Issue a CompleteRemoval request to this device.
  // When the response comes in, the given completion will be invoked.
  zx_status_t SendCompleteRemoval(RemoveCompletion completion);

  // Break the relationship between this device object and its parent
  void DetachFromParent();

  // Sets the properties of this device.  Returns an error if the properties
  // array contains more than one property from the BIND_TOPO_* range.
  zx_status_t SetProps(fbl::Array<const zx_device_prop_t> props);
  const fbl::Array<const zx_device_prop_t>& props() const { return props_; }
  const zx_device_prop_t* topo_prop() const { return topo_prop_; }

  const fbl::RefPtr<Device>& parent() { return parent_; }
  fbl::RefPtr<const Device> parent() const { return parent_; }

  const fbl::RefPtr<Device>& proxy() { return proxy_; }
  fbl::RefPtr<const Device> proxy() const { return proxy_; }

  uint32_t protocol_id() const { return protocol_id_; }

  bool is_bindable() const {
    return !(flags & (DEV_CTX_BOUND | DEV_CTX_INVISIBLE)) && (state_ != Device::State::kDead);
  }

  bool is_visible() const { return !(flags & DEV_CTX_INVISIBLE); }

  bool is_composite_bindable() const {
    if (flags & (DEV_CTX_DEAD | DEV_CTX_INVISIBLE)) {
      return false;
    }
    if ((flags & DEV_CTX_BOUND) && !(flags & DEV_CTX_ALLOW_MULTI_COMPOSITE)) {
      return false;
    }
    return true;
  }

  void push_component(CompositeDeviceComponent* component) { components_.push_back(component); }
  bool is_components_empty() { return components_.is_empty(); }

  fbl::DoublyLinkedList<CompositeDeviceComponent*, CompositeDeviceComponent::DeviceNode>&
  components() {
    return components_;
  }
  // If the device was created as a composite, this returns its description.
  CompositeDevice* composite() const {
    auto val = std::get_if<CompositeDevice*>(&composite_);
    return val ? *val : nullptr;
  }
  void set_composite(CompositeDevice* composite) {
    ZX_ASSERT(std::holds_alternative<UnassociatedWithComposite>(composite_));
    composite_ = composite;
  }
  void disassociate_from_composite() { composite_ = UnassociatedWithComposite{}; }

  void set_host(Devhost* host);
  Devhost* host() const { return host_; }
  uint64_t local_id() const { return local_id_; }

  const fbl::DoublyLinkedList<std::unique_ptr<Metadata>, Metadata::Node>& metadata() const {
    return metadata_;
  }
  void AddMetadata(std::unique_ptr<Metadata> md) { metadata_.push_front(std::move(md)); }

  // Creates the init task for the device.
  void CreateInitTask();
  // Returns the in-progress init task if it exists, nullptr otherwise.
  fbl::RefPtr<InitTask> GetActiveInit() { return active_init_; }

  // Run the completion for the outstanding init, if any.
  zx_status_t CompleteInit(zx_status_t status);

  // Returns the in-progress suspend task if it exists, nullptr otherwise.
  fbl::RefPtr<SuspendTask> GetActiveSuspend() { return active_suspend_; }
  // Creates a new suspend task if necessary and returns a reference to it.
  // If one is already in-progress, a reference to it is returned instead
  fbl::RefPtr<SuspendTask> RequestSuspendTask(uint32_t suspend_flags);

  fbl::RefPtr<ResumeTask> GetActiveResume() { return active_resume_; }
  void SetActiveResume(fbl::RefPtr<ResumeTask> resume_task) { active_resume_ = resume_task; }

  // Request Resume task
  fbl::RefPtr<ResumeTask> RequestResumeTask(uint32_t system_resume_state);

  // Run the completion for the outstanding suspend, if any.  This method is
  // only exposed currently because RemoveDevice is on Coordinator instead of
  // Device.
  void CompleteSuspend(zx_status_t status);

  // Run the completion for the outstanding resume, if any.
  void CompleteResume(zx_status_t status);

  // Creates the unbind and remove tasks for the device if they do not already exist.
  // |opts| is used to configure the unbind task.
  void CreateUnbindRemoveTasks(UnbindTaskOpts opts);

  // Returns the in-progress unbind task if it exists, nullptr otherwise.
  // Unbind tasks are used to facilitate |Unbind| requests.
  fbl::RefPtr<UnbindTask> GetActiveUnbind() { return active_unbind_; }
  // Returns the in-progress remove task if it exists, nullptr otherwise.
  // Remove tasks are used to facilitate |CompleteRemoval| requests.
  fbl::RefPtr<RemoveTask> GetActiveRemove() { return active_remove_; }

  // Run the completion for the outstanding unbind, if any.
  zx_status_t CompleteUnbind(zx_status_t status = ZX_OK);
  // Run the completion for the outstanding remove, if any.
  zx_status_t CompleteRemove(zx_status_t status = ZX_OK);

  // Drops the reference to the task.
  // This should be called if the device will not send an init, unbind or remove request.
  void DropInitTask() { active_init_ = nullptr; }
  void DropUnbindTask() { active_unbind_ = nullptr; }
  void DropRemoveTask() { active_remove_ = nullptr; }

  zx_status_t DriverCompatibiltyTest();

  zx::channel take_client_remote() { return std::move(client_remote_); }

  const fbl::String& name() const { return name_; }
  const fbl::String& libname() const { return libname_; }
  const fbl::String& args() const { return args_; }

  Coordinator* coordinator;
  uint32_t flags = 0;

  // The backoff between each driver retry. This grows exponentially.
  zx::duration backoff = zx::msec(250);
  // The number of retries left for the driver.
  uint32_t retries = 4;
  Devnode* self = nullptr;
  Devnode* link = nullptr;

  // TODO(teisenbe): We probably want more states.
  enum class State {
    kActive,
    kInitializing,  // The devhost is in the process of running the device init hook.
    kSuspending,    // The devhost is in the process of suspending the device.
    kSuspended,
    kResuming,   // The devhost is in the process of resuming the device.
    kResumed,    // Resume is complete. Will be marked active, after all children resume.
    kUnbinding,  // The devhost is in the process of unbinding and removing the device.
    kDead,       // The device has been remove()'d
  };

  void set_state(Device::State state) { state_ = state; }
  State state() const { return state_; }

  void clear_wait_make_visible() { wait_make_visible_ = false; }
  bool wait_make_visible() const { return wait_make_visible_; }

  void inc_num_removal_attempts() { num_removal_attempts_++; }
  size_t num_removal_attempts() const { return num_removal_attempts_; }

  enum class TestStateMachine {
    kTestNotStarted = 1,
    kTestUnbindSent,
    kTestBindSent,
    kTestBindDone,
    kTestSuspendSent,
    kTestSuspendDone,
    kTestResumeSent,
    kTestResumeDone,
    kTestDone,
  };

  TestStateMachine test_state() {
    fbl::AutoLock<fbl::Mutex> lock(&test_state_lock_);
    return test_state_;
  }

  void set_test_state(TestStateMachine new_state) {
    fbl::AutoLock<fbl::Mutex> lock(&test_state_lock_);
    test_state_ = new_state;
  }

  void clear_active_resume() { active_resume_ = nullptr; }
  void set_test_time(zx::duration& test_time) { test_time_ = test_time; }
  void set_test_reply_required(bool required) { test_reply_required_ = required; }
  zx::duration& test_time() { return test_time_; }
  const char* GetTestDriverName();
  zx::event& test_event() { return test_event_; }

  // This is public for testing purposes.
  std::unique_ptr<DriverTestReporter> test_reporter;

  zx_status_t set_test_output(zx::channel test_output, async_dispatcher_t* dispatcher) {
    test_output_ = std::move(test_output);
    test_wait_.set_object(test_output_.get());
    test_wait_.set_trigger(ZX_CHANNEL_PEER_CLOSED);
    return test_wait_.Begin(dispatcher);
  }

  const fidl::InterfacePtr<fuchsia::device::manager::DeviceController>& device_controller() const {
    return device_controller_;
  }

  const fidl::InterfaceRequest<fuchsia::device::manager::DeviceController> ConnectDeviceController(
      async_dispatcher_t* dispatcher) {
    return device_controller_.NewRequest(dispatcher);
  }

 private:
  void HandleTestOutput(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                        const zx_packet_signal_t* signal);

  // The driver sends output from run_unit_tests over this channel.
  zx::channel test_output_;

  // Async waiter that drives the consumption of test_output_. It is triggered when the channel is
  // closed by the driver, signalling the end of the tests. We don't print log messages until the
  // entire test is finished to avoid interleaving output from multiple drivers.
  async::WaitMethod<Device, &Device::HandleTestOutput> test_wait_{this};

  fidl::InterfacePtr<fuchsia::device::manager::DeviceController> device_controller_;

  zx_status_t HandleRead();
  int RunCompatibilityTests();

  const fbl::String name_;
  const fbl::String libname_;
  const fbl::String args_;

  fbl::RefPtr<Device> parent_;
  const uint32_t protocol_id_;

  fbl::RefPtr<Device> proxy_;

  fbl::Array<const zx_device_prop_t> props_;
  // If the device has a topological property in |props|, this points to it.
  const zx_device_prop_t* topo_prop_ = nullptr;

  async::TaskClosure publish_task_;

  // listnode for this device in its parent's list-of-children
  fbl::DoublyLinkedListNodeState<Device*> node_;

  // List of all child devices of this device, except for composite devices.
  // Composite devices are excluded because their multiple-parent nature
  // precludes using the same intrusive nodes as single-parent devices.
  fbl::DoublyLinkedList<Device*, Node> children_;

  // Metadata entries associated to this device.
  fbl::DoublyLinkedList<std::unique_ptr<Metadata>, Metadata::Node> metadata_;

  // listnode for this device in the all devices list
  fbl::DoublyLinkedListNodeState<Device*> all_devices_node_;

  // listnode for this device in its devhost's list-of-devices
  fbl::DoublyLinkedListNodeState<Device*> devhost_node_;

  // list of all components that this device bound to.
  fbl::DoublyLinkedList<CompositeDeviceComponent*, CompositeDeviceComponent::DeviceNode>
      components_;

  // - If this device is part of a composite device, this is inhabited by
  //   CompositeDeviceComponent* and it points to the component that matched it.
  //   Note that this is only set on the device that matched the component, not
  //   the "component device" added by the component driver.
  // - If this device is a composite device, this is inhabited by
  //   CompositeDevice* and it points to the composite that describes it.
  // - Otherwise, it is inhabited by UnassociatedWithComposite
  struct UnassociatedWithComposite {};
  std::variant<UnassociatedWithComposite, CompositeDevice*> composite_;

  Devhost* host_ = nullptr;
  // The id of this device from the perspective of the devhost.  This can be
  // used to communicate with the devhost about this device.
  uint64_t local_id_ = 0;

  // The current state of the device
  State state_ = State::kActive;

  // If an init is in-progress, this task represents it.
  fbl::RefPtr<InitTask> active_init_;
  // If an init is in-progress, this completion will be invoked when it is
  // completed.  It will likely mark |active_init_| as completed and clear it.
  InitCompletion init_completion_;

  // If a suspend is in-progress, this task represents it.
  fbl::RefPtr<SuspendTask> active_suspend_;
  // If a suspend is in-progress, this completion will be invoked when it is
  // completed.  It will likely mark |active_suspend_| as completed and clear
  // it.
  SuspendCompletion suspend_completion_;

  // If a resume is in-progress, this task represents it.
  fbl::RefPtr<ResumeTask> active_resume_;
  // If a Resume is in-progress, this completion will be invoked when it is
  // completed.
  ResumeCompletion resume_completion_;

  // If an unbind is in-progress, this task represents it.
  fbl::RefPtr<UnbindTask> active_unbind_;
  // If an unbind is in-progress, this completion will be invoked when it is
  // completed. It will likely mark |active_unbind_| as completed and clear
  // it.
  UnbindCompletion unbind_completion_;

  // If a remove is in-progress, this task represents it.
  fbl::RefPtr<RemoveTask> active_remove_;
  // If a remove is in-progress, this completion will be invoked when it is
  // completed. It will likely mark |active_remove_| as completed and clear
  // it.
  RemoveCompletion remove_completion_;

  // For attaching as an open connection to the proxy device,
  // or once the device becomes visible.
  zx::channel client_remote_;

  // If true, we should only make the device visible after DdkMakeVisible is called
  // (and after the init task has completed).
  bool wait_make_visible_ = false;

  // For compatibility tests.
  fbl::Mutex test_state_lock_;
  TestStateMachine test_state_ __TA_GUARDED(test_state_lock_) = TestStateMachine::kTestNotStarted;
  zx::event test_event_;
  zx::duration test_time_;
  fuchsia_device_manager_CompatibilityTestStatus test_status_;
  bool test_reply_required_ = false;

  // This lets us check for unexpected removals and is for testing use only.
  size_t num_removal_attempts_ = 0;
};

}  // namespace devmgr

#endif  // SRC_DEVICES_DRIVER_MANAGER_DEVICE_H_
