Skip to content

Commit

Permalink
featured: Add FeaturedClient and Fake
Browse files Browse the repository at this point in the history
This CL implements boilerplate code for FeaturedClient and
FakeFeaturedClient.

To support early platform finch, we add a FeaturedClient to pass a new
safe seed via the HandleSeedFetched dbus method whenever Chrome successfully fetches a new seed.

BUG=b:265878189
TEST=unit tests

Change-Id: I38b923f855fba24f5c4f800ca88294db259bfd4f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4175304
Reviewed-by: Steven Bennetts <stevenjb@chromium.org>
Commit-Queue: Kendrake Tsui <kendraketsui@google.com>
Reviewed-by: Miriam Zimmerman <mutexlox@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1100509}
  • Loading branch information
Kendrake Tsui authored and Chromium LUCI CQ committed Feb 2, 2023
1 parent 2713078 commit 10cefd7
Show file tree
Hide file tree
Showing 7 changed files with 552 additions and 0 deletions.
1 change: 1 addition & 0 deletions chromeos/ash/components/dbus/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ source_set("unit_tests") {
"//chromeos/ash/components/dbus/cryptohome:attestation_proto",
"//chromeos/ash/components/dbus/dlcservice:unit_tests",
"//chromeos/ash/components/dbus/easy_unlock:unit_tests",
"//chromeos/ash/components/dbus/featured:unit_tests",
"//chromeos/ash/components/dbus/fwupd:test_support",
"//chromeos/ash/components/dbus/gnubby:unit_tests",
"//chromeos/ash/components/dbus/hermes:test_support",
Expand Down
48 changes: 48 additions & 0 deletions chromeos/ash/components/dbus/featured/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/chromeos/ui_mode.gni")
import("//third_party/protobuf/proto_library.gni")

assert(is_chromeos_ash)

component("featured") {
defines = [ "IS_CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED_IMPL" ]

deps = [
":proto",
"//base",
"//dbus",
]

sources = [
"fake_featured_client.cc",
"fake_featured_client.h",
"featured_client.cc",
"featured_client.h",
]
}

source_set("unit_tests") {
testonly = true

deps = [
":featured",
":proto",
"//base",
"//base/test:test_support",
"//dbus",
"//dbus:test_support",
"//testing/gmock",
"//testing/gtest",
]

sources = [ "featured_client_unittest.cc" ]
}

proto_library("proto") {
sources = [ "//third_party/cros_system_api/dbus/featured/featured.proto" ]

proto_out_dir = "chromeos/ash/components/dbus/featured"
}
48 changes: 48 additions & 0 deletions chromeos/ash/components/dbus/featured/fake_featured_client.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/ash/components/dbus/featured/fake_featured_client.h"

#include <string>

#include "base/check_op.h"
#include "base/functional/callback.h"
#include "chromeos/ash/components/dbus/featured/featured.pb.h"
#include "dbus/object_proxy.h"

namespace ash::featured {

namespace {

// Used to track the fake instance, mirrors the instance in the base class.
FakeFeaturedClient* g_instance = nullptr;

} // namespace

FakeFeaturedClient::FakeFeaturedClient() {
DCHECK(!g_instance);
g_instance = this;
}

FakeFeaturedClient::~FakeFeaturedClient() {
DCHECK_EQ(this, g_instance);
g_instance = nullptr;
}

// static
FakeFeaturedClient* FakeFeaturedClient::Get() {
return g_instance;
}

void FakeFeaturedClient::SetCallbackSuccess(bool success) {
success_ = success;
}

void FakeFeaturedClient::HandleSeedFetched(
const ::featured::SeedDetails& safe_seed,
base::OnceCallback<void(bool success)> callback) {
std::move(callback).Run(success_);
}

} // namespace ash::featured
43 changes: 43 additions & 0 deletions chromeos/ash/components/dbus/featured/fake_featured_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED_FAKE_FEATURED_CLIENT_H_
#define CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED_FAKE_FEATURED_CLIENT_H_

#include "base/component_export.h"
#include "base/functional/callback.h"
#include "chromeos/ash/components/dbus/featured/featured.pb.h"
#include "chromeos/ash/components/dbus/featured/featured_client.h"

namespace ash::featured {

// Fake implementation of FeaturedClient.
class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED) FakeFeaturedClient
: public FeaturedClient {
public:
FakeFeaturedClient();
FakeFeaturedClient(const FakeFeaturedClient&) = delete;
FakeFeaturedClient& operator=(const FakeFeaturedClient&) = delete;
~FakeFeaturedClient() override;

// Returns the global FakeFeaturedClient instance. Returns `nullptr` if
// it is not initialized.
static FakeFeaturedClient* Get();

// Sets the callback parameter for `HandleSeedFetched`.
void SetCallbackSuccess(bool success);

// |callback| is run with true by default. Call |SetCallbackSuccess|
// to change the callback parameter.
void HandleSeedFetched(
const ::featured::SeedDetails& safe_seed,
base::OnceCallback<void(bool success)> callback) override;

private:
bool success_ = true;
};

} // namespace ash::featured

