Commit 6f851a2e authored by Kyle Williams's avatar Kyle Williams Committed by Commit Bot

cfm: Add Feature/GN Flags for Cfm Mojo Services

Create GN flags to ensure target code compiles only on the cfm platform

Create Feature flags to support experiments specifically for
enabled chromium support for mojo based services on the platform layer
of cfm provisioned devices.

Adds support for hotline dbus and mojom

BUG=chromium:1105567
TEST='Set feature and gn flag to true/false ran respective dbus/services
tests'

Change-Id: Ica004eddd2f59398dcacc4e0d35d1b536705fa2b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2298486
Commit-Queue: Kyle Williams <kdgwill@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarNico Weber <thakis@chromium.org>
Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarAlexei Svitkine <asvitkine@chromium.org>
Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791155}
parent eb6317a2
......@@ -4,6 +4,7 @@
import("//build/config/features.gni")
import("//build/config/ui.gni")
import("//chromeos/services/cfm/public/buildflags/buildflags.gni")
import("//extensions/buildflags/buildflags.gni")
import("//media/media_options.gni")
import("//printing/buildflags/buildflags.gni")
......@@ -169,6 +170,7 @@ source_set("chromeos") {
"//chromeos/login/session",
"//chromeos/network",
"//chromeos/services/assistant/public/cpp",
"//chromeos/services/cfm/public/buildflags",
"//chromeos/services/cros_healthd/public/cpp",
"//chromeos/services/cros_healthd/public/mojom",
"//chromeos/services/device_sync",
......@@ -353,6 +355,9 @@ source_set("chromeos") {
"//ui/wm/public",
"//url",
]
if (is_cfm) {
deps += [ "//chromeos/dbus/cfm" ]
}
data_deps = [ ":dbus_service_files" ]
allow_circular_includes_from = [
......
......@@ -34,9 +34,14 @@
#include "chromeos/dbus/system_clock/system_clock_client.h"
#include "chromeos/dbus/system_proxy/system_proxy_client.h"
#include "chromeos/dbus/upstart/upstart_client.h"
#include "chromeos/services/cfm/public/buildflags/buildflags.h" // PLATFORM_CFM
#include "chromeos/tpm/install_attributes.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#if BUILDFLAG(PLATFORM_CFM)
#include "chromeos/dbus/cfm/cfm_hotline_client.h"
#endif
namespace {
void OverrideStubPathsIfNeeded() {
......@@ -97,6 +102,9 @@ void InitializeDBus() {
void InitializeFeatureListDependentDBus() {
dbus::Bus* bus = DBusThreadManager::Get()->GetSystemBus();
InitializeDBusClient<bluez::BluezDBusManager>(bus);
#if BUILDFLAG(PLATFORM_CFM)
InitializeDBusClient<CfmHotlineClient>(bus);
#endif
InitializeDBusClient<WilcoDtcSupportdClient>(bus);
}
......@@ -104,6 +112,9 @@ void ShutdownDBus() {
// Feature list-dependent D-Bus clients are shut down first because we try to
// shut down in reverse order of initialization (in case of dependencies).
WilcoDtcSupportdClient::Shutdown();
#if BUILDFLAG(PLATFORM_CFM)
CfmHotlineClient::Shutdown();
#endif
bluez::BluezDBusManager::Shutdown();
// Other D-Bus clients are shut down, also in reverse order of initialization.
......
......@@ -5,6 +5,7 @@
import("//build/config/features.gni")
import("//build/config/ui.gni")
import("//chrome/common/features.gni")
import("//chromeos/services/cfm/public/buildflags/buildflags.gni")
import("//components/nacl/features.gni")
import("//extensions/buildflags/buildflags.gni")
import("//mojo/public/tools/bindings/mojom.gni")
......@@ -1015,6 +1016,7 @@ static_library("extensions") {
"//chromeos/login/login_state",
"//chromeos/network",
"//chromeos/services/assistant/public/cpp",
"//chromeos/services/cfm/public/buildflags",
"//chromeos/services/ime/public/mojom",
"//chromeos/services/machine_learning/public/cpp",
"//chromeos/services/machine_learning/public/mojom",
......@@ -1043,6 +1045,12 @@ static_library("extensions") {
if (enable_nacl) {
deps += [ "//chrome/browser/resources/chromeos/zip_archiver" ]
}
if (is_cfm) {
deps += [
"//chromeos/services/cfm/public/cpp",
"//chromeos/services/cfm/public/mojom",
]
}
} else {
assert(!is_chromeos)
sources += [
......
......@@ -23,6 +23,7 @@
#include "chrome/common/extensions/extension_constants.h"
#include "chromeos/components/camera_app_ui/camera_app_helper.mojom.h"
#include "chromeos/components/camera_app_ui/camera_app_helper_impl.h"
#include "chromeos/services/cfm/public/buildflags/buildflags.h"
#include "chromeos/services/media_perception/public/mojom/media_perception.mojom.h"
#include "chromeos/services/tts/public/mojom/tts_service.mojom.h"
#include "components/arc/intent_helper/arc_intent_helper_bridge.h"
......@@ -46,7 +47,14 @@
#include "ui/base/ime/chromeos/extension_ime_util.h"
#include "ui/base/ime/chromeos/input_method_manager.h"
#endif
#if BUILDFLAG(PLATFORM_CFM)
#include "chromeos/services/cfm/public/cpp/appid_util.h"
#include "chromeos/services/cfm/public/cpp/service_connection.h"
#include "chromeos/services/cfm/public/features/features.h"
#include "chromeos/services/cfm/public/mojom/cfm_service_manager.mojom.h"
#endif
#endif // definied(OS_CHROMEOS)
namespace extensions {
......@@ -197,6 +205,20 @@ void PopulateChromeFrameBindersForExtension(
}
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
#if BUILDFLAG(PLATFORM_CFM)
if (base::FeatureList::IsEnabled(chromeos::cfm::features::kCfmMojoServices) &&
chromeos::cfm::IsChromeboxForMeetingsAppId(extension->id())) {
binder_map->Add<chromeos::cfm::mojom::CfmServiceContext>(
base::BindRepeating(
[](content::RenderFrameHost* frame_host,
mojo::PendingReceiver<chromeos::cfm::mojom::CfmServiceContext>
receiver) {
chromeos::cfm::ServiceConnection::GetInstance()
->BindServiceContext(std::move(receiver));
}));
}
#endif // BUILDFLAG(PLATFORM_CFM)
if (extension->permissions_data()->HasAPIPermission(
APIPermission::kMediaPerceptionPrivate)) {
extensions::ExtensionsAPIClient* client =
......
......@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//chromeos/services/cfm/public/buildflags/buildflags.gni")
import("//testing/test.gni")
import("//third_party/protobuf/proto_library.gni")
import("use_real_dbus_clients.gni")
......@@ -188,7 +189,6 @@ source_set("unit_tests") {
"//chromeos/dbus/audio",
"//chromeos/dbus/authpolicy",
"//chromeos/dbus/biod:test_support",
"//chromeos/dbus/cfm:unit_tests",
"//chromeos/dbus/cryptohome",
"//chromeos/dbus/cryptohome:attestation_proto",
"//chromeos/dbus/dlcservice:test_support",
......@@ -206,6 +206,9 @@ source_set("unit_tests") {
"//testing/gtest",
"//third_party/icu",
]
if (is_cfm) {
deps += [ "//chromeos/dbus/cfm:unit_tests" ]
}
sources = [
"audio/cras_audio_client_unittest.cc",
"authpolicy/fake_authpolicy_client_unittest.cc",
......
......@@ -2,15 +2,19 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//chromeos/services/cfm/public/buildflags/buildflags.gni")
import("//third_party/protobuf/proto_library.gni")
assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
assert(is_cfm, "Non-CfM builds cannot depend on this library")
component("cfm") {
defines = [ "IS_CFM_HOTLINE_CLIENT_IMPL" ]
public_deps = [
"//chromeos/dbus:common",
"//chromeos/dbus:dbus",
"//chromeos/services/cfm/public/buildflags",
"//chromeos/services/cfm/public/features",
]
deps = [
"//base",
......
include_rules = [
"+chromeos/services/cfm/public/buildflags",
"+chromeos/services/cfm/public/features",
]
......@@ -11,12 +11,12 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "chromeos/dbus/cfm/fake_cfm_hotline_client.h"
#include "chromeos/services/cfm/public/features/features.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#include "chromeos/dbus/cfm/fake_cfm_hotline_client.h"
namespace chromeos {
namespace {
......@@ -31,8 +31,9 @@ class CfmHotlineClientImpl : public CfmHotlineClient {
~CfmHotlineClientImpl() override = default;
void Init(dbus::Bus* const bus) {
dbus_proxy_ = bus->GetObjectProxy(
cfm::broker::kServiceName, dbus::ObjectPath(cfm::broker::kServicePath));
dbus_proxy_ =
bus->GetObjectProxy(::cfm::broker::kServiceName,
dbus::ObjectPath(::cfm::broker::kServicePath));
}
void WaitForServiceToBeAvailable(
......@@ -44,8 +45,8 @@ class CfmHotlineClientImpl : public CfmHotlineClient {
void BootstrapMojoConnection(
base::ScopedFD fd,
BootstrapMojoConnectionCallback result_callback) override {
dbus::MethodCall method_call(cfm::broker::kServiceInterfaceName,
cfm::broker::kBootstrapMojoConnectionMethod);
dbus::MethodCall method_call(::cfm::broker::kServiceInterfaceName,
::cfm::broker::kBootstrapMojoConnectionMethod);
dbus::MessageWriter writer(&method_call);
writer.AppendBool(/*is_outgoing_invitation=*/true);
writer.AppendFileDescriptor(fd.get());
......@@ -85,7 +86,9 @@ CfmHotlineClient::~CfmHotlineClient() {
// static
void CfmHotlineClient::Initialize(dbus::Bus* bus) {
DCHECK(bus);
(new CfmHotlineClientImpl())->Init(bus);
if (base::FeatureList::IsEnabled(chromeos::cfm::features::kCfmMojoServices)) {
(new CfmHotlineClientImpl())->Init(bus);
}
}
// static
......@@ -95,12 +98,19 @@ void CfmHotlineClient::InitializeFake() {
// static
void CfmHotlineClient::Shutdown() {
DCHECK(g_instance);
delete g_instance;
if (g_instance) {
delete g_instance;
}
}
// static
bool CfmHotlineClient::IsInitialized() {
return g_instance;
}
// static
CfmHotlineClient* CfmHotlineClient::Get() {
CHECK(IsInitialized());
return g_instance;
}
......
......@@ -38,6 +38,9 @@ class COMPONENT_EXPORT(CFM_HOTLINE_CLIENT) CfmHotlineClient {
// Destroys the global instance.
static void Shutdown();
// Checks if initialization was performed
static bool IsInitialized();
// Returns the global instance which may be null if not initialized.
static CfmHotlineClient* Get();
......
......@@ -16,7 +16,9 @@
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "chromeos/services/cfm/public/features/features.h"
#include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h"
#include "dbus/object_path.h"
......@@ -32,7 +34,10 @@ namespace chromeos {
class CfmHotlineClientTest : public testing::Test {
public:
CfmHotlineClientTest() = default;
CfmHotlineClientTest() {
scoped_feature_list_.InitAndEnableFeature(
chromeos::cfm::features::kCfmMojoServices);
}
~CfmHotlineClientTest() override = default;
void SetUp() override {
......@@ -44,12 +49,12 @@ class CfmHotlineClientTest : public testing::Test {
dbus::Bus::Options());
mock_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>(
mock_bus_.get(), cfm::broker::kServiceName,
dbus::ObjectPath(cfm::broker::kServicePath));
mock_bus_.get(), ::cfm::broker::kServiceName,
dbus::ObjectPath(::cfm::broker::kServicePath));
EXPECT_CALL(*mock_bus_.get(),
GetObjectProxy(cfm::broker::kServiceName,
dbus::ObjectPath(cfm::broker::kServicePath)))
GetObjectProxy(::cfm::broker::kServiceName,
dbus::ObjectPath(::cfm::broker::kServicePath)))
.WillOnce(Return(mock_proxy_.get()));
CfmHotlineClient::Initialize(mock_bus_.get());
......@@ -89,6 +94,7 @@ class CfmHotlineClientTest : public testing::Test {
base::File test_file_;
private:
base::test::ScopedFeatureList scoped_feature_list_;
std::deque<std::unique_ptr<dbus::Response>> used_responses_;
};
......
......@@ -4,6 +4,7 @@
import("//build/config/ui.gni")
import("//chromeos/assistant/assistant.gni")
import("//chromeos/services/cfm/public/buildflags/buildflags.gni")
import("//testing/test.gni")
assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
......@@ -20,7 +21,6 @@ source_set("unit_tests") {
deps = [
"//chromeos/services/assistant:tests",
"//chromeos/services/cellular_setup:unit_tests",
"//chromeos/services/cfm/public/cpp:unit_tests",
"//chromeos/services/cros_healthd/public/cpp:unit_tests",
"//chromeos/services/device_sync:unit_tests",
"//chromeos/services/ime:services_unittests",
......@@ -30,4 +30,7 @@ source_set("unit_tests") {
"//chromeos/services/network_config:unit_tests",
"//chromeos/services/secure_channel:unit_tests",
]
if (is_cfm) {
deps += [ "//chromeos/services/cfm/public/cpp:unit_tests" ]
}
}
# 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("//build/buildflag_header.gni")
import("//chromeos/services/cfm/public/buildflags/buildflags.gni")
# This file is in a separate directory so all targets in the build can refer to
# the buildflag header to get the necessary preprocessor defines without
# bringing in unneeded resources.
buildflag_header("buildflags") {
header = "buildflags.h"
flags = [ "PLATFORM_CFM=$is_cfm" ]
}
# CfM GN Build Flags
Note: GN Flags are Build time flags
You can get a comprehensive list of all arguments supported by gn by running the
command gn args --list out/some-directory (the directory passed to gn args is
required as gn args will invokes gn gen to generate the build.ninja files).
## is_cfm (BUILDFLAG(PLATFORM_CFM))
Flag for building chromium for CfM devices.
### Query Flag
```bash
$ gn args out_<cfm_overlay>/{Release||Debug} --list-is_cfm
```
### Enagle Flag
```bash
$ gn args out_<cfm_overlay>/{Release||Debug}
$ Editor will open add is_cfm=true save and exit
```
### Alt: EnrollmentRequisitionManager
We can alternatively use the EnrollmentRequisitionManager to determine if
chromium is running a CfM enabled Platform in source code
```cpp
policy::EnrollmentRequisitionManager::IsRemoraRequisition();
```
# 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.
declare_args() {
# True if compiling for Chromebox for Meeting devices.
is_cfm = false
}
......@@ -2,7 +2,10 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//chromeos/services/cfm/public/buildflags/buildflags.gni")
assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
assert(is_cfm, "Non-CfM builds cannot depend on this library")
source_set("cpp") {
sources = [
......@@ -16,6 +19,10 @@ source_set("cpp") {
"//chromeos/dbus/cfm",
"//chromeos/services/cfm/public/mojom",
]
public_deps = [
"//chromeos/services/cfm/public/buildflags",
"//chromeos/services/cfm/public/features",
]
}
source_set("test_support") {
......
# 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.
# This file is in a separate directory so all targets in the build can refer to
# the buildflag header and feature list to get the necessary finch experiments,
# respectively, without bringing in unneeded resources.
component("features") {
output_name = "cfm_features"
defines = [ "IS_CFM_FEATURES_IMPL" ]
sources = [
"features.cc",
"features.h",
]
deps = [ "//base" ]
}
# Features
Note: Feature Flags are run time flags
## CfmMojoServices
```bash
$ ssh <cfm-dut>
$ echo "--enable-features=CfmMojoServices" >> /etc/chrome_dev.conf
$ reboot ui
```
This Feature flag is controlled by a server-side experiment that enables
Chromium to interact with mojom based Chromebox for Meetings services.
// 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/services/cfm/public/features/features.h"
namespace chromeos {
namespace cfm {
namespace features {
// Enables or disables the ability to bind mojo connections through chrome for
// Cfm specific mojom based system services.
const base::Feature kCfmMojoServices{"CfmMojoServices",
base::FEATURE_DISABLED_BY_DEFAULT};
} // namespace features
} // namespace cfm
} // 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_SERVICES_CFM_PUBLIC_FEATURES_FEATURES_H_
#define CHROMEOS_SERVICES_CFM_PUBLIC_FEATURES_FEATURES_H_
#include "base/component_export.h"
#include "base/feature_list.h"
namespace chromeos {
namespace cfm {
namespace features {
COMPONENT_EXPORT(CFM_FEATURES)
extern const base::Feature kCfmMojoServices;
} // namespace features
} // namespace cfm
} // namespace chromeos
#endif // CHROMEOS_SERVICES_CFM_PUBLIC_FEATURES_FEATURES_H_
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