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

// API exposed by the cros_healthd daemon. This API is normally consumed by the
// browser and the telem and diag command-line tools.

// NOTE: This mojom should be kept in sync with the copy in Chromium's repo in
// src/chrome/services/cros_healthd/public/mojom/cros_healthd.mojom.

module chromeos.cros_healthd.mojom;

import "cros_healthd_diagnostics.mojom";
import "cros_healthd_events.mojom";
import "cros_healthd_probe.mojom";

// Factory interface which allows remote ends to request implementations of the
// probe or diagnostics services.
interface CrosHealthdServiceFactory {
  // Returns a bound interface to the diagnostics service.
  GetDiagnosticsService(CrosHealthdDiagnosticsService& service);
  // Returns a bound interface to the event service.
  GetEventService(CrosHealthdEventService& service);
  // Returns a bound interface to the probe service.
  GetProbeService(CrosHealthdProbeService& service);
};

// Diagnostics interface exposed by the cros_healthd daemon.
interface CrosHealthdDiagnosticsService {
  // Returns an array of all diagnostic routines that the platform supports.
  GetAvailableRoutines()
      => (array<DiagnosticRoutineEnum> available_routines);

  // Sends commands to an existing routine. Also returns status information for
  // the routine.
  //
  // The request:
  // * |id| - specifies which routine the command will be sent to. This must be
  //          the same id that was returned from the RunSomeRoutine function
  //          call used to create the routine.
  // * |command| - command to send the routine.
  // * |include_output| - whether or not the response should include any output
  //                      accumulated from the routine.
  //
  // The response:
  // * |routine_update| - status information for the specified routine. See
  //                      cros_healthd_diagnostics.mojom for the structure.
  GetRoutineUpdate(int32 id, DiagnosticRoutineCommandEnum command,
                   bool include_output)
      => (RoutineUpdate routine_update);

  // Requests that the Urandom routine is created and started on the platform.
  // This routine attempts to continually read from /dev/urandom to stress the
  // cpu. The routine will pass iff all the reads from /dev/urandom succeed.
  // This routine is only available if GetAvailableRoutines returned kUrandom.
  //
  // The request:
  // * |length_seconds| - length of time, in seconds, to run the urandom routine
  //                      for. If all reads from /dev/urandom for this length of
  //                      time are successful, then the test  will pass. This
  //                      parameter needs to be strictly greater than zero.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunUrandomRoutine(uint32 length_seconds)
      => (RunRoutineResponse response);

  // Requests that the BatteryCapacity routine is created and started on the
  // platform. This routine checks the battery's design capacity against the
  // inputs. The routine will pass iff the design capacity of the battery read
  // from the platform is inclusively within these bounds. This routine is only
  // available if GetAvailableRoutines returned kBatteryCapactity.
  //
  // The request:
  // * |low_mah| - lower bound for the battery's design capacity (mAh).
  // * |high_mah| - upper bound for the battery's design capacity (mAh).
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunBatteryCapacityRoutine(uint32 low_mah, uint32 high_mah)
      => (RunRoutineResponse response);

