chromium/chrome/common/chromeos/extensions/api/diagnostics.idl

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

// Use the <code>chrome.os.diagnostics</code> API to run diagnostic routines.
//
// Many types defined here map with Mojo structs defined in
// chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom.
[implemented_in = "chrome/browser/chromeos/extensions/telemetry/api/diagnostics/diagnostics_api.h"]
namespace os.diagnostics {
// Note: Please update documentation as well when this interface is changed.
// The documentation lives here: //docs/telemetry_extension/api_overview.md.
// LINT.IfChange


// ----------------- DIAGNOSTICS API V1 -----------------
  enum RoutineType {
    ac_power,
    battery_capacity,
    battery_charge,
    battery_discharge,
    battery_health,
    cpu_cache,
    cpu_floating_point_accuracy,
    cpu_prime_search,
    cpu_stress,
    disk_read,
    dns_resolution,
    memory,
    smartctl_check,
    lan_connectivity,
    signal_strength,
    dns_resolver_present,
    gateway_can_be_pinged,
    sensitive_sensor,
    nvme_self_test,
    fingerprint_alive,
    smartctl_check_with_percentage_used,
    emmc_lifetime,
    bluetooth_power,
    ufs_lifetime,
    power_button,
    audio_driver,
    bluetooth_discovery,
    bluetooth_scanning,
    bluetooth_pairing,
    fan
  };

  enum RoutineStatus {
    unknown,
    ready,
    running,
    waiting_user_action,
    passed,
    failed,
    error,
    cancelled,
    failed_to_start,
    removed,
    cancelling,
    unsupported,
    not_run
  };

  enum RoutineCommandType {
    cancel,
    remove,
    resume,
    status
  };

  enum UserMessageType {
    unknown,
    unplug_ac_power,
    plug_in_ac_power,
    press_power_button
  };

  enum DiskReadRoutineType {
    linear,
    random
  };

  enum AcPowerStatus {
    connected,
    disconnected
  };

  dictionary GetAvailableRoutinesResponse {
    RoutineType[] routines;
  };

  dictionary GetRoutineUpdateRequest {
    long id;
    RoutineCommandType command;
  };

  dictionary GetRoutineUpdateResponse {
    long progress_percent;
    DOMString? output;
    RoutineStatus status;
    DOMString status_message;
    // Returned for routines that require user action (e.g. unplug power cable).
    UserMessageType? user_message;
  };

  dictionary RunAcPowerRoutineRequest {
    AcPowerStatus expected_status;
    // If specified, this must match the type of power
    // supply for the routine to succeed.
    DOMString? expected_power_type;
  };

  dictionary RunBatteryChargeRoutineRequest {
    long length_seconds;

    long minimum_charge_percent_required;
  };

  dictionary RunBatteryDischargeRoutineRequest {
    long length_seconds;

    long maximum_discharge_percent_allowed;
  };

  dictionary RunBluetoothPairingRoutineRequest {
    DOMString peripheral_id;
  };

  dictionary RunBluetoothScanningRoutineRequest {
    long length_seconds;
  };

  dictionary RunCpuRoutineRequest {
    long length_seconds;
  };

  dictionary RunDiskReadRequest {
    DiskReadRoutineType type;
    long length_seconds;
    long file_size_mb;
  };

  enum NvmeSelfTestType {
    short_test,
    long_test
  };

  dictionary RunNvmeSelfTestRequest {
    NvmeSelfTestType test_type;
  };

  dictionary RunSmartctlCheckRequest {
    long? percentage_used_threshold;
  };

  dictionary RunPowerButtonRequest {
    long timeout_seconds;
  };

  dictionary RunRoutineResponse {
    long id;

    RoutineStatus status;
  };

  callback GetAvailableRoutinesCallback = void (
      GetAvailableRoutinesResponse response);

  callback GetRoutineUpdateCallback = void (GetRoutineUpdateResponse response);

  callback RunRoutineCallback = void (RunRoutineResponse response);

  // ----------------- DIAGNOSTICS API V2 -----------------

  dictionary RoutineInitializedInfo {
    DOMString? uuid;
  };

  enum NetworkBandwidthRoutineRunningType {
    download,
    upload
  };

  dictionary NetworkBandwidthRoutineRunningInfo {
    // The type of test that routine is running.
    NetworkBandwidthRoutineRunningType type;
    // The current network speed in Kbps.
    double speedKbps;
  };

  // This is a union type. Exactly one field should be set.
  dictionary RoutineRunningInfoUnion {
    NetworkBandwidthRoutineRunningInfo? networkBandwidth;
  };

  dictionary RoutineRunningInfo {
    DOMString? uuid;
    long? percentage;
    RoutineRunningInfoUnion? info;
  };

  // Details regarding the inquiry to check the LED lit up state. Clients should
  // inspect the target LED and report its state using `CheckLedLitUpStateReply`
  // as the argument of `replyToRoutineInquiry`.
  dictionary CheckLedLitUpStateInquiry {
  };

  // Details regarding the inquiry to check the keyboard backlight lit up state.
  // Clients should confirm the correctness and report its state using
  // `CheckKeyboardBacklightStateReply` as the argument of
  // `replyToRoutineInquiry`.
  dictionary CheckKeyboardBacklightStateInquiry {
  };

  // This is a union type. Exactly one field should be set.
  //
  // At this time, there is only one member type. Other member types will be
  // added when needed.
  dictionary RoutineInquiryUnion {
    CheckLedLitUpStateInquiry? checkLedLitUpState;
    CheckKeyboardBacklightStateInquiry? checkKeyboardBacklightState;
  };

  // This is a union type. Exactly one field should be set.
  //
  // At this time, there is only one member type. Other member types will be
  // added later.
  dictionary RoutineInteractionUnion {
    // Routine inquiries need to be replied to with the `replyToRoutineInquiry`
    // method.
    RoutineInquiryUnion? inquiry;
  };

  enum RoutineWaitingReason {
    waiting_to_be_scheduled,
    waiting_for_interaction
  };

  dictionary RoutineWaitingInfo {
    DOMString? uuid;
    long? percentage;
    // Reason why the routine waits.
    RoutineWaitingReason? reason;
    // Additional information, may be used to pass instruction or explanation.
    DOMString? message;
    // The requested interaction. When set, clients must respond to the
    // interaction for the routine to proceed. See `RoutineInteractionUnion` to
    // learn about how to respond to each interaction.
    RoutineInteractionUnion? interaction;
  };

  enum ExceptionReason {
    unknown,
    // Any other exceptions that we don't expect to happen. Clients should
    // simply report the error.
    unexpected,
    // Raises this if clients try to run an unsupported feature. Note that
    // clients should use methods which return `SupportStatus` for support
    // status check.
    unsupported,
    // The corresponding App UI was closed and thus stopped the routine
    // execution.
    app_ui_closed,
    // Raises this if a camera frontend needs to be opened but it is actually
    // not opened.
    camera_frontend_not_opened
  };

  dictionary ExceptionInfo {
    DOMString? uuid;
    ExceptionReason reason;
    // A human readable message for debugging. Don't rely on the content because
    // it could change anytime.
    DOMString? debugMessage;
  };

  enum MemtesterTestItemEnum {
    // The memtester test is not recognized.
    unknown,

    // Test that all memory addresses to be tested can be set to itself and its
    // complement.
    stuck_address,

    // These tests test different operation of a random int64 with buffer
    // initialized as 0xFFFFFFFF, repeating over 64 bit blocks.
    // Perform AND operation.
    compare_and,
    // Perform DIV operation.
    compare_div,
    // Perform MUL operation.
    compare_mul,
    // Perform OR operation.
    compare_or,
    // Perform SUB operation.
    compare_sub,
    // Perform XOR operation.
    compare_xor,
    // Perform ADD operation.
    sequential_increment,

    // These tests test setting memory regions in a certain pattern, repeating
    // over each 64 bit blocks.
    // Test Pattern: |0*10*| and |1*01*|.
    bit_flip,
    // Test Pattern:|0*1010*| and |1*0101*|.
    bit_spread,
    // Test Pattern: all 256 possible combinations of a 8 bit block, repeated 8
    // times.
    block_sequential,
    // Test Pattern: Alternating 0 and 1.
    checkerboard,
    // Test Pattern: Random 64 bits.
    random_value,
    // Test Pattern: all 0s and all 1s.
    solid_bits,
    // Test Pattern: |0*10*|.
    walking_ones,
    // Test Pattern: |1*01*|.
    walking_zeroes,