#endif // CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED_FAKE_FEATURED_CLIENT_H_
109 changes: 109 additions & 0 deletions chromeos/ash/components/dbus/featured/featured_client.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/ash/components/dbus/featured/featured_client.h"

#include <string>

#include <base/logging.h>
#include "base/functional/callback.h"
#include "chromeos/ash/components/dbus/featured/fake_featured_client.h"
#include "chromeos/ash/components/dbus/featured/featured.pb.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace ash::featured {

namespace {

FeaturedClient* g_instance = nullptr;

// Production implementation of FeaturedClient.
class FeaturedClientImpl : public FeaturedClient {
public:
FeaturedClientImpl() = default;

FeaturedClientImpl(const FeaturedClient&) = delete;
FeaturedClientImpl operator=(const FeaturedClient&) = delete;

~FeaturedClientImpl() override = default;

void Init(dbus::Bus* const bus) {
featured_service_proxy_ =
bus->GetObjectProxy(::featured::kFeaturedServiceName,
dbus::ObjectPath(::featured::kFeaturedServicePath));
}

void HandleSeedFetchedResponse(
base::OnceCallback<void(bool success)> callback,
dbus::Response* response) {
if (!response ||
response->GetMessageType() != dbus::Message::MESSAGE_METHOD_RETURN) {
LOG(WARNING) << "Received invalid response for HandleSeedFetched";
std::move(callback).Run(false);
return;
}
std::move(callback).Run(true);
}

void HandleSeedFetched(
const ::featured::SeedDetails& safe_seed,
base::OnceCallback<void(bool success)> callback) override {
dbus::MethodCall method_call(::featured::kFeaturedInterface,
"HandleSeedFetched");

dbus::MessageWriter writer(&method_call);
writer.AppendProtoAsArrayOfBytes(safe_seed);

featured_service_proxy_->CallMethod(
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::BindOnce(&FeaturedClientImpl::HandleSeedFetchedResponse,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

private:
dbus::ObjectProxy* featured_service_proxy_ = nullptr;

// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<FeaturedClientImpl> weak_ptr_factory_{this};
};

} // namespace

FeaturedClient::FeaturedClient() {
DCHECK(!g_instance);
g_instance = this;
}

FeaturedClient::~FeaturedClient() {
DCHECK_EQ(this, g_instance);
g_instance = nullptr;
}

// static
void FeaturedClient::Initialize(dbus::Bus* bus) {
DCHECK(bus);
(new FeaturedClientImpl())->Init(bus);
}

// static
void FeaturedClient::InitializeFake() {
new FakeFeaturedClient();
}

// static
void FeaturedClient::Shutdown() {
DCHECK(g_instance);
delete g_instance;
}

// static
FeaturedClient* FeaturedClient::Get() {
return g_instance;
}

} // namespace ash::featured
50 changes: 50 additions & 0 deletions chromeos/ash/components/dbus/featured/featured_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED_FEATURED_CLIENT_H_
#define CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED_FEATURED_CLIENT_H_

#include "base/component_export.h"
#include "base/functional/callback.h"
#include "chromeos/ash/components/dbus/featured/featured.pb.h"

namespace dbus {
class Bus;
}

namespace ash::featured {

// FeaturedClient is used to communicate seed state with featured, which is used
// for enabling and managing platform specific features. Its main user is Chrome
// field trials.
class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED) FeaturedClient {
public:
// Creates and initializes the global instance. |bus| must not be null.
static void Initialize(dbus::Bus* bus);

// Creates and initializes a fake global instance.
static void InitializeFake();

// Destroys the global instance.
static void Shutdown();

// Returns the global instance which may be null if not initialized.
static FeaturedClient* Get();

FeaturedClient(const FeaturedClient&) = delete;
FeaturedClient& operator=(const FeaturedClient&) = delete;

// Asynchronously calls featured's `HandleSeedFetched`.
virtual void HandleSeedFetched(
const ::featured::SeedDetails& safe_seed,
base::OnceCallback<void(bool success)> callback) = 0;

protected:
// Initialize/Shutdown should be used instead.
FeaturedClient();
virtual ~FeaturedClient();
};
} // namespace ash::featured

#endif // CHROMEOS_ASH_COMPONENTS_DBUS_FEATURED_FEATURED_CLIENT_H_

0 comments on commit 10cefd7

Please sign in to comment.