| // Copyright 2024 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef HEARTD_DAEMON_HEARTBEAT_TRACKER_H_ | |
| #define HEARTD_DAEMON_HEARTBEAT_TRACKER_H_ | |
| #include <memory> | |
| #include <vector> | |
| #include <base/time/time.h> | |
| #include <mojo/public/cpp/bindings/pending_receiver.h> | |
| #include <mojo/public/cpp/bindings/receiver.h> | |
| #include "heartd/mojom/heartd.mojom.h" | |
| namespace heartd { | |
| constexpr base::TimeDelta kMinVerificationWindow = base::Seconds(70); | |
| class HeartbeatTracker : public ash::heartd::mojom::Pacemaker { | |
| public: | |
| explicit HeartbeatTracker( | |
| ash::heartd::mojom::ServiceName name, | |
| mojo::PendingReceiver<ash::heartd::mojom::Pacemaker> receiver); | |
| HeartbeatTracker(const HeartbeatTracker&) = delete; | |
| HeartbeatTracker& operator=(const HeartbeatTracker&) = delete; | |
| ~HeartbeatTracker(); | |
| // ash::heartd::mojom::Pacemaker overrides: | |
| void SendHeartbeat(SendHeartbeatCallback callback) override; | |
| void StopMonitor(StopMonitorCallback callback) override; | |
| // Returns if pacemaker receiver is bound or not. We use this to check if it's | |
| // a repeated registration. | |
| bool IsPacemakerBound(); | |
| // Returns if we should stop monitor or not. | |
| bool IsStopMonitor(); | |
| // Rebind pacemaker receiver. This can be called when |IsPacemakerBound()| | |
| // returns false. | |
| void RebindPacemaker( | |
| mojo::PendingReceiver<ash::heartd::mojom::Pacemaker> receiver); | |
| // Set up the service argument. | |
| void SetupArgument(ash::heartd::mojom::HeartbeatServiceArgumentPtr argument); | |
| // Returns the number of heartbeat verification failure. It'll be reset to | |
| // zero every time when receiving a heartbeat. | |
| uint8_t GetFailureCount(); | |
| // Returns the time to wait for pings before we declare one failure. | |
| base::TimeDelta GetVerificationWindow(); | |
| // Verifies if the time gap between the |current_time| and the | |
| // |last_touch_time_| is within the |verification_window_|. | |
| bool VerifyTimeGap(const base::Time& current_time); | |
| void SetLastDryRunResponse(ash::heartd::mojom::HeartbeatResponse response); | |
| // Returns the actions that need to be taken at current |failure_count_|. | |
| std::vector<ash::heartd::mojom::ActionType> GetFailureCountActions(); | |
| // Returns all valid actions to be executed | |
| std::vector<ash::heartd::mojom::ActionType> GetActions(); | |
| private: | |
| // Handler when pacemaker mojo disconnects. | |
| void OnPacemakerDisconnect(); | |
| private: | |
| // Service name. | |
| ash::heartd::mojom::ServiceName name_; | |
| // Pacemaker receiver. | |
| mojo::Receiver<ash::heartd::mojom::Pacemaker> receiver_; | |
| // Once this is set to true, the whole HeartbeatTracker instance will be | |
| // cleaned up by HeartbeatManager. | |
| bool stop_monitor_ = false; | |
| // Number of consecutive heartbeat verification failure. | |
| uint8_t failure_count_ = 0; | |
| // The time when receiving the last heartbeat. | |
| base::Time last_touch_time_; | |
| // What was the response of last dryrun from action to return back when asked. | |
| ::ash::heartd::mojom::HeartbeatResponse last_dryrun_response_; | |
| // For every verification, we check if there is at least one heartbeat in the | |
| // past |verification_window_seconds|. The minimum value of this is 70. | |
| base::TimeDelta verification_window_ = kMinVerificationWindow; | |
| // |actions_| describes what action to be taken for a specific failure count. | |
| std::vector<ash::heartd::mojom::ActionPtr> actions_; | |
| }; | |
| } // namespace heartd | |
| #endif // HEARTD_DAEMON_HEARTBEAT_TRACKER_H_ |