Skip to content

Commit

Permalink
Reland "[fuchsia] Add fuchsia.hwinfo.ProductInfo support"
Browse files Browse the repository at this point in the history
This is a reland of commit d2ab1c0.

The fix is to temporarily change the `ZX_CHECK` to a DLOG and re-add
it once the service routing is appropriately configured in the fuchsia
tree.

Original change's description:
> [fuchsia] Add fuchsia.hwinfo.ProductInfo support
>
> https://fuchsia.dev/reference/fidl/fuchsia.hwinfo#ProductInfo
> holds a number of pieces of information about the device that
> chromium is running on. For now, manufacturer and model are being
> used for sync to help identify different machines that settings
> are synced on.
>
> Bug: 1311066
> Change-Id: Ie10b53e8581829c7d99080d49dc685014551c20f
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3572507
> Reviewed-by: Kevin Marshall <kmarshall@chromium.org>
> Reviewed-by: Alex Gough <ajgo@chromium.org>
> Reviewed-by: Scott Violet <sky@chromium.org>
> Commit-Queue: Bryant Chandler <bryantchandler@chromium.org>
> Reviewed-by: Wez <wez@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1008023}

Bug: 1311066
Change-Id: I4f423052bad2b6d772710fcac8cec21405b21a9b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3679883
Reviewed-by: Wez <wez@chromium.org>
Reviewed-by: Alex Gough <ajgo@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Commit-Queue: Bryant Chandler <bryantchandler@chromium.org>
Reviewed-by: David Dorwin <ddorwin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1014444}
  • Loading branch information
