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( ...@@ -105,4 +105,19 @@ void DiagnosticsService::RunSmartctlCheckRoutine(
std::move(callback))); 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 } // namespace chromeos
...@@ -41,6 +41,9 @@ class DiagnosticsService : public health::mojom::DiagnosticsService { ...@@ -41,6 +41,9 @@ class DiagnosticsService : public health::mojom::DiagnosticsService {
RunBatteryHealthRoutineCallback callback) override; RunBatteryHealthRoutineCallback callback) override;
void RunSmartctlCheckRoutine( void RunSmartctlCheckRoutine(
RunSmartctlCheckRoutineCallback callback) override; 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 // Ensures that |service_| created and connected to the
// CrosHealthdProbeService. // CrosHealthdProbeService.
......
...@@ -175,5 +175,18 @@ std::vector<health::mojom::DiagnosticRoutineEnum> Convert( ...@@ -175,5 +175,18 @@ std::vector<health::mojom::DiagnosticRoutineEnum> Convert(
return output; 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 converters
} // namespace chromeos } // namespace chromeos
...@@ -56,6 +56,9 @@ cros_healthd::mojom::DiagnosticRoutineCommandEnum Convert( ...@@ -56,6 +56,9 @@ cros_healthd::mojom::DiagnosticRoutineCommandEnum Convert(
std::string Convert(mojo::ScopedHandle handle); std::string Convert(mojo::ScopedHandle handle);
cros_healthd::mojom::AcPowerStatusEnum Convert(
health::mojom::AcPowerStatusEnum input);
} // namespace converters } // namespace converters
} // namespace chromeos } // namespace chromeos
......
...@@ -66,5 +66,15 @@ TEST(DiagnosticsServiceConvertersTest, ConvertDiagnosticRoutineCommandEnum) { ...@@ -66,5 +66,15 @@ TEST(DiagnosticsServiceConvertersTest, ConvertDiagnosticRoutineCommandEnum) {
cros_healthd::DiagnosticRoutineCommandEnum::kRemove); 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 converters
} // namespace chromeos } // namespace chromeos
...@@ -84,6 +84,24 @@ interface DiagnosticsService { ...@@ -84,6 +84,24 @@ interface DiagnosticsService {
// * |response| - contains a unique identifier and status for the created // * |response| - contains a unique identifier and status for the created
// routine. // routine.
RunSmartctlCheckRoutine() => (RunRoutineResponse response); 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. // Enumeration of each of the diagnostics routines the platform may support.
...@@ -189,3 +207,11 @@ struct RunRoutineResponse { ...@@ -189,3 +207,11 @@ struct RunRoutineResponse {
// means the routine was unable to be created. // means the routine was unable to be created.
DiagnosticRoutineStatusEnum status; 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 = { ...@@ -26,6 +26,7 @@ dpsl_internal.Message = {
'DiagnosticsService.RunBatteryHealthRoutine', 'DiagnosticsService.RunBatteryHealthRoutine',
DIAGNOSTICS_RUN_SMARTCTL_CHECK_ROUTINE: DIAGNOSTICS_RUN_SMARTCTL_CHECK_ROUTINE:
'DiagnosticsService.RunSmartctlCheckRoutine', 'DiagnosticsService.RunSmartctlCheckRoutine',
DIAGNOSTICS_RUN_AC_POWER_ROUTINE: 'DiagnosticsService.RunAcPowerRoutine',
PROBE_TELEMETRY_INFO: 'ProbeService.ProbeTelemetryInfo', PROBE_TELEMETRY_INFO: 'ProbeService.ProbeTelemetryInfo',
}; };
...@@ -85,6 +86,15 @@ dpsl_internal.DiagnosticsRunBatteryHealthRoutineRequest; ...@@ -85,6 +86,15 @@ dpsl_internal.DiagnosticsRunBatteryHealthRoutineRequest;
*/ */
dpsl_internal.DiagnosticsRunSmartctlCheckRoutineRequest; 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 * Response message sent by the privileged context containing routine
* information. * information.
......
...@@ -130,6 +130,22 @@ class DiagnosticsProxy { ...@@ -130,6 +130,22 @@ class DiagnosticsProxy {
throw RangeError( throw RangeError(
'enumToUserMessage_ does not contain all items from enum!'); '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 { ...@@ -325,6 +341,34 @@ class DiagnosticsProxy {
async handleRunSmartctlCheckRoutine() { async handleRunSmartctlCheckRoutine() {
return await getOrCreateDiagnosticsService().runSmartctlCheckRoutine(); 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(); const diagnosticsProxy = new DiagnosticsProxy();
...@@ -622,6 +666,12 @@ untrustedMessagePipe.registerHandler( ...@@ -622,6 +666,12 @@ untrustedMessagePipe.registerHandler(
(message) => diagnosticsProxy.genericRunRoutineHandler( (message) => diagnosticsProxy.genericRunRoutineHandler(
() => diagnosticsProxy.handleRunSmartctlCheckRoutine(), message)); () => diagnosticsProxy.handleRunSmartctlCheckRoutine(), message));
untrustedMessagePipe.registerHandler(
dpsl_internal.Message.DIAGNOSTICS_RUN_AC_POWER_ROUTINE,
(message) => diagnosticsProxy.genericRunRoutineHandler(
(message) => diagnosticsProxy.handleRunAcPowerRoutine(message),
message));
untrustedMessagePipe.registerHandler( untrustedMessagePipe.registerHandler(
dpsl_internal.Message.PROBE_TELEMETRY_INFO, dpsl_internal.Message.PROBE_TELEMETRY_INFO,
(message) => telemetryProxy.handleProbeTelemetryInfo(message)); (message) => telemetryProxy.handleProbeTelemetryInfo(message));
...@@ -137,6 +137,31 @@ chromeos.test_support = {}; ...@@ -137,6 +137,31 @@ chromeos.test_support = {};
dpsl_internal.Message.DIAGNOSTICS_RUN_SMARTCTL_CHECK_ROUTINE)); dpsl_internal.Message.DIAGNOSTICS_RUN_SMARTCTL_CHECK_ROUTINE));
return response; 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', () => { ...@@ -115,6 +115,15 @@ TEST_F('TelemetryExtensionUIBrowserTest', 'ConvertDiagnosticsEnums', () => {
diagnosticsProxy.convertUserMessage(userMessageEnum.kPlugInACPower), diagnosticsProxy.convertUserMessage(userMessageEnum.kPlugInACPower),
'plug-in-ac-power'); '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(); testDone();
}); });
...@@ -368,6 +377,21 @@ TEST_F( ...@@ -368,6 +377,21 @@ TEST_F(
testDone(); testDone();
}); });
TEST_F(
'TelemetryExtensionUIBrowserTest',
'UntrustedDiagnosticsRequestRunAcPowerRoutineInvalidInput', async () => {
await runTestInUntrusted(
'UntrustedDiagnosticsRequestRunAcPowerRoutineInvalidInput');
testDone();
});
TEST_F(
'TelemetryExtensionUIBrowserTest',
'UntrustedDiagnosticsRequestRunAcPowerRoutine', async () => {
await runTestInUntrusted('UntrustedDiagnosticsRequestRunAcPowerRoutine');
testDone();
});
TEST_F( TEST_F(
'TelemetryExtensionUIBrowserTest', 'TelemetryExtensionUIBrowserTest',
'UntrustedRequestTelemetryInfoUnknownCategory', async () => { 'UntrustedRequestTelemetryInfoUnknownCategory', async () => {
......
...@@ -152,6 +152,38 @@ UNTRUSTED_TEST( ...@@ -152,6 +152,38 @@ UNTRUSTED_TEST(
assertDeepEquals(response, {id: 123456789, status: 'ready'}); 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 // Tests that TelemetryInfo can be successfully requested from
// from chrome-untrusted://. // from chrome-untrusted://.
UNTRUSTED_TEST('UntrustedRequestTelemetryInfo', async () => { 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