Commit bfa59294 authored by Andrei-Laurențiu Olteanu's avatar Andrei-Laurențiu Olteanu Committed by Commit Bot

[Telemetry SWX] Add ac power routine

Add converters.

Add implementation to chrome://.

Add implementation to chrome-untrusted://.

Add tests.

Bug: b:162051831
Change-Id: I50146d5c470c987a2f1e0ed39533d860713a71e5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2374148
Commit-Queue: Laurențiu Olteanu <lolteanu@google.com>
Reviewed-by: default avatarOleh Lamzin <lamzin@google.com>
Reviewed-by: default avatarMahmoud Gawad <mgawad@google.com>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804258}
parent 751a970a
......@@ -105,4 +105,19 @@ void DiagnosticsService::RunSmartctlCheckRoutine(
std::move(callback)));
}
void DiagnosticsService::RunAcPowerRoutine(
health::mojom::AcPowerStatusEnum expected_status,
const base::Optional<std::string>& expected_power_type,
RunAcPowerRoutineCallback callback) {
GetService()->RunAcPowerRoutine(
converters::Convert(expected_status), expected_power_type,
base::BindOnce(
[](health::mojom::DiagnosticsService::RunAcPowerRoutineCallback
callback,
cros_healthd::mojom::RunRoutineResponsePtr ptr) {
std::move(callback).Run(converters::ConvertPtr(std::move(ptr)));
},
std::move(callback)));
}
} // namespace chromeos
......@@ -41,6 +41,9 @@ class DiagnosticsService : public health::mojom::DiagnosticsService {
RunBatteryHealthRoutineCallback callback) override;
void RunSmartctlCheckRoutine(
RunSmartctlCheckRoutineCallback callback) override;
void RunAcPowerRoutine(health::mojom::AcPowerStatusEnum expected_status,
const base::Optional<std::string>& expected_power_type,
RunAcPowerRoutineCallback callback) override;
// Ensures that |service_| created and connected to the
// CrosHealthdProbeService.
......
......@@ -175,5 +175,18 @@ std::vector<health::mojom::DiagnosticRoutineEnum> Convert(
return output;
}
cros_healthd::mojom::AcPowerStatusEnum Convert(
health::mojom::AcPowerStatusEnum input) {
switch (input) {
case health::mojom::AcPowerStatusEnum::kConnected:
return cros_healthd::mojom::AcPowerStatusEnum::kConnected;
case health::mojom::AcPowerStatusEnum::kDisconnected:
return cros_healthd::mojom::AcPowerStatusEnum::kDisconnected;
}
NOTREACHED();
return static_cast<cros_healthd::mojom::AcPowerStatusEnum>(
static_cast<int>(cros_healthd::mojom::AcPowerStatusEnum::kMaxValue) + 1);
}
} // namespace converters
} // namespace chromeos
......@@ -56,6 +56,9 @@ cros_healthd::mojom::DiagnosticRoutineCommandEnum Convert(
std::string Convert(mojo::ScopedHandle handle);
cros_healthd::mojom::AcPowerStatusEnum Convert(
health::mojom::AcPowerStatusEnum input);
} // namespace converters
} // namespace chromeos
......
......@@ -66,5 +66,15 @@ TEST(DiagnosticsServiceConvertersTest, ConvertDiagnosticRoutineCommandEnum) {
cros_healthd::DiagnosticRoutineCommandEnum::kRemove);
}
TEST(DiagnosticsServiceConvertersTest, ConvertAcPowerStatusEnum) {
namespace cros_healthd = ::chromeos::cros_healthd::mojom;
namespace health = ::chromeos::health::mojom;
EXPECT_EQ(Convert(health::AcPowerStatusEnum::kConnected),
cros_healthd::AcPowerStatusEnum::kConnected);
EXPECT_EQ(Convert(health::AcPowerStatusEnum::kDisconnected),
cros_healthd::AcPowerStatusEnum::kDisconnected);
}
} // namespace converters
} // namespace chromeos
......@@ -84,6 +84,24 @@ interface DiagnosticsService {
// * |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);
};
// Enumeration of each of the diagnostics routines the platform may support.
......@@ -189,3 +207,11 @@ struct RunRoutineResponse {
// means the routine was unable to be created.
DiagnosticRoutineStatusEnum status;
};
// Enumeration of the possible statuses for a power supply in the AC power
// routine.
[Extensible]
enum AcPowerStatusEnum {
kConnected = 0, // Power supply is connected.
kDisconnected = 1, // Power supply is disconnected.
};
......@@ -26,6 +26,7 @@ dpsl_internal.Message = {
'DiagnosticsService.RunBatteryHealthRoutine',
DIAGNOSTICS_RUN_SMARTCTL_CHECK_ROUTINE:
'DiagnosticsService.RunSmartctlCheckRoutine',
DIAGNOSTICS_RUN_AC_POWER_ROUTINE: 'DiagnosticsService.RunAcPowerRoutine',
PROBE_TELEMETRY_INFO: 'ProbeService.ProbeTelemetryInfo',
};
......@@ -85,6 +86,15 @@ dpsl_internal.DiagnosticsRunBatteryHealthRoutineRequest;
*/
dpsl_internal.DiagnosticsRunSmartctlCheckRoutineRequest;
/**
* Request message sent by the unprivileged context to the privileged
* context to run ac power routine.
* @typedef {{
* expectedStatus: !string,
* expectedPowerType: string}}
*/
dpsl_internal.DiagnosticsRunAcPowerRoutineRequest;
/**
* Response message sent by the privileged context containing routine
* information.
......
......@@ -130,6 +130,22 @@ class DiagnosticsProxy {
throw RangeError(
'enumToUserMessage_ does not contain all items from enum!');
}
const acPowerStatusEnum = chromeos.health.mojom.AcPowerStatusEnum;
/**
* @type { !Map<!string, !chromeos.health.mojom.AcPowerStatusEnum> }
* @const
*/
this.acPowerStatusToEnum_ = new Map([
['connected', acPowerStatusEnum.kConnected],
['disconnected', acPowerStatusEnum.kDisconnected],
]);
if (this.acPowerStatusToEnum_.size !== acPowerStatusEnum.MAX_VALUE + 1) {
throw RangeError(
'acPowerStatusToEnum_ does not contain all items from enum!');
}
}
/**
......@@ -325,6 +341,34 @@ class DiagnosticsProxy {
async handleRunSmartctlCheckRoutine() {
return await getOrCreateDiagnosticsService().runSmartctlCheckRoutine();
};
/**
* Converts expected status string to AcPowerStatusEnum.
* @param { !string } expectedStatus
* @return { !chromeos.health.mojom.AcPowerStatusEnum }
*/
convertPowerStatusToEnum(expectedStatus) {
if (!this.acPowerStatusToEnum_.has(expectedStatus)) {
throw TypeError(
`Diagnostic expected status '${expectedStatus}' is unknown.`);
}
return this.acPowerStatusToEnum_.get(expectedStatus);
}
/**
* Runs ac power routine.
* @param { !Object } message
* @return { !RunRoutineResponsePromise }
*/
async handleRunAcPowerRoutine(message) {
const request =
/** @type {!dpsl_internal.DiagnosticsRunAcPowerRoutineRequest} */ (
message);
const expectedStatus = this.convertPowerStatusToEnum(request.expectedStatus)
return await getOrCreateDiagnosticsService().runAcPowerRoutine(
expectedStatus, request.expectedPowerType);
};
};
const diagnosticsProxy = new DiagnosticsProxy();
......@@ -622,6 +666,12 @@ untrustedMessagePipe.registerHandler(
(message) => diagnosticsProxy.genericRunRoutineHandler(
() => diagnosticsProxy.handleRunSmartctlCheckRoutine(), message));
untrustedMessagePipe.registerHandler(
dpsl_internal.Message.DIAGNOSTICS_RUN_AC_POWER_ROUTINE,
(message) => diagnosticsProxy.genericRunRoutineHandler(
(message) => diagnosticsProxy.handleRunAcPowerRoutine(message),
message));
untrustedMessagePipe.registerHandler(
dpsl_internal.Message.PROBE_TELEMETRY_INFO,
(message) => telemetryProxy.handleProbeTelemetryInfo(message));
......@@ -137,6 +137,31 @@ chromeos.test_support = {};
dpsl_internal.Message.DIAGNOSTICS_RUN_SMARTCTL_CHECK_ROUTINE));
return response;
}
/**
* Requests ac power routine to be run.
* @param { !string } expectedStatus
* @param { !string= } expectedPowerType
* @return { !Promise<!Object> }
* @public
*/
async runAcPowerRoutine(expectedStatus, expectedPowerType) {
const message =
/**
@type {!dpsl_internal.DiagnosticsRunAcPowerRoutineRequest}
*/
({
expectedStatus: expectedStatus,
expectedPowerType: expectedPowerType
});
const response =
/** @type {!Object} */ (await messagePipe.sendMessage(
dpsl_internal.Message.DIAGNOSTICS_RUN_AC_POWER_ROUTINE, message));
if (response instanceof Error) {
throw response;
}
return response;
}
};
/**
......
......@@ -115,6 +115,15 @@ TEST_F('TelemetryExtensionUIBrowserTest', 'ConvertDiagnosticsEnums', () => {
diagnosticsProxy.convertUserMessage(userMessageEnum.kPlugInACPower),
'plug-in-ac-power');
// Unit tests for convertPowerStatusToEnum
const acPowerStatusEnum = chromeos.health.mojom.AcPowerStatusEnum;
assertEquals(
diagnosticsProxy.convertPowerStatusToEnum('connected'),
acPowerStatusEnum.kConnected);
assertEquals(
diagnosticsProxy.convertPowerStatusToEnum('disconnected'),
acPowerStatusEnum.kDisconnected);
testDone();
});
......@@ -368,6 +377,21 @@ TEST_F(
testDone();
});
TEST_F(
'TelemetryExtensionUIBrowserTest',
'UntrustedDiagnosticsRequestRunAcPowerRoutineInvalidInput', async () => {
await runTestInUntrusted(
'UntrustedDiagnosticsRequestRunAcPowerRoutineInvalidInput');
testDone();
});
TEST_F(
'TelemetryExtensionUIBrowserTest',
'UntrustedDiagnosticsRequestRunAcPowerRoutine', async () => {
await runTestInUntrusted('UntrustedDiagnosticsRequestRunAcPowerRoutine');
testDone();
});
TEST_F(
'TelemetryExtensionUIBrowserTest',
'UntrustedRequestTelemetryInfoUnknownCategory', async () => {
......
......@@ -152,6 +152,38 @@ UNTRUSTED_TEST(
assertDeepEquals(response, {id: 123456789, status: 'ready'});
});
// Tests that runAcPowerRoutine throws the correct error
// when invalid enum is passed as input.
UNTRUSTED_TEST(
'UntrustedDiagnosticsRequestRunAcPowerRoutineInvalidInput', async () => {
let caughtError;
try {
await chromeos.diagnostics.runAcPowerRoutine('this-does-not-exist');
} catch (error) {
caughtError = error;
}
assertEquals(caughtError.name, 'TypeError');
assertEquals(
caughtError.message,
`Diagnostic expected status \'this-does-not-exist\' is unknown.`);
});
// Tests that runAcPowerRoutine returns the correct Object when one or two
// parameters are given as input.
UNTRUSTED_TEST('UntrustedDiagnosticsRequestRunAcPowerRoutine', async () => {
const response1 = await chromeos.diagnostics.runAcPowerRoutine('connected');
assertDeepEquals(response1, {id: 123456789, status: 'ready'});
const response2 =
await chromeos.diagnostics.runAcPowerRoutine('connected', 'Mains');
assertDeepEquals(response2, {id: 123456789, status: 'ready'});
const response3 =
await chromeos.diagnostics.runAcPowerRoutine('disconnected', 'Battery');
assertDeepEquals(response3, {id: 123456789, status: 'ready'});
});
// Tests that TelemetryInfo can be successfully requested from
// from chrome-untrusted://.
UNTRUSTED_TEST('UntrustedRequestTelemetryInfo', async () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment