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