    // These tests test writing random n bit words across the memory regions.
    // Test Pattern: 8 bit random words.
    eight_bit_writes,
    // Test Pattern: 16 bit random words.
    sixteen_bit_writes
  };

  dictionary MemtesterResult {
    MemtesterTestItemEnum[] passedItems;
    MemtesterTestItemEnum[] failedItems;
  };

  dictionary LegacyMemtesterResult {
    MemtesterTestItemEnum[] passed_items;
    MemtesterTestItemEnum[] failed_items;
  };

  dictionary MemoryRoutineFinishedDetail {
    // Number of bytes tested in the memory routine.
    double? bytesTested;
    // Contains the memtester test results.
    MemtesterResult? result;
  };

  dictionary LegacyMemoryRoutineFinishedInfo {
    DOMString? uuid;
    boolean? has_passed;
    // Number of bytes tested in the memory routine.
    double? bytesTested;
    // Contains the memtester test results.
    LegacyMemtesterResult? result;
  };

  dictionary CreateMemoryRoutineArguments {
    // An optional field to indicate how much memory should be tested. If the
    // value is null, memory test will run with as much memory as possible.
    long? maxTestingMemKib;
  };

  enum VolumeButtonType {
    // The volume up button.
    volume_up,
    // The volume down button.
    volume_down
  };

  dictionary LegacyVolumeButtonRoutineFinishedInfo {
    DOMString? uuid;
    boolean? has_passed;
  };

  dictionary CreateVolumeButtonRoutineArguments {
    // The volume button to be tested.
    VolumeButtonType buttonType;
    // Length of time to listen to the volume button events. The value should be
    // positive and less or equal to 600 seconds.
    long timeoutSeconds;
  };

  dictionary LegacyCreateVolumeButtonRoutineArguments {
    // The volume button to be tested.
    VolumeButtonType button_type;
    // Length of time to listen to the volume button events. The value should be
    // positive and less or equal to 600 seconds.
    long timeout_seconds;
  };

  enum HardwarePresenceStatus {
    // The hardware presence matches the description.
    matched,
    // The hardware presence does not match the description.
    not_matched,
    // There is no description available, skipping check.
    not_configured
  };

  dictionary FanRoutineFinishedDetail {
    // The ids of fans that can be controlled.
    long[]? passedFanIds;
    // The ids of fans that cannot be controlled.
    long[]? failedFanIds;
    // Whether the number of fan probed is matched.
    HardwarePresenceStatus? fanCountStatus;
  };

  dictionary LegacyFanRoutineFinishedInfo {
    DOMString? uuid;
    boolean? has_passed;
    // The ids of fans that can be controlled.
    long[]? passed_fan_ids;
    // The ids of fans that cannot be controlled.
    long[]? failed_fan_ids;
    // Whether the number of fan probed is matched.
    HardwarePresenceStatus? fan_count_status;
  };

  dictionary CreateFanRoutineArguments {
  };

  dictionary CreateNetworkBandwidthRoutineArguments {
  };

  dictionary NetworkBandwidthRoutineFinishedDetail {
    // Average download speed in Kbit/s.
    double downloadSpeedKbps;
    // Average upload speed in Kbit/s.
    double uploadSpeedKbps;
  };

  enum LedName {
    battery,
    power,
    adapter,
    left,
    right
  };

  enum LedColor {
    red,
    green,
    blue,
    yellow,
    white,
    amber
  };

  // The routine lights up the target LED in the specified color and requests
  // the caller to verify the change.
  //
  // This routine is supported if and only if the device has a ChromeOS EC.
  //
  // When an LED name or LED color is not supported by the EC, it will cause a
  // routine exception (by emitting an `onRoutineException` event) at runtime.
  //
  // The routine proceeds with the following steps:
  // 1. Set the specified LED with the specified color and enter the waiting
  //    state with the `CheckLedLitUpStateInquiry` interaction request.
  // 2. After receiving `CheckLedLitUpStateReply` with the observed LED state,
  //    the color of the LED will be reset (back to auto control). Notice that
  //    there is no timeout so the routine will be in the waiting state
  //    indefinitely.
  // 3. The routine passes if the LED is lit up in the correct color. Otherwise,
  //    the routine fails.
  dictionary CreateLedLitUpRoutineArguments {
    LedName name;
    LedColor color;
  };

