Commit ddc23b76 authored by Bailey Berro's avatar Bailey Berro Committed by Commit Bot

Create SystemDataProvider interface

This change defines and implements the SystemDataProvider interface.
This interface will be used by the Diagnostics App to provide
telemetric information about the system. go/cros-diagnostics-dd

- Creates mojo interface for SystemDataProvider.
- Implements GetSystemInfo() method. Additionally functionality to be
implemented in follow up CLs.
- Will be called by Diagnostics UI in a follow-up CL.

Bug: 1128204
Change-Id: If2a490b2a91dd9a0627f28dc523d195d4f148b3f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2402183
Commit-Queue: Bailey Berro <baileyberro@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarZentaro Kavanagh <zentaro@chromium.org>
Reviewed-by: default avatarJimmy Gong <jimmyxgong@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809595}
parent fcf12ecf
......@@ -18,6 +18,7 @@ test("chromeos_components_unittests") {
"//chromeos/components/account_manager:unit_tests",
"//chromeos/components/bloom:unit_tests",
"//chromeos/components/cdm_factory_daemon:unit_tests",
"//chromeos/components/diagnostics_ui/backend:unit_tests",
"//chromeos/components/drivefs:unit_tests",
"//chromeos/components/local_search_service:unit_tests",
"//chromeos/components/local_search_service/mojom:unit_tests",
......
......@@ -13,6 +13,8 @@ static_library("diagnostics_ui") {
]
deps = [
"//chromeos/components/diagnostics_ui/backend",
"//chromeos/components/diagnostics_ui/mojom",
"//chromeos/constants",
"//chromeos/resources:diagnostics_app_resources",
"//content/public/browser",
......
# Copyright 2020 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.
assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
static_library("backend") {
sources = [
"cros_healthd_helpers.cc",
"cros_healthd_helpers.h",
"system_data_provider.cc",
"system_data_provider.h",
]
deps = [
"//base",
"//chromeos/components/diagnostics_ui/mojom",
"//chromeos/services/cros_healthd/public/cpp",
"//chromeos/services/cros_healthd/public/mojom",
]
}
source_set("unit_tests") {
testonly = true
sources = [ "system_data_provider_unittest.cc" ]
deps = [
":backend",
"//base/test:test_support",
"//chromeos/dbus/cros_healthd",
"//chromeos/services/cros_healthd/public/cpp",
"//chromeos/services/cros_healthd/public/mojom",
"//testing/gtest",
]
}
// Copyright 2020 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.
#include "chromeos/components/diagnostics_ui/backend/cros_healthd_helpers.h"
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
namespace chromeos {
namespace diagnostics {
namespace {
using cros_healthd::mojom::BatteryInfo;
using cros_healthd::mojom::BatteryResult;
using cros_healthd::mojom::BatteryResultPtr;
using cros_healthd::mojom::CpuInfo;
using cros_healthd::mojom::CpuResult;
using cros_healthd::mojom::CpuResultPtr;
using cros_healthd::mojom::MemoryInfo;
using cros_healthd::mojom::MemoryResult;
using cros_healthd::mojom::MemoryResultPtr;
using cros_healthd::mojom::SystemInfo;
using cros_healthd::mojom::SystemResult;
using cros_healthd::mojom::SystemResultPtr;
using cros_healthd::mojom::TelemetryInfo;
template <typename TResult, typename TTag>
bool CheckResponse(const TResult& result,
TTag expected_tag,
base::StringPiece type_name) {
if (result.is_null()) {
DVLOG(1) << type_name << " not found in croshealthd response.";
return false;
}
auto tag = result->which();
if (tag == TTag::ERROR) {
DVLOG(1) << "Error retrieving " << type_name
<< "from croshealthd: " << result->get_error()->msg;
return false;
}
DCHECK_EQ(tag, expected_tag);
return true;
}
} // namespace
const BatteryInfo* GetBatteryInfo(const TelemetryInfo& info) {
const BatteryResultPtr& battery_result = info.battery_result;
if (!CheckResponse(battery_result, BatteryResult::Tag::BATTERY_INFO,
"battery info")) {
return nullptr;
}
return battery_result->get_battery_info().get();
}
const CpuInfo* GetCpuInfo(const TelemetryInfo& info) {
const CpuResultPtr& cpu_result = info.cpu_result;
if (!CheckResponse(cpu_result, CpuResult::Tag::CPU_INFO, "cpu info")) {
return nullptr;
}
return cpu_result->get_cpu_info().get();
}
const MemoryInfo* GetMemoryInfo(const TelemetryInfo& info) {
const MemoryResultPtr& memory_result = info.memory_result;
if (!CheckResponse(memory_result, MemoryResult::Tag::MEMORY_INFO,
"memory info")) {
return nullptr;
}
return memory_result->get_memory_info().get();
}
const SystemInfo* GetSystemInfo(const TelemetryInfo& info) {
const SystemResultPtr& system_result = info.system_result;
if (!CheckResponse(system_result, SystemResult::Tag::SYSTEM_INFO,
"system info")) {
return nullptr;
}
return system_result->get_system_info().get();
}
} // namespace diagnostics
} // namespace chromeos
// Copyright 2020 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.
#ifndef CHROMEOS_COMPONENTS_DIAGNOSTICS_UI_BACKEND_CROS_HEALTHD_HELPERS_H_
#define CHROMEOS_COMPONENTS_DIAGNOSTICS_UI_BACKEND_CROS_HEALTHD_HELPERS_H_
namespace cros_healthd {
namespace mojom {
class BatteryInfo;
class CpuInfo;
class MemoryInfo;
class SystemInfo;
class TelemetryInfo;
} // namespace mojom
} // namespace cros_healthd
namespace chromeos {
namespace diagnostics {
// Extracts BatteryInfo from |info|. Logs and returns a nullptr if
// BatteryInfo in not present.
const cros_healthd::mojom::BatteryInfo* GetBatteryInfo(
const cros_healthd::mojom::TelemetryInfo& info);
// Extracts CpuInfo from |info|. Logs and returns a nullptr if CpuInfo
// in not present.
const cros_healthd::mojom::CpuInfo* GetCpuInfo(
const cros_healthd::mojom::TelemetryInfo& info);
// Extracts MemoryInfo from |info|. Logs and returns a nullptr if MemoryInfo
// in not present.
const cros_healthd::mojom::MemoryInfo* GetMemoryInfo(
const cros_healthd::mojom::TelemetryInfo& info);
// Extracts SystemInfo from |info|. Logs and returns a nullptr if SystemInfo
// in not present.
const cros_healthd::mojom::SystemInfo* GetSystemInfo(
const cros_healthd::mojom::TelemetryInfo& info);
} // namespace diagnostics
} // namespace chromeos
#endif // CHROMEOS_COMPONENTS_DIAGNOSTICS_UI_BACKEND_CROS_HEALTHD_HELPERS_H_
// Copyright 2020 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.
#include "chromeos/components/diagnostics_ui/backend/system_data_provider.h"
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/optional.h"
#include "chromeos/components/diagnostics_ui/backend/cros_healthd_helpers.h"
#include "chromeos/services/cros_healthd/public/cpp/service_connection.h"
#include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
namespace chromeos {
namespace diagnostics {
namespace {
namespace healthd = cros_healthd::mojom;
using PhysicalCpuInfos = std::vector<healthd::PhysicalCpuInfoPtr>;
using ProbeCategories = healthd::ProbeCategoryEnum;
void PopulateBoardName(const healthd::SystemInfo& system_info,
mojom::SystemInfo& out_system_info) {
const base::Optional<std::string>& product_name = system_info.product_name;
if (!product_name.has_value()) {
DVLOG(1) << "No board name in SystemInfo response.";
return;
}
out_system_info.board_name = product_name.value();
}
void PopulateCpuInfo(const healthd::CpuInfo& cpu_info,
mojom::SystemInfo& out_system_info) {
const PhysicalCpuInfos& physical_cpus = cpu_info.physical_cpus;
DCHECK_GE(physical_cpus.size(), 1u);
out_system_info.cpu_threads_count = cpu_info.num_total_threads;
// If there is more than one physical cpu on the device, use the name of the
// first CPU.
out_system_info.cpu_model_name = physical_cpus[0]->model_name;
}
void PopulateVersionInfo(const healthd::SystemInfo& system_info,
mojom::SystemInfo& out_system_info) {
out_system_info.version_info =
mojom::VersionInfo::New(system_info.os_version->release_milestone);
}
void PopulateMemorySize(const healthd::MemoryInfo& memory_info,
mojom::SystemInfo& out_system_info) {
out_system_info.total_memory_kib = memory_info.total_memory_kib;
}
void PopulateDeviceCapabilities(const healthd::TelemetryInfo& telemetry_info,
mojom::SystemInfo& out_system_info) {
mojom::DeviceCapabilitiesPtr capabilities = mojom::DeviceCapabilities::New();
capabilities->has_battery = GetBatteryInfo(telemetry_info) != nullptr;
out_system_info.device_capabilities = std::move(capabilities);
}
} // namespace
SystemDataProvider::SystemDataProvider() = default;
SystemDataProvider::~SystemDataProvider() = default;
void SystemDataProvider::GetSystemInfo(GetSystemInfoCallback callback) {
BindCrosHealthdProbeServiceIfNeccessary();
probe_service_->ProbeTelemetryInfo(
{ProbeCategories::kBattery, ProbeCategories::kCpu,
ProbeCategories::kMemory, ProbeCategories::kSystem},
base::BindOnce(&SystemDataProvider::OnSystemInfoProbeResponse,
base::Unretained(this), std::move(callback)));
}
void SystemDataProvider::OnSystemInfoProbeResponse(
GetSystemInfoCallback callback,
healthd::TelemetryInfoPtr info_ptr) {
mojom::SystemInfoPtr system_info = mojom::SystemInfo::New();
if (info_ptr.is_null()) {
LOG(ERROR) << "Null response from croshealthd::ProbeTelemetryInfo.";
std::move(callback).Run(std::move(system_info));
return;
}
const healthd::SystemInfo* system_info_ptr =
diagnostics::GetSystemInfo(*info_ptr);
if (system_info_ptr) {
PopulateBoardName(*system_info_ptr, *system_info.get());
PopulateVersionInfo(*system_info_ptr, *system_info.get());
} else {
LOG(ERROR)
<< "Expected SystemInfo in croshealthd::ProbeTelemetryInfo response";
std::move(callback).Run(std::move(system_info));
return;
}
const healthd::CpuInfo* cpu_info_ptr = GetCpuInfo(*info_ptr);
if (cpu_info_ptr) {
PopulateCpuInfo(*cpu_info_ptr, *system_info.get());
} else {
LOG(ERROR)
<< "Expected CpuInfo in croshealthd::ProbeTelemetryInfo response";
}
const healthd::MemoryInfo* memory_info_ptr = GetMemoryInfo(*info_ptr);
if (memory_info_ptr) {
PopulateMemorySize(*memory_info_ptr, *system_info.get());
} else {
LOG(ERROR)
<< "Expected MemoryInfo in croshealthd::ProbeTelemetryInfo response";
}
PopulateDeviceCapabilities(*info_ptr, *system_info.get());
std::move(callback).Run(std::move(system_info));
}
void SystemDataProvider::BindCrosHealthdProbeServiceIfNeccessary() {
if (!probe_service_ || !probe_service_.is_connected()) {
cros_healthd::ServiceConnection::GetInstance()->GetProbeService(
probe_service_.BindNewPipeAndPassReceiver());
probe_service_.set_disconnect_handler(base::BindOnce(
&SystemDataProvider::OnProbeServiceDisconnect, base::Unretained(this)));
}
}
void SystemDataProvider::OnProbeServiceDisconnect() {
probe_service_.reset();
}
} // namespace diagnostics
} // namespace chromeos
// Copyright 2020 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.
#ifndef CHROMEOS_COMPONENTS_DIAGNOSTICS_UI_BACKEND_SYSTEM_DATA_PROVIDER_H_
#define CHROMEOS_COMPONENTS_DIAGNOSTICS_UI_BACKEND_SYSTEM_DATA_PROVIDER_H_
#include "chromeos/components/diagnostics_ui/mojom/system_data_provider.mojom.h"
#include "chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
namespace chromeos {
namespace diagnostics {
class SystemDataProvider : public mojom::SystemDataProvider {
public:
SystemDataProvider();
~SystemDataProvider() override;
SystemDataProvider(const SystemDataProvider&) = delete;
SystemDataProvider& operator=(const SystemDataProvider&) = delete;
// mojom::SystemDataProvider:
void GetSystemInfo(GetSystemInfoCallback callback) override;
private:
void BindCrosHealthdProbeServiceIfNeccessary();
void OnProbeServiceDisconnect();
void OnSystemInfoProbeResponse(
GetSystemInfoCallback callback,
cros_healthd::mojom::TelemetryInfoPtr info_ptr);
mojo::Remote<cros_healthd::mojom::CrosHealthdProbeService> probe_service_;
};
} // namespace diagnostics
} // namespace chromeos
#endif // CHROMEOS_COMPONENTS_DIAGNOSTICS_UI_BACKEND_SYSTEM_DATA_PROVIDER_H_
// Copyright 2020 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.
#include "chromeos/components/diagnostics_ui/backend/system_data_provider.h"
#include <cstdint>
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/system/sys_info.h"
#include "base/test/bind_test_util.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "chromeos/dbus/cros_healthd/cros_healthd_client.h"
#include "chromeos/dbus/cros_healthd/fake_cros_healthd_client.h"
#include "chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
#include "chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace diagnostics {
namespace {
void SetCrosHealthdSystemInfoResponse(const std::string& board_name,
const std::string& cpu_model,
uint32_t total_memory_kib,
uint16_t cpu_threads_count,
bool has_battery,
const std::string& milestone_version) {
// System info
auto system_info = cros_healthd::mojom::SystemInfo::New();
system_info->product_name = base::Optional<std::string>(board_name);
auto os_version_info = cros_healthd::mojom::OsVersion::New();
os_version_info->release_milestone = milestone_version;
system_info->os_version = std::move(os_version_info);
// Battery info
auto battery_info =
has_battery ? cros_healthd::mojom::BatteryInfo::New() : nullptr;
// Memory info
auto memory_info = cros_healthd::mojom::MemoryInfo::New();
memory_info->total_memory_kib = total_memory_kib;
// CPU info
auto cpu_info = cros_healthd::mojom::CpuInfo::New();
auto physical_cpu_info = cros_healthd::mojom::PhysicalCpuInfo::New();
physical_cpu_info->model_name = cpu_model;
cpu_info->num_total_threads = cpu_threads_count;
cpu_info->physical_cpus.emplace_back(std::move(physical_cpu_info));
auto info = cros_healthd::mojom::TelemetryInfo::New();
info->system_result =
cros_healthd::mojom::SystemResult::NewSystemInfo(std::move(system_info));
info->battery_result = cros_healthd::mojom::BatteryResult::NewBatteryInfo(
std::move(battery_info));
info->memory_result =
cros_healthd::mojom::MemoryResult::NewMemoryInfo(std::move(memory_info));
info->cpu_result =
cros_healthd::mojom::CpuResult::NewCpuInfo(std::move(cpu_info));
cros_healthd::FakeCrosHealthdClient::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
}
} // namespace
class SystemDataProviderTest : public testing::Test {
public:
SystemDataProviderTest() {
chromeos::CrosHealthdClient::InitializeFake();
system_data_provider_ = std::make_unique<SystemDataProvider>();
}
~SystemDataProviderTest() override {
chromeos::CrosHealthdClient::Shutdown();
base::RunLoop().RunUntilIdle();
}
protected:
std::unique_ptr<SystemDataProvider> system_data_provider_;
private:
base::test::TaskEnvironment task_environment_;
};
TEST_F(SystemDataProviderTest, GetSystemInfo) {
const std::string expected_board_name = "board_name";
const std::string expected_cpu_model = "cpu_model";
const uint32_t expected_total_memory_kib = 1234;
const uint16_t expected_cpu_threads_count = 5678;
const bool expected_has_battery = true;
const std::string expected_milestone_version = "M99";
SetCrosHealthdSystemInfoResponse(
expected_board_name, expected_cpu_model, expected_total_memory_kib,
expected_cpu_threads_count, expected_has_battery,
expected_milestone_version);
base::RunLoop run_loop;
system_data_provider_->GetSystemInfo(
base::BindLambdaForTesting([&](mojom::SystemInfoPtr ptr) {
ASSERT_TRUE(ptr);
EXPECT_EQ(expected_board_name, ptr->board_name);
EXPECT_EQ(expected_cpu_model, ptr->cpu_model_name);
EXPECT_EQ(expected_total_memory_kib, ptr->total_memory_kib);
EXPECT_EQ(expected_cpu_threads_count, ptr->cpu_threads_count);
EXPECT_EQ(expected_milestone_version,
ptr->version_info->milestone_version);
EXPECT_EQ(expected_has_battery, ptr->device_capabilities->has_battery);
run_loop.Quit();
}));
run_loop.Run();
}
TEST_F(SystemDataProviderTest, NoBattery) {
const std::string expected_board_name = "board_name";
const std::string expected_cpu_model = "cpu_model";
const uint32_t expected_total_memory_kib = 1234;
const uint16_t expected_cpu_threads_count = 5678;
const bool expected_has_battery = false;
const std::string expected_milestone_version = "M99";
SetCrosHealthdSystemInfoResponse(
expected_board_name, expected_cpu_model, expected_total_memory_kib,
expected_cpu_threads_count, expected_has_battery,
expected_milestone_version);
base::RunLoop run_loop;
system_data_provider_->GetSystemInfo(
base::BindLambdaForTesting([&](mojom::SystemInfoPtr ptr) {
ASSERT_TRUE(ptr);
EXPECT_EQ(expected_board_name, ptr->board_name);
EXPECT_EQ(expected_cpu_model, ptr->cpu_model_name);
EXPECT_EQ(expected_total_memory_kib, ptr->total_memory_kib);
EXPECT_EQ(expected_cpu_threads_count, ptr->cpu_threads_count);
EXPECT_EQ(expected_milestone_version,
ptr->version_info->milestone_version);
EXPECT_EQ(expected_has_battery, ptr->device_capabilities->has_battery);
run_loop.Quit();
}));
run_loop.Run();
}
} // namespace diagnostics
} // namespace chromeos
# Copyright 2020 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.
import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
sources = [ "system_data_provider.mojom" ]
public_deps = [ "//mojo/public/mojom/base" ]
}
per-file *.mojom=set noparent
per-file *.mojom=file://ipc/SECURITY_OWNERS
// Copyright 2020 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.
module chromeos.diagnostics.mojom;
// Contains the capabilities of the device.
struct DeviceCapabilities {
bool has_battery;
};
// Contains information about the OS version on the device.
struct VersionInfo {
string milestone_version;
};
// Contains a snapshot of static system information.
struct SystemInfo {
string board_name;
string cpu_model_name;
uint32 total_memory_kib;
uint16 cpu_threads_count;
VersionInfo version_info;
DeviceCapabilities device_capabilities;
};
// Provides telemetric information about the system. This API is exposed to the
// Diagnostics SWA.
interface SystemDataProvider {
// Returns a snapshot of system information. |system_info| is static
// information that does not change during the lifetime of the service.
GetSystemInfo() => (SystemInfo system_info);
};
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