// 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 "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";

// 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(CrosHealthdDiagnosticsService& service);
  // Returns a bound interface to the event service.
  GetEventService(CrosHealthdEventService& service);
  // Returns a bound interface to the probe service.
  GetProbeService(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);
};

// 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);
};

// 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);
};