  // The routine checks the frames captured by camera. The frontend should
  // ensure the camera is opened during the execution of the routine.
  dictionary CreateCameraFrameAnalysisRoutineArguments {
  };

  // The routine checks whether the keyboard backlight can be lit up at any
  // brightness level.
  dictionary CreateKeyboardBacklightRoutineArguments {
  };

  enum CameraFrameAnalysisIssue {
    // No issue.
    no_issue,
    // The camera service is not available.
    camera_service_not_available,
    // The len is blocked by the privacy shutter.
    blocked_by_privacy_shutter,
    // The frames are blurred. Lens might be dirty.
    lens_are_dirty
  };

  enum CameraSubtestResult {
    // The subtest was not run, possibly because the subtest was not enabled in
    // the routine parameter or the subtest was not available on the device.
    not_run,
    // The subtest was passed.
    passed,
    // The subtest was failed.
    failed
  };

  dictionary CameraFrameAnalysisRoutineFinishedDetail {
    // The issue caught by the routine. See the fields for each subtest for
    // their details.
    CameraFrameAnalysisIssue issue;
    // The result is `failed` if the len is blocked by the privacy shutter. To
    // mitigate the issue, users are suggested to open the privacy shutter to
    // unveil the len.
    CameraSubtestResult privacyShutterOpenTest;
    // The result is `failed` if the frames are blurred. To mitigate the issue,
    // users are suggested to clean the lens.
    CameraSubtestResult lensNotDirtyTest;
  };

  // This is a union type. Exactly one field should be set.
  [ignoreAdditionalProperties] dictionary CreateRoutineArgumentsUnion {
    CreateMemoryRoutineArguments? memory;
    CreateVolumeButtonRoutineArguments? volumeButton;
    CreateFanRoutineArguments? fan;
    CreateNetworkBandwidthRoutineArguments? networkBandwidth;
    CreateLedLitUpRoutineArguments? ledLitUp;
    CreateCameraFrameAnalysisRoutineArguments? cameraFrameAnalysis;
    CreateKeyboardBacklightRoutineArguments? keyboardBacklight;
  };

  // This is a union type. Exactly one field should be set.
  dictionary RoutineFinishedDetailUnion {
    MemoryRoutineFinishedDetail? memory;
    FanRoutineFinishedDetail? fan;
    NetworkBandwidthRoutineFinishedDetail? networkBandwidth;
    CameraFrameAnalysisRoutineFinishedDetail? cameraFrameAnalysis;
  };

  dictionary RoutineFinishedInfo {
    DOMString? uuid;
    boolean? hasPassed;
    RoutineFinishedDetailUnion? detail;
  };

  dictionary CreateRoutineResponse {
    DOMString? uuid;
  };

  callback CreateRoutineCallback = void (CreateRoutineResponse response);

  enum RoutineSupportStatus {
    supported,
    unsupported
  };

  dictionary RoutineSupportStatusInfo {
    RoutineSupportStatus? status;
  };

  callback RoutineSupportStatusInfoCallback = void (RoutineSupportStatusInfo info);

  dictionary StartRoutineRequest {
    DOMString uuid;
  };

  callback StartRoutineCallback = void ();

  dictionary CancelRoutineRequest {
    DOMString uuid;
  };

  callback CancelRoutineCallback = void ();

  enum LedLitUpState {
    correct_color,
    not_lit_up
  };

  enum KeyboardBacklightState {
    ok,
    any_not_lit_up
  };

  dictionary CheckLedLitUpStateReply {
    // State of the target LED.
    LedLitUpState state;
  };

  dictionary CheckKeyboardBacklightStateReply {
    // State of the keyboard backlight.
    KeyboardBacklightState state;
  };

  // This is a union type. Exactly one field should be set.
  [ignoreAdditionalProperties] dictionary RoutineInquiryReplyUnion {
    CheckLedLitUpStateReply? checkLedLitUpState;
    CheckKeyboardBacklightStateReply? checkKeyboardBacklightState;
  };

