// 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 "mojo/cros_healthd_diagnostics.mojom";
import "mojo/cros_healthd_events.mojom";
import "mojo/cros_healthd_probe.mojom";
import "mojo/network_diagnostics.mojom";
import "mojo/network_health.mojom";
import "mojo/nullable_primitives.mojom";
import "mojo/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.
interface CrosHealthdServiceFactory {
  // Returns a bound interface to the diagnostics service.
  GetDiagnosticsService(pending_receiver<CrosHealthdDiagnosticsService> service);
  // Returns a bound interface to the event service.
  GetEventService(pending_receiver<CrosHealthdEventService> service);
  // Returns a bound interface to the probe service.
  GetProbeService(pending_receiver<CrosHealthdProbeService> service);
  // Sends a bound interface to the Network Health service in Chrome.
  SendNetworkHealthService(
      pending_remote<
          chromeos.network_health.mojom.NetworkHealthService> remote);
  // Sends a NetworkDiagnosticsRoutines pending remote to the cros_healthd
  // daemon.
  SendNetworkDiagnosticsRoutines(
      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(pending_receiver<CrosHealthdSystemService> 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. If
  //                      not specified, the routine will default to 10 seconds.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunUrandomRoutine(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() => (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() => (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. If not specified, the routine will default
  //                      to 1 minute.
  //
  // The response:
  // * |response| - contains a unique identifier and status for the created
  //                routine.
  RunCpuCacheRoutine(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(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(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(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 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(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(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(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() => (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() => (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() => (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() => (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() => (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() => (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() => (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() => (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() => (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() => (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() => (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() => (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(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() => (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() => (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() => (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(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(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(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(
      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(pending_remote<CrosHealthdAudioObserver> 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);
};

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

// Interface to query the status of the cros_healthd service.
interface CrosHealthdSystemService {
  // Returns the status of the cros_healthd service and external mojo remotes.
  GetServiceStatus() => (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
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(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(string payload_string) => (GetEcTelemetryResponse response);

  // Starts the Service.
  StartEcService();

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