blob: 316906e32c7508df40dd05e928d0c806c1d994d7 [file]
// 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.
#ifndef SRC_DEVICES_BIN_DRIVER_MANAGER_REBOOT_WATCHER_MANAGER_H_
#define SRC_DEVICES_BIN_DRIVER_MANAGER_REBOOT_WATCHER_MANAGER_H_
#include <fuchsia/hardware/power/statecontrol/llcpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/zx/channel.h>
#include <optional>
// TODO(fxb/52901): Delete this once power_manager serves |RebootMethodsWatcherRegister|.
class RebootWatcherManager : public llcpp::fuchsia::hardware::power::statecontrol::
RebootMethodsWatcherRegister::Interface {
public:
RebootWatcherManager(async_dispatcher_t* dispatcher);
// RebootWatcherRegister interface
void Register(zx::channel watcher,
llcpp::fuchsia::hardware::power::statecontrol::RebootMethodsWatcherRegister::
Interface::RegisterCompleter::Sync _completer) override;
// Sets the reboot reason. If the reason has already been set, this function does nothing.
void SetRebootReason(llcpp::fuchsia::hardware::power::statecontrol::RebootReason reason);
size_t NumWatchers() const;
// Returns true if |RebootWatcherManager| has at least 1 bound watcher and |reason_| is
// set.
bool ShouldNotifyWatchers() const;
// Notify all of the watchers of the current suspend request. Execute |watchdog| and close all
// open channels if all of the watchers fail to respond or excute |on_last_reply| when the last
// watcher has responded, whichever occurs first.
void NotifyAll(
fit::closure watchdog, fit::closure on_last_reply = [] {});
// If |watchdog_task_| is still pending, cancel it post it to execute immediately.
void ExecuteWatchdog();
bool HasRebootReason() const { return reason_.has_value(); }
void ClearRebootReason() { reason_ = std::nullopt; }
private:
void UnbindWatcher(size_t idx);
struct Watcher {
fidl::Client<llcpp::fuchsia::hardware::power::statecontrol::RebootMethodsWatcher> client;
// Track if the client is bound to avoid sending messages to unbound |RebootMethodsWatchers|.
bool client_is_bound;
};
async_dispatcher_t* dispatcher_;
std::optional<llcpp::fuchsia::hardware::power::statecontrol::RebootReason> reason_;
std::vector<Watcher> watchers_;
size_t num_bound_watchers_ = 0;
std::unique_ptr<async::TaskClosure> watchdog_task_;
};
#endif // SRC_DEVICES_BIN_DRIVER_MANAGER_REBOOT_WATCHER_MANAGER_H_