  dictionary ReplyToRoutineInquiryRequest {
    DOMString uuid;
    // The reply to an inquiry in the routine waiting info.
    RoutineInquiryReplyUnion reply;
  };

  callback ReplyToRoutineInquiryCallback = void ();

  interface Functions {
    static void getAvailableRoutines(GetAvailableRoutinesCallback callback);

    static void getRoutineUpdate(
        GetRoutineUpdateRequest request,
        GetRoutineUpdateCallback callback);

    static void runAcPowerRoutine(
        RunAcPowerRoutineRequest request,
        RunRoutineCallback callback);

    static void runBatteryCapacityRoutine(RunRoutineCallback callback);

    static void runBatteryChargeRoutine(
        RunBatteryChargeRoutineRequest request,
        RunRoutineCallback callback);

    static void runBatteryDischargeRoutine(
        RunBatteryDischargeRoutineRequest request,
        RunRoutineCallback callback);

    static void runBatteryHealthRoutine(RunRoutineCallback callback);

    static void runBluetoothDiscoveryRoutine(RunRoutineCallback callback);

    static void runBluetoothPairingRoutine(
        RunBluetoothPairingRoutineRequest request,
        RunRoutineCallback callback);

    static void runBluetoothPowerRoutine(RunRoutineCallback callback);

    static void runBluetoothScanningRoutine(
        RunBluetoothScanningRoutineRequest request,
        RunRoutineCallback callback);

    static void runCpuCacheRoutine(
        RunCpuRoutineRequest request,
        RunRoutineCallback callback);

    static void runCpuFloatingPointAccuracyRoutine(
        RunCpuRoutineRequest request,
        RunRoutineCallback callback);

    static void runCpuPrimeSearchRoutine(
        RunCpuRoutineRequest request,
        RunRoutineCallback callback);

    static void runCpuStressRoutine(
        RunCpuRoutineRequest request,
        RunRoutineCallback callback);

    static void runDiskReadRoutine(
        RunDiskReadRequest request,
        RunRoutineCallback callback);

    static void runDnsResolutionRoutine(RunRoutineCallback callback);

    static void runDnsResolverPresentRoutine(RunRoutineCallback callback);

    static void runEmmcLifetimeRoutine(RunRoutineCallback callback);

    static void runFingerprintAliveRoutine(RunRoutineCallback callback);

    static void runGatewayCanBePingedRoutine(RunRoutineCallback callback);

    static void runLanConnectivityRoutine(RunRoutineCallback callback);

    static void runMemoryRoutine(RunRoutineCallback callback);

    static void runNvmeSelfTestRoutine(
        RunNvmeSelfTestRequest request,
        RunRoutineCallback callback);

    static void runSensitiveSensorRoutine(RunRoutineCallback callback);

    static void runSignalStrengthRoutine(RunRoutineCallback callback);

    static void runSmartctlCheckRoutine(
        optional RunSmartctlCheckRequest request,
        RunRoutineCallback callback);

    static void runUfsLifetimeRoutine(RunRoutineCallback callback);

    static void runPowerButtonRoutine(
        RunPowerButtonRequest request,
        RunRoutineCallback callback);

    static void runAudioDriverRoutine(RunRoutineCallback callback);

    static void runFanRoutine(RunRoutineCallback callback);

    // ----------------- DIAGNOSTICS API V2 -----------------

    // Checks whether a certain routine arguments (expected to be of type
    // `CreateRoutineArgumentsUnion`) is supported on the platform. Exactly one
    // routine should be set in `CreateRoutineArgumentsUnion`.
    static void isRoutineArgumentSupported(
        CreateRoutineArgumentsUnion args,
        RoutineSupportStatusInfoCallback callback);

    // Create a routine with routine arguments (expected to be of type
    // `CreateRoutineArgumentsUnion`). Exactly one routine should be set in
    // `CreateRoutineArgumentsUnion`.
    static void createRoutine(
        CreateRoutineArgumentsUnion args,
        CreateRoutineCallback callback);

    // Starts execution of a routine. This can only be expected to work after
    // `onRoutineInitialized` was emitted for the routine with `UUID`.
    static void startRoutine(
        StartRoutineRequest request,
        StartRoutineCallback callback);

    // Stops executing the routine identified by `UUID` and removes all related
    // resources from the system.
    static void cancelRoutine(
        CancelRoutineRequest request,
        CancelRoutineCallback callback);

    // Replies to a routine inquiry. This can only work when the routine with
    // `UUID` is in the waiting state and has set an inquiry in the waiting
    // info.
    static void replyToRoutineInquiry(
        ReplyToRoutineInquiryRequest request,
        ReplyToRoutineInquiryCallback callback);

    // ----------------- DEPRECATED DIAGNOSTICS API V2 -----------------
    // TODO(b/331540565): Remove legacy APIs.

    // Deprecated. Use `createRoutine` instead.
    static void createMemoryRoutine(
        CreateMemoryRoutineArguments args,
        CreateRoutineCallback callback);

    // Deprecated. Use `isRoutineArgumentSupported` instead.
    // Checks whether a certain `CreateMemoryRoutineArguments` is supported on
    // the platform.
    static void isMemoryRoutineArgumentSupported(
        CreateMemoryRoutineArguments args,
        RoutineSupportStatusInfoCallback callback);

    // Deprecated. Use `createRoutine` instead.
    static void createVolumeButtonRoutine(
        LegacyCreateVolumeButtonRoutineArguments args,
        CreateRoutineCallback callback);

    // Deprecated. Use `isRoutineArgumentSupported` instead.
    // Checks whether a certain `LegacyCreateVolumeButtonRoutineArguments` is
    // supported on the platform.
    static void isVolumeButtonRoutineArgumentSupported(
        LegacyCreateVolumeButtonRoutineArguments args,
        RoutineSupportStatusInfoCallback callback);

    // Deprecated. Use `createRoutine` instead.
    static void createFanRoutine(
        CreateFanRoutineArguments args,
        CreateRoutineCallback callback);

    // Deprecated. Use `isRoutineArgumentSupported` instead.
    // Checks whether a certain `CreateFanRoutineArguments` is supported on the
    // platform.
    static void isFanRoutineArgumentSupported(
        CreateFanRoutineArguments args,
        RoutineSupportStatusInfoCallback callback);
  };

  interface Events {
    // Informs the extension that a routine was intitialized.
    static void onRoutineInitialized(RoutineInitializedInfo initializedInfo);

    // Informs the extension that a routine started running. This can happen in
    // two situations:
    // 1. `startRoutine` was called and the routine successfully started
    //    execution.
    // 2. The routine exited the "waiting" state and returned to running.
    static void onRoutineRunning(RoutineRunningInfo runningInfo);

    // Informs the extension that a routine stopped execution and waits for an
    // event, e.g. user interaction. `RoutineWaitingInfo` contains information
    // about what the routine is waiting for (see prototype above).
    static void onRoutineWaiting(RoutineWaitingInfo waitingInfo);

    // Informs the extension that a routine finished.
    static void onRoutineFinished(RoutineFinishedInfo finishedInfo);

    // Informs the extension that an exception occured. The error passed in
    // `ExceptionInfo` is non-recoverable.
    static void onRoutineException(ExceptionInfo exceptionInfo);

    // ----------------- DEPRECATED DIAGNOSTICS API V2 -----------------
    // TODO(b/331540565): Remove legacy APIs.

    // Deprecated. Use `onRoutineFinished` instead.
    // Informs the extension that a memory routine finished.
    static void onMemoryRoutineFinished(
        LegacyMemoryRoutineFinishedInfo finishedInfo);

    // Deprecated. Use `onRoutineFinished` instead.
    // Informs the extension that a volume button routine finished.
    static void onVolumeButtonRoutineFinished(
        LegacyVolumeButtonRoutineFinishedInfo finishedInfo);

    // Deprecated. Use `onRoutineFinished` instead.
    // Informs the extension that a fan routine finished.
    static void onFanRoutineFinished(LegacyFanRoutineFinishedInfo finishedInfo);
  };

  // LINT.ThenChange(//docs/telemetry_extension/api_overview.md)
  // The following is an empty definition, since the IDL compiler only accepts
  // comments over valid definitions.
  callback EOF = void();
};