chromium/chromeos/ash/services/heartd/public/mojom/heartd.mojom

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module ash.heartd.mojom;

// Control interface exposed by heartd. Chrome can use this interface to control
// the behavior of heartd.
//
// NextMinVersion: 0, NextIndex: 3
interface HeartdControl {
  // Enable the heartd daemon to perform normal reboot action, this asks the
  // powerd to reboot the device through D-Bus.
  EnableNormalRebootAction@0();
  // Enable the heartd daemon to perform force reboot action, this is done by
  // using /proc/sysrq-trigger.
  EnableForceRebootAction@1();
  // Execute action immediately.
  RunAction@2(ActionType action) => (bool success);
};

// Heartbeat service interface exposed by heartd. Clients can use this interface
// to register the service and send heartbeat to heartd.
//
// NextMinVersion: 0, NextIndex: 1
interface HeartbeatService {
  // Each ServiceName can only register one heartbeat service. We reject second
  // registration by dropping the `Pacemaker` mojo connection directly.
  // After registration, heartd starts to verify the heartbeat consistency. So
  // clients are expected to send heartbeat once registered. If the mojo
  // connection of `Pacemaker` is dropped by the clients before calling
  // `StopMonitor`, we assume that something bad happens and will treat it as
  // one missing heartbeat when verification.
  Register@0(
    ServiceName name,
    HeartbeatServiceArgument argument,
    pending_receiver<Pacemaker> receiver) => (bool success);
};

struct HeartbeatServiceArgument {
  // The actions to be taken when the heartbeat is missing.
  array<Action> actions@0;
  // For every verification, we check if there is at least one heartbeat in the
  // past `verification_window_seconds`. It's recommended to set it to a little
  // larger than the heartbeat rate. The minimum value of this is 70 (The min
  // heartbeat rate is 60s + buffer time 10s). Client is better to consider the
  // buffer time since their process may not be real time or high priority.
  uint32 verification_window_seconds@1;
};

struct Action {
  // How many heartbeat consecutive verification failures are required to
  // perform `action`.
  uint8 failure_count@0;
  // The action to perform when failure count is equal to `failure_count`.
  ActionType action@1;
};

// SendHeartbeat can either be successful or rate limited depending on how many
// reboots have happened. The HeartbeatResponse Enum takes care of proper
// replies.
enum HeartbeatResponse {
  kSuccess = 0,
  kRateLimit,
  kNotAllowed,
};

// Pacemaker interface. Clients hold the remote and use this to send heartbeat
// or stop the service.
//
// NextMinVersion: 1, NextIndex: 2
interface Pacemaker {
  // Clients have to call this method periodically to indicate they are alive.
  // Please call this at most once in a minute to minimize power consumption.
  SendHeartbeat@0() => (HeartbeatResponse response);
  // After calling this method, heartd will do the necessary clean up. Clients
  // can drop the connection safely after the callback is invoked.
  StopMonitor@1() => ();
};

// Adding new service needs a security review. Please reach out to the heartd
// service owner as early as possible.
[Extensible]
enum ServiceName {
  [Default] kUnmappedEnumField = 0,
  kKiosk = 1,
};

[Extensible]
enum ActionType {
  [Default] kUnmappedEnumField = 0,
  // No operation.
  kNoOperation = 1,
  kNormalReboot = 2,
  kForceReboot = 3,
  // Call `sync` to sync data to disk.
  kSyncData = 4,
};