Bryant Chandler authored and Chromium LUCI CQ committed Jun 15, 2022
1 parent dac98e6 commit 6cf7b6b
Show file tree
Hide file tree
Showing 22 changed files with 223 additions and 41 deletions.
3 changes: 3 additions & 0 deletions base/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1878,6 +1878,7 @@ mixed_component("base") {

deps += [
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.buildinfo",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.hwinfo",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.media",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sys",
"//third_party/fuchsia-sdk/sdk/pkg/async-default",
Expand Down Expand Up @@ -3766,6 +3767,7 @@ test("base_unittests") {
"fuchsia/service_directory_test_base.h",
"fuchsia/service_provider_impl_unittest.cc",
"fuchsia/system_build_info_unittest.cc",
"fuchsia/system_product_info_unittest.cc",
"fuchsia/test_component_context_for_process_unittest.cc",
"fuchsia/time_zone_data_unittest.cc",
"message_loop/fd_watch_controller_posix_unittest.cc",
Expand All @@ -3777,6 +3779,7 @@ test("base_unittests") {
":test_log_listener_safe",
":testfidl",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.buildinfo",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.hwinfo",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.logger",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem",
Expand Down
49 changes: 31 additions & 18 deletions base/fuchsia/system_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,45 @@
#include "base/fuchsia/system_info.h"

#include <fuchsia/buildinfo/cpp/fidl.h>
#include <fuchsia/hwinfo/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>

#include "base/check.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/process_context.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_restrictions.h"

namespace base {

namespace {

fuchsia::buildinfo::BuildInfo FetchSystemBuildInfo() {
ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::WILL_BLOCK);

fuchsia::buildinfo::ProviderSyncPtr build_info_provider_sync;
ComponentContextForProcess()->svc()->Connect(
build_info_provider_sync.NewRequest());

fuchsia::buildinfo::BuildInfo build_info;
zx_status_t status = build_info_provider_sync->GetBuildInfo(&build_info);
ZX_DCHECK(status == ZX_OK, status);
DCHECK(!build_info.IsEmpty()) << "FIDL service returned empty BuildInfo";
return build_info;
}

// Returns this process's BuildInfo object.
// Returns this process's cached object for `BuildInfo`.
fuchsia::buildinfo::BuildInfo& CachedBuildInfo() {
static NoDestructor<fuchsia::buildinfo::BuildInfo> build_info;
return *build_info;
}

// Synchronously fetches BuildInfo from the system and caches it for use in this
// process.
void FetchAndCacheBuildInfo() {
DCHECK(CachedBuildInfo().IsEmpty()) << "Only call once per process";

fuchsia::buildinfo::ProviderSyncPtr provider_sync;
ComponentContextForProcess()->svc()->Connect(provider_sync.NewRequest());

zx_status_t status = provider_sync->GetBuildInfo(&CachedBuildInfo());
ZX_CHECK(status == ZX_OK, status);
CHECK(!CachedBuildInfo().IsEmpty());
}

} // namespace

void FetchAndCacheSystemInfo() {
DCHECK(CachedBuildInfo().IsEmpty()) << "Only call once per process";
CachedBuildInfo() = FetchSystemBuildInfo();
ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::WILL_BLOCK);
FetchAndCacheBuildInfo();
}

const fuchsia::buildinfo::BuildInfo& GetCachedBuildInfo() {
Expand All @@ -51,6 +52,18 @@ const fuchsia::buildinfo::BuildInfo& GetCachedBuildInfo() {
return CachedBuildInfo();
}

// Synchronously fetches ProductInfo from the system
fuchsia::hwinfo::ProductInfo GetProductInfo() {
ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::WILL_BLOCK);
fuchsia::hwinfo::ProductSyncPtr provider_sync;
ComponentContextForProcess()->svc()->Connect(provider_sync.NewRequest());

fuchsia::hwinfo::ProductInfo product_info;
zx_status_t status = provider_sync->GetInfo(&product_info);
ZX_DLOG_IF(ERROR, status != ZX_OK, status);
return product_info;
}

void ClearCachedSystemInfoForTesting() {
CachedBuildInfo() = {};
}
Expand Down
22 changes: 14 additions & 8 deletions base/fuchsia/system_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,31 @@
#define BASE_FUCHSIA_SYSTEM_INFO_H_

#include "base/base_export.h"
#include "base/strings/string_piece_forward.h"

namespace fuchsia {
namespace buildinfo {
namespace fuchsia::buildinfo {
class BuildInfo;
}
} // namespace fuchsia
namespace fuchsia::hwinfo {
class ProductInfo;
}

namespace base {

// Fetches the build info from the system and caches it before returning.
// Must be called in each process before calling other non-test functions.
// Makes a blocking call to fetch the info from the system and caches it
// before returning. Must be called in each process during the initialization
// phase.
BASE_EXPORT void FetchAndCacheSystemInfo();

// Returns the cached build info.
BASE_EXPORT const fuchsia::buildinfo::BuildInfo& GetCachedBuildInfo();

// Reset the cached BuildInfo to empty so that FetchAndCacheSystemInfo()
// can be called again in this process.
// Synchronously fetches the system ProductInfo.
// Returns empty ProductInfo if the required service is unavailable or returns
// an error.
BASE_EXPORT fuchsia::hwinfo::ProductInfo GetProductInfo();

// Resets the cached system info to empty so that
// FetchAndCacheSystemInfo() can be called again in this process.
BASE_EXPORT void ClearCachedSystemInfoForTesting();

} // namespace base
Expand Down
133 changes: 133 additions & 0 deletions base/fuchsia/system_product_info_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Copyright 2022 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 "base/callback_forward.h"
#include "base/fuchsia/system_info.h"

#include <fuchsia/buildinfo/cpp/fidl.h>
#include <fuchsia/hwinfo/cpp/fidl.h>
#include <fuchsia/hwinfo/cpp/fidl_test_base.h>
#include <memory>

#include "base/bind.h"
#include "base/fuchsia/scoped_service_binding.h"
#include "base/fuchsia/scoped_service_publisher.h"
#include "base/fuchsia/test_component_context_for_process.h"
#include "base/location.h"
#include "base/run_loop.h"
#include "base/strings/string_piece_forward.h"
#include "base/test/bind.h"
#include "base/test/gtest_util.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "base/threading/sequence_bound.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

namespace {

class FakeHardwareInfoProduct
: public fuchsia::hwinfo::testing::Product_TestBase {
public:
FakeHardwareInfoProduct(const base::StringPiece model,
const base::StringPiece manufacturer,
sys::OutgoingDirectory* outgoing_services)
: model_(model),
manufacturer_(manufacturer),
binding_(outgoing_services, this) {}
FakeHardwareInfoProduct(const FakeHardwareInfoProduct&) = delete;
FakeHardwareInfoProduct& operator=(const FakeHardwareInfoProduct&) = delete;
~FakeHardwareInfoProduct() override = default;

// fuchsia::hwinfo::testing::Provider_TestBase implementation
void GetInfo(GetInfoCallback callback) override {
fuchsia::hwinfo::ProductInfo product_info;
product_info.set_model(model_);
product_info.set_manufacturer(manufacturer_);
callback(std::move(product_info));
}
void NotImplemented_(const std::string& name) final {
ADD_FAILURE() << "Unexpected call: " << name;
}

private:
std::string model_;
std::string manufacturer_;
ScopedServiceBinding<fuchsia::hwinfo::Product> binding_;
};

} // namespace

// Uses a fake "fuchsia.hwinfo.Product" implementation.
// clears the cached ProductInfo to ensure that each test starts with no cached
// ProductInfo and that subsequent tests runs do not use fake values.
class ProductInfoTest : public testing::Test {
protected:
ProductInfoTest()
: task_environment_(
base::test::SingleThreadTaskEnvironment::MainThreadType::IO),
thread_("ProductInfo Retrieval Thread") {
thread_.StartWithOptions(
base::Thread::Options(base::MessagePumpType::IO, 0));
ClearCachedSystemInfoForTesting();
component_context_.AddService(fuchsia::buildinfo::Provider::Name_);
}
~ProductInfoTest() override { ClearCachedSystemInfoForTesting(); }

// Fetch the product info in a separate thread, while servicing the
// FIDL fake implementation on the main thread.
fuchsia::hwinfo::ProductInfo GetProductInfoViaTask() {
fuchsia::hwinfo::ProductInfo product_info;
base::RunLoop run_loop;
thread_.task_runner()->PostTaskAndReplyWithResult(
FROM_HERE, base::BindOnce(&GetProductInfo),
base::BindOnce(
[](base::RunLoop& run_loop,
fuchsia::hwinfo::ProductInfo& product_info,
fuchsia::hwinfo::ProductInfo result) {
product_info = std::move(result);
run_loop.Quit();
},
std::ref(run_loop), std::ref(product_info)));
run_loop.Run();
return product_info;
}

base::test::SingleThreadTaskEnvironment task_environment_;
TestComponentContextForProcess component_context_;
base::Thread thread_;
};

using ProductInfoDeathTest = ProductInfoTest;

TEST_F(ProductInfoTest, GetProductInfoReturnsFakedValues) {
FakeHardwareInfoProduct hwinfo_product_provider(
"test.model", "test.manufacturer",
component_context_.additional_services());

const auto product_info = GetProductInfoViaTask();
EXPECT_EQ(product_info.model(), "test.model");
EXPECT_EQ(product_info.manufacturer(), "test.manufacturer");
}

TEST_F(ProductInfoTest, SystemServiceReturnsValidValues) {
component_context_.AddService(fuchsia::hwinfo::Product::Name_);

const auto product_info = GetProductInfoViaTask();
EXPECT_TRUE(product_info.has_model());
EXPECT_FALSE(product_info.model().empty());

EXPECT_TRUE(product_info.has_manufacturer());
EXPECT_FALSE(product_info.manufacturer().empty());
}

// TODO(crbug.com/101396): Re-enable once all clients
// provide this service.
TEST_F(ProductInfoDeathTest, DISABLED_DcheckOnServiceNotPresent) {
EXPECT_DCHECK_DEATH_WITH(GetProductInfoViaTask(), "ZX_ERR_PEER_CLOSED");
}

} // namespace base
2 changes: 1 addition & 1 deletion base/system/sys_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ void SysInfo::GetHardwareInfo(base::OnceCallback<void(HardwareInfo)> callback) {
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {}, base::BindOnce(&GetHardwareInfoSync), std::move(callback));
#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock()}, base::BindOnce(&GetHardwareInfoSync),
std::move(callback));
Expand Down
11 changes: 11 additions & 0 deletions base/system/sys_info_fuchsia.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "base/system/sys_info.h"

#include <fuchsia/buildinfo/cpp/fidl.h>
#include <fuchsia/hwinfo/cpp/fidl.h>
#include <sys/statvfs.h>
#include <zircon/syscalls.h>

Expand Down Expand Up @@ -206,4 +207,14 @@ size_t SysInfo::VMAllocationGranularity() {
return getpagesize();
}

SysInfo::HardwareInfo SysInfo::GetHardwareInfoSync() {
const auto product_info = GetProductInfo();

return {
.manufacturer =
product_info.has_manufacturer() ? product_info.manufacturer() : "",
.model = product_info.has_model() ? product_info.model() : "",
};
}

} // namespace base
2 changes: 1 addition & 1 deletion base/system/sys_info_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ TEST_F(SysInfoTest, GetHardwareInfo) {
EXPECT_TRUE(IsStringUTF8(hardware_info->model));
bool empty_result_expected =
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN) || \
BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_FUCHSIA)
false;
#else
true;
Expand Down
7 changes: 1 addition & 6 deletions build/config/fuchsia/test/minimum.shard.test-cml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,6 @@
}
],
use: [
{
// Required by the build-info-service child.
directory: "build-info",
rights: [ "r*" ],
path: "/config/build-info",
},
{
directory: "config-data",
rights: [ "r*" ],
Expand Down Expand Up @@ -64,6 +58,7 @@
},
{
protocol: [
"fuchsia.hwinfo.Product",
"fuchsia.media.ProfileProvider",
"fuchsia.process.Launcher",
"fuchsia.sys.Loader",
Expand Down
7 changes: 7 additions & 0 deletions build/config/fuchsia/test/minimum_capabilities.test-cmx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
"fuchsia.test": {
"injected-services": {
"fuchsia.buildinfo.Provider": "fuchsia-pkg://fuchsia.com/build-info-service#meta/build-info.cmx",
"fuchsia.factory.MiscFactoryStoreProvider": [
"fuchsia-pkg://fuchsia.com/fake_factory_store_providers#meta/misc.cmx",
"--config=/config/data/fuchsia.factory.MiscFactoryStoreProvider.config"
],
"fuchsia.hwinfo.Product": "fuchsia-pkg://fuchsia.com/hwinfo#meta/hwinfo.cmx",
"fuchsia.intl.PropertyProvider": "fuchsia-pkg://fuchsia.com/intl_property_manager#meta/intl_property_manager_v1.cmx"
},
"system-services": [
Expand All @@ -19,6 +24,8 @@
],
"services": [
"fuchsia.buildinfo.Provider",
"fuchsia.factory.MiscFactoryStoreProvider",
"fuchsia.hwinfo.Product",
"fuchsia.intl.PropertyProvider",
"fuchsia.logger.LogSink",
"fuchsia.media.ProfileProvider",
Expand Down
1 change: 1 addition & 0 deletions chrome/app/chrome.cml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"fuchsia.device.NameProvider",
"fuchsia.element.GraphicalPresenter",
"fuchsia.fonts.Provider",
"fuchsia.hwinfo.Product",
"fuchsia.input.virtualkeyboard.ControllerCreator",
"fuchsia.intl.PropertyProvider",
"fuchsia.media.Audio",
Expand Down
1 change: 1 addition & 0 deletions chrome/app/chrome_v1.cmx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"fuchsia.device.NameProvider",
"fuchsia.element.GraphicalPresenter",
"fuchsia.fonts.Provider",
"fuchsia.hwinfo.Product",
"fuchsia.input.virtualkeyboard.ControllerCreator",
"fuchsia.intl.PropertyProvider",
"fuchsia.logger.LogSink",
Expand Down
2 changes: 1 addition & 1 deletion content/public/test/browser_test_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ void BrowserTestBase::SetUp() {

ui::fuchsia::IgnorePresentCallsForTest();

// Clear the per-process cached BuildInfo, which was initialized by
// Clear the per-process cached system info, which was initialized by
// TestSuite::Initialize(), to prevent a DCHECK for multiple calls during
// in-process browser tests. There is not a single TestSuite for all browser
// tests and some use the cached values, so skipping the earlier
Expand Down
1 change: 1 addition & 0 deletions content/shell/fuchsia/content_shell.cmx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"fuchsia.buildinfo.Provider",
"fuchsia.device.NameProvider",
"fuchsia.fonts.Provider",
"fuchsia.hwinfo.Product",
"fuchsia.input.virtualkeyboard.ControllerCreator",
"fuchsia.intl.PropertyProvider",
"fuchsia.logger.LogSink",
Expand Down
Loading

0 comments on commit 6cf7b6b

Please sign in to comment.