// 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/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.

module chromeos.cros_healthd.mojom;

import "diagnostics/mojom/external/network_diagnostics.mojom";
import "diagnostics/mojom/external/network_health.mojom";
import "diagnostics/mojom/public/cros_healthd_diagnostics.mojom";
import "diagnostics/mojom/public/cros_healthd_events.mojom";
import "diagnostics/mojom/public/cros_healthd_probe.mojom";
import "diagnostics/mojom/public/nullable_primitives.mojom";
import "diagnostics/mojom/public/wilco_ec.mojom";

// Factory interface which allows remote ends to request implementations of the
// probe, diagnostics, or event services. Additionally, the browser can send
// network-related implementations to the cros_healthd daemon.
//
// NextMinVersion: 1, NextIndex: 6
interface CrosHealthdServiceFactory {
  // Returns a bound interface to the diagnostics service.
  GetDiagnosticsService@0(pending_receiver<CrosHealthdDiagnosticsService> service);
  // Returns a bound interface to the event service.
  GetEventService@1(pending_receiver<CrosHealthdEventService> service);
  // Returns a bound interface to the probe service.
  GetProbeService@2(pending_receiver<CrosHealthdProbeService> service);
  // Sends a bound interface to the Network Health service in Chrome.
  SendNetworkHealthService@3(
      pending_remote<
          chromeos.network_health.mojom.NetworkHealthService> remote);
  // Sends a NetworkDiagnosticsRoutines pending remote to the cros_healthd
  // daemon.
  SendNetworkDiagnosticsRoutines@4(
      pending_remote<
          chromeos.network_diagnostics.mojom.NetworkDiagnosticsRoutines>
              network_diagnostics_routines);
  // TODO(http://b/181133872): Move this service out of this interface
  // Returns a bound interface to the system service.
  GetSystemService@5(pending_receiver<CrosHealthdSystemService> service);
};

// Diagnostics interface exposed by the cros_healthd daemon.
//
// NextMinVersion: 1, NextIndex: 32
interface CrosHealthdDiagnosticsService {
  // Returns an array of all diagnostic routines that the platform supports.
  GetAvailableRoutines@0()
      => (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@1(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. If
  //                      not specified, the routine will default to 10 seconds.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunUrandomRoutine@2(NullableUint32? 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 inputs
  // configured in cros_config. If no configuration data is present in
  // cros_config, the routine will fall back to fleet-wide default values of
  // [1000, 10000]. 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 response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunBatteryCapacityRoutine@3() => (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 against inputs configured in cros_config. If no configuration data
  // is present in cros_config, the routine will fall back to fleet-wide default
  // values of 1000 for the maximum allowable cycle count and 50% for maximum
  // battery wear percentage allowed. This routine is only available if
  // GetAvailableRoutines returned kBatteryHealth.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunBatteryHealthRoutine@4() => (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@5() => (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@6(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. If not specified, the routine will default
  //                      to 1 minute.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunCpuCacheRoutine@7(NullableUint32? 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. If not specified, the routine will default
  //                      to 1 minute.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunCpuStressRoutine@8(NullableUint32? 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.
  //                      If not specified, the routine will default to
  //                      1 minute.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunFloatingPointAccuracyRoutine@9(NullableUint32? 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@10(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@11(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@12(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 and verifies 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. If not specified, the routine will
  //                      default to 1 minute.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunPrimeSearchRoutine@13(NullableUint32? length_seconds)
      => (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@14(uint32 length_seconds,
                             uint32 maximum_discharge_percent_allowed)
      => (RunRoutineResponse response);

  // Requests that the BatteryCharge routine is created and started on the
  // platform. This routine checks the battery's charge rate over a period of
  // time. This routine is only available if GetAvailableRoutines returned
  // kBatteryCharge.
  //
  // The request:
  // * |length_seconds| - length of time to run the routine for.
  // * |minimum_charge_percent_required| - the routine will fail if the battery
  //                                       charges by less than this percentage.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunBatteryChargeRoutine@15(uint32 length_seconds,
                          uint32 minimum_charge_percent_required)
      => (RunRoutineResponse response);

  // Requests that the Memory routine is created and started on the platform.
  // This routine checks that the device's memory is working correctly. This
  // routine is only available if GetAvailableRoutines returned kMemory.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunMemoryRoutine@16() => (RunRoutineResponse response);

  // Requests that the LanConnectivity routine is created and started on the
  // platform. This routine checks whether the device is connected to a LAN.
  // This routine is only available if GetAvailableRoutines returned
  // kLanConnectivity.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunLanConnectivityRoutine@17() => (RunRoutineResponse response);

  // Requests that the SignalStrength routine is created and started on the
  // platform. This routine checks whether there is an acceptable signal
  // strength on wireless networks. This routine is only available if
  // GetAvailableRoutines returned kSignalStrength.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunSignalStrengthRoutine@18() => (RunRoutineResponse response);

  // Requests that the GatewayCanBePinged routine is created and started on the
  // platform. This routine checks whether the gateway of connected networks is
  // pingable. This routine is only available if GetAvailableRoutines returned
  // kGatewayCanBePinged.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunGatewayCanBePingedRoutine@19() => (RunRoutineResponse response);

  // Requests that the HasSecureWiFiConnection routine is created and started
  // on the platform. This routine checks whether the WiFi connection is
  // secure. Note that if WiFi is not connected, the routine will not run. This
  // routine is only available if GetAvailableRoutines returned
  // kHasSecureWiFiConnection.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunHasSecureWiFiConnectionRoutine@20() => (RunRoutineResponse response);

  // Requests that the DnsResolverPresent routine is created and started on the
  // platform. This routine checks whether a DNS resolver is available to the
  // browser. This routine is only available if GetAvailableRoutines returned
  // kDnsResolverPresent.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunDnsResolverPresentRoutine@21() => (RunRoutineResponse response);

  // Requests that the DnsLatency routine is created and started on the
  // platform. This routine checks whether the DNS latency is below an
  // acceptable threshold. This routine is only available if
  // GetAvailableRoutines returned kDnsLatency.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunDnsLatencyRoutine@22() => (RunRoutineResponse response);

  // Requests that the DnsResolution routine is created and started on the
  // platform. This routine checks whether a DNS resolution can be completed
  // successfully. This routine is only available if GetAvailableRoutines
  // returned kDnsResolution.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunDnsResolutionRoutine@23() => (RunRoutineResponse response);

  // Requests that the CaptivePortal routine is created and started on the
  // platform. This routine checks whether the internet connection is behind a
  // captive portal. This routine is only available if GetAvailableRoutines
  // returned kCaptivePortal.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunCaptivePortalRoutine@24() => (RunRoutineResponse response);

  // Requests that the HttpFirewall routine is created and started on the
  // platform. This routine checks whether a firewall is blocking HTTP port 80.
  // This routine is only available if GetAvailableRoutines returned
  // kHttpFirewall.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunHttpFirewallRoutine@25() => (RunRoutineResponse response);

  // Requests that the HttpsFirewall routine is created and started on the
  // platform. This routine checks whether a firewall is blocking HTTPS port
  // 443. This routine is only available if GetAvailableRoutines returned
  // kHttpsFirewall.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunHttpsFirewallRoutine@26() => (RunRoutineResponse response);

  // Requests that the HttpsLatency routine is created and started on the
  // platform. This routine checks whether the HTTPS latency is within
  // established tolerance levels for the system. This routine is only
  // available if GetAvailableRoutines returned kHttpsLatency.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunHttpsLatencyRoutine@27() => (RunRoutineResponse response);

  // Requests that the VideoConferencing routine is created and started on the
  // platform. This routine checks the device's video conferencing capabalities
  // by testing whether the device can:
  // (1) Contact either a default or specified STUN server via UDP.
  // (2) Contact either a default or specified STUN server via TCP.
  // (3) Reach common media endpoints.
  // This routine is only available if GetAvailableRoutines returned
  // kVideoConferencing.
  //
  // The request:
  // * |stun_server_hostname| - if specified, represents the custom STUN server
  //                            hostname.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunVideoConferencingRoutine@28(string? stun_server_hostname)
      => (RunRoutineResponse response);

  // Requests that the ArcHttp routine is created and started on the
  // platform. This routine checks whether the HTTP latency from inside ARC
  // is within established tolerance levels for the system. This routine is
  // only available if GetAvailableRoutines returned kArcHttp.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunArcHttpRoutine@29() => (RunRoutineResponse response);

  // Requests that the ArcPing routine is created and started on the
  // platform. This routine checks whether the gateway of connected networks is
  // pingable inside ARC. This routine is only available if GetAvailableRoutines
  // returned kArcPing.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunArcPingRoutine@30() => (RunRoutineResponse response);

  // Requests that the ArcDnsResolution routine is created and started on the
  // platform. This routine checks whether a DNS resolution can be completed
  // successfully inside ARC. This routine is only available if
  // GetAvailableRoutines returned kDnsResolution.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunArcDnsResolutionRoutine@31() => (RunRoutineResponse response);
};

// Event interface exposed by the cros_healthd daemon.
//
// NextMinVersion: 2, NextIndex: 7
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@0(pending_remote<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@1(pending_remote<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@2(pending_remote<CrosHealthdPowerObserver> observer);

  // Adds an observer to be notified on network events. The caller can remove
  // the observer created by this call by closing their end of the message pipe.
  //
  // The request:
  // * |observer| - network observer to be added to cros_healthd.
  AddNetworkObserver@3(
      pending_remote<
          chromeos.network_health.mojom.NetworkEventsObserver> observer);

  // Adds an observer to be notified on audio events. The caller can remove the
  // observer created by this call by closing their end of the message pipe.
  //
  // The request:
  // * |observer| - audio observer to be added to cros_healthd.
  AddAudioObserver@4(pending_remote<CrosHealthdAudioObserver> observer);

  // Adds an observer to be notified on Thunderbolt events. The caller can
  // remove the observer created by this call by closing their end of the
  // message pipe.
  //
  // The request:
  // * |observer| - Thunderbolt observer to be added to cros_healthd.
  AddThunderboltObserver@5(
      pending_remote<CrosHealthdThunderboltObserver> observer);

  // Adds an observer to be notified on USB events. The caller can remove the
  // observer created by this call by closing their end of the message pipe.
  //
  // The request:
  // * |observer| - USB observer to be added to cros_healthd.
  [MinVersion=1] AddUsbObserver@6(
      pending_remote<CrosHealthdUsbObserver> observer);
};

// Probe interface exposed by the cros_healthd daemon.
//
// NextMinVersion: 1, NextIndex: 2
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@0(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@1(array<ProbeCategoryEnum> categories)
      => (TelemetryInfo telemetry_info);
};

// Contains data about the current service instance of cros_healthd.
//
// NextMinVersion: 1, NextIndex: 2
struct ServiceStatus {
  // Boolean flag if the NetworkHealthService mojo remote has been sent from
  // Chrome and bound in cros_healthd.
  bool network_health_bound@0;
  // Boolean flag if the NetworkDiagnosticsService mojo remote has been sent
  // from Chrome and bound in cros_healthd.
  bool network_diagnostics_bound@1;
};

// Interface to query the status of the cros_healthd service.
//
// NextMinVersion: 1, NextIndex: 1
interface CrosHealthdSystemService {
  // Returns the status of the cros_healthd service and external mojo remotes.
  GetServiceStatus@0() => (ServiceStatus response);
};

// Wilco EC (embedded controller) interface exposed by the cros_healthd daemon.
// This is to be used by the wilco_dtc and wilco_dtc_supportd processes to
// interact with the cros_healthd ec_service, observe EC events, and request
// telemetry information.
// ChromeOS wilco_dtc_supportd will use this to capture EC events and telemetry
// to be communicated to the sandboxed wilco_dtc which uses external,
// proprietary code to communicate with Dell enterprise telemetry services
// through the browser.
// See go/wilco-ec for more information
//
// NextMinVersion: 1, NextIndex: 4
interface WilcoEcServiceController {
  // Adds an observer to be notified on EC events. The caller can remove the
  // observer created by this call by closing their end of the message pipe.
  //
  // The request:
  // * |observer| - EC observer to be added to cros_healthd.
  AddEcObserver@0(pending_remote<WilcoEcObserver> observer);

  // Returns EC telemetry
  //
  // The request:
  // * |payload_string| - a byte string produced by the wilco_dtc VM.
  //
  // The response:
  // * |response| - a structure containing a byte string and a status code.
  GetEcTelemetry@1(string payload_string) => (GetEcTelemetryResponse response);

  // Starts the Service.
  StartEcService@2();

  // Shuts down the Service.
  ShutdownEcService@3();
};