  // Requests that the BatteryHealth routine is created and started on the
  // platform. This routine checks the cycle count and percent wear of the
  // battery. This routine is only available if GetAvailableRoutines returned
  // kBatteryHealth.
  //
  // The request:
  // * |maximum_cycle_count| - maximum cycle count allowed for the routine to
  //                           pass.
  // * |percent_battery_wear_allowed| - maximum percent battery wear allowed for
  //                                    the routine to pass.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunBatteryHealthRoutine(uint32 maximum_cycle_count,
                          uint32 percent_battery_wear_allowed)
      => (RunRoutineResponse response);

  // Requests that the SmartctlCheck routine is created and started on the
  // platform. This routine checks available spare NVMe capacity against the
  // threshold. This routine is only available if GetAvailableRoutines returned
  // kSmartctlCheck.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunSmartctlCheckRoutine() => (RunRoutineResponse response);

  // Requests that the AcPower routine is created and started on the
  // platform. This routine checks the status of the power supply, and if
  // |expected_power_type| is specified, checks to see that
  // |expected_power_type| matches the type reported by the power supply. This
  // routine is only available if GetAvailableRoutines returned kAcPower.
  //
  // The request:
  // * |expected_status| - whether or not the adapter is expected to be online.
  // * |expected_power_type| - if specified, must match the type of the power
  //                           supply for the routine to succeed.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunAcPowerRoutine(AcPowerStatusEnum expected_status,
                    string? expected_power_type)
      => (RunRoutineResponse response);

  // Requests that the CPU cache routine is created and started on the
  // platform. This routine runs the stressapptest to test the CPU caches.
  // The routine will pass if the stressapptest returns zero. This routine is
  // only available if GetAvailableRoutines returned kCpuCache.
  //
  // The request:
  // * |length_seconds| - length of time, in seconds, to run the CPU cache
  //                      routine. This parameter needs to be strictly greater
  //                      than zero.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunCpuCacheRoutine(uint32 length_seconds)
      => (RunRoutineResponse response);

  // Requests that the CPU stress routine is created and started on the
  // platform. This routine runs the stressapptest to stress test the CPU.
  // The routine will pass if the stressapptest returns zero. This routine is
  // only available if GetAvailableRoutines returned kCpuStress.
  //
  // The request:
  // * |length_seconds| - length of time, in seconds, to run the CPU stress
  //                      routine. This parameter needs to be strictly greater
  //                      than zero.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunCpuStressRoutine(uint32 length_seconds)
      => (RunRoutineResponse response);

  // Requests that the FloatingPointAccuracy routine is created and started
  // on the platform. This routine executes millions of floating-point
  // operations by SSE instructions for a specified amount of time. The routine
  // will pass if the result values of the operations and known accurate result
  // are the same.
  //
  // The request:
  // * |length_seconds| - length of time, in seconds, to run the floating-point
  //                      routine for. Test will executes millions of
  //                      floating-point operations in length seconds and get
  //                      the result to compare with known accurate results.
  //                      This parameter needs to be strictly greater than zero.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunFloatingPointAccuracyRoutine(uint32 length_seconds)
      => (RunRoutineResponse response);

  // Requests that the NvmeWearLevel routine is created and started on the
  // platform. This routine examines wear level of NVMe against input
  // threshold. This routine is only available if GetAvailableRoutines returned
  // kNvmeWearLevel.
  //
  // The request:
  // * |wear_level_threshold| - threshold number in percentage which routine
  //                            examines wear level status against.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunNvmeWearLevelRoutine(uint32 wear_level_threshold)
      => (RunRoutineResponse response);

  // Requests that the NvmeSelfTest routine is created and started on the
  // platform. This routine launches the NVMe self-test, a tool to perform
  // necessary tests to observe the performance and the parameters. This routine
  // is only available if GetAvailableRoutines returned kNvmeSelfTest.
  //
  // The request:
  // * |nvme_self_test_type| - specifies the type of test for short period or
  //                           extended version.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunNvmeSelfTestRoutine(NvmeSelfTestTypeEnum nvme_self_test_type)
      => (RunRoutineResponse response);

  // Requests that the DiskRead routine is created and started on the platform.
  // The routine will create a test file with md5 checksum, read the test file
  // either randomly or linearly, repeatedly for a dedicated duration. If the
  // md5 checksum of read back is validated, then the test will pass.
  // This routine is only available if GetAvailableRoutines returned kDiskRead.
  //
  // The request:
  // * |type| - type of how disk reading is performed, either linear or random.
  //
  // * |length_seconds| - length of time, in seconds, to run the DiskRead
  //                      routine for. This parameter needs to be strictly
  //                      greater than zero.
  // * |file_size_mb| - test file size, in mega bytes, to test with DiskRead
  //                    routine
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunDiskReadRoutine(DiskReadRoutineTypeEnum type, uint32 length_seconds,
                     uint32 file_size_mb)
      => (RunRoutineResponse response);

  // Requests that the PrimeSearch routine is created and started on the
  // platform. Calculate prime numbers between 2 to max_num and verify the
  // calculation repeatedly in a duration. This routine is only available
  // if GetAvailableRoutines returned kPrimeSearch.
  //
  // The request:
  // * |length_seconds| - length of time, in seconds, to run the PrimeSearch
  //                      routine for. This parameter needs to be strictly
  //                      greater than zero.
  // * |max_num| - largest number that routine will calculate prime numbers up
  //               to.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunPrimeSearchRoutine(uint32 length_seconds, uint64 max_num)
      => (RunRoutineResponse response);

  // Requests that the BatteryDischarge routine is created and started on the
  // platform. This routine checks the battery's discharge rate over a period of
  // time. This routine is only available if GetAvailableRoutines returned
  // kBatteryDischarge.
  //
  // The request:
  // * |length_seconds| - length of time to run the routine for.
  // * |maximum_discharge_percent_allowed| - the routine will fail if the
  //                                         battery discharges by more than
  //                                         this percentage.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunBatteryDischargeRoutine(uint32 length_seconds,
                             uint32 maximum_discharge_percent_allowed)
      => (RunRoutineResponse response);
};

// Event interface exposed by the cros_healthd daemon.
interface CrosHealthdEventService {
  // Adds an observer to be notified on Bluetooth events. The caller can remove
  // the observer created by this call by closing their end of the message pipe.
  //
  // The request:
  // * |observer| - Bluetooth observer to be added to cros_healthd.
  AddBluetoothObserver(CrosHealthdBluetoothObserver observer);

  // Adds an observer to be notified on lid events. The caller can remove the
  // observer created by this call by closing their end of the message pipe.
  //
  // The request:
  // * |observer| - lid observer to be added to cros_healthd.
  AddLidObserver(CrosHealthdLidObserver observer);

  // Adds an observer to be notified on power events. The caller can remove the
  // observer created by this call by closing their end of the message pipe.
  //
  // The request:
  // * |observer| - power observer to be added to cros_healthd.
  AddPowerObserver(CrosHealthdPowerObserver observer);
};

// Probe interface exposed by the cros_healthd daemon.
interface CrosHealthdProbeService {
  // Returns information about a specific process running on the device.
  //
  // The request:
  // * |process_id| - PID of the process whose information is requested.
  //
  // The response:
  // * |process_info| - Information about the requested process.
  ProbeProcessInfo(uint32 process_id) => (ProcessResult process_info);

  // Returns telemetry information for the desired categories.
  //
  // The request:
  // * |categories| - list of each of the categories that ProbeTelemetryInfo
  //                  should return information for.
  //
  // The response:
  // * |telemetry_info| - information for each of the requested categories. Only
  //                      the fields corresponding to the requested categories
  //                      will be non-null.
  ProbeTelemetryInfo(array<ProbeCategoryEnum> categories)
      => (TelemetryInfo telemetry_info);
};
