Commit f4c11e33 authored by Nicholas Hollingum's avatar Nicholas Hollingum Committed by Commit Bot

borealis: Begin implementing Features and Prefs

This CL refactors IsAllowed for borealis into the standard GuestOs
approach (i.e. having a pref-keyed singleton). This necessitates minor
refactorings of the installer and its tests.

Relatedly, this calls for the creation of Borealis prefs, which were
also added in the same fashion as the other GuestOs implementations.

Bug: b/168763038, b/162562622
Change-Id: Ie153c2a860a174feaa3156801a8415ca99eefcad
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2415755Reviewed-by: default avatarNancy Wang <nancylingwang@chromium.org>
Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Reviewed-by: default avatarDaniel Ng <danielng@google.com>
Commit-Queue: Nic Hollingum <hollingum@google.com>
Cr-Commit-Position: refs/heads/master@{#813976}
parent 45afbd3e
......@@ -7,6 +7,8 @@
#include "ash/public/cpp/app_menu_constants.h"
#include "chrome/browser/apps/app_service/app_icon_factory.h"
#include "chrome/browser/apps/app_service/menu_util.h"
#include "chrome/browser/chromeos/borealis/borealis_features.h"
#include "chrome/browser/chromeos/borealis/borealis_features_factory.h"
#include "chrome/browser/chromeos/borealis/borealis_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/app_management/app_management.mojom.h"
......@@ -64,7 +66,9 @@ void BorealisApps::Connect(
mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
apps::mojom::ConnectOptionsPtr opts) {
std::vector<apps::mojom::AppPtr> apps;
apps.push_back(GetBorealisLauncher(profile_, borealis::IsBorealisAllowed()));
apps.push_back(GetBorealisLauncher(
profile_,
borealis::BorealisFeaturesFactory::GetForProfile(profile_)->IsAllowed()));
mojo::Remote<apps::mojom::Subscriber> subscriber(
std::move(subscriber_remote));
......@@ -95,7 +99,8 @@ void BorealisApps::Launch(const std::string& app_id,
apps::mojom::LaunchSource launch_source,
int64_t display_id) {
DCHECK_EQ(borealis::kBorealisAppId, app_id);
DCHECK_EQ(borealis::IsBorealisAllowed(), true);
DCHECK(
borealis::BorealisFeaturesFactory::GetForProfile(profile_)->IsAllowed());
borealis::ShowBorealisInstallerView(profile_);
}
......
......@@ -829,12 +829,18 @@ source_set("chromeos") {
"bluetooth/debug_logs_manager_factory.h",
"boot_times_recorder.cc",
"boot_times_recorder.h",
"borealis/borealis_features.cc",
"borealis/borealis_features.h",
"borealis/borealis_features_factory.cc",
"borealis/borealis_features_factory.h",
"borealis/borealis_installer.cc",
"borealis/borealis_installer.h",
"borealis/borealis_installer_factory.cc",
"borealis/borealis_installer_factory.h",
"borealis/borealis_installer_impl.cc",
"borealis/borealis_installer_impl.h",
"borealis/borealis_prefs.cc",
"borealis/borealis_prefs.h",
"borealis/borealis_util.cc",
"borealis/borealis_util.h",
"browser_context_keyed_service_factories.cc",
......@@ -3192,6 +3198,7 @@ source_set("unit_tests") {
"authpolicy/authpolicy_helper.unittest.cc",
"base/file_flusher_unittest.cc",
"bluetooth/debug_logs_manager_unittest.cc",
"borealis/borealis_features_unittest.cc",
"borealis/borealis_installer_unittest.cc",
"cert_provisioning/cert_provisioning_invalidator_unittest.cc",
"cert_provisioning/cert_provisioning_platform_keys_helpers_unittest.cc",
......
// 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 "chrome/browser/chromeos/borealis/borealis_features.h"
#include "chrome/browser/chromeos/borealis/borealis_features_factory.h"
#include "chrome/browser/chromeos/borealis/borealis_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_features.h"
#include "components/prefs/pref_service.h"
namespace borealis {
BorealisFeatures::BorealisFeatures(Profile* profile) : profile_(profile) {}
BorealisFeatures::~BorealisFeatures() = default;
bool BorealisFeatures::IsAllowed() {
return base::FeatureList::IsEnabled(features::kBorealis);
}
bool BorealisFeatures::IsEnabled() {
if (!IsAllowed())
return false;
return profile_->GetPrefs()->GetBoolean(prefs::kBorealisInstalledOnDevice);
}
} // namespace borealis
// 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 CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_FEATURES_H_
#define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_FEATURES_H_
#include "components/keyed_service/core/keyed_service.h"
class Profile;
namespace borealis {
class BorealisFeatures : public KeyedService {
public:
// Creates a per-profile instance of the feature-checker for borealis.
explicit BorealisFeatures(Profile* profile);
~BorealisFeatures() override;
// Returns true if borealis can be installed on the profile associated with
// this feature check.
bool IsAllowed();
// Returns true if borealis has been installed and can be run in the profile.
bool IsEnabled();
private:
Profile* profile_;
};
} // namespace borealis
#endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_FEATURES_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 "chrome/browser/chromeos/borealis/borealis_features_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
namespace borealis {
BorealisFeatures* BorealisFeaturesFactory::GetForProfile(Profile* profile) {
return static_cast<BorealisFeatures*>(
GetInstance()->GetServiceForBrowserContext(profile,
/* create */ true));
}
BorealisFeaturesFactory* BorealisFeaturesFactory::GetInstance() {
static base::NoDestructor<BorealisFeaturesFactory> factory;
return factory.get();
}
// This service does not depend on any other services.
BorealisFeaturesFactory::BorealisFeaturesFactory()
: BrowserContextKeyedServiceFactory(
"BorealisFeaturesService",
BrowserContextDependencyManager::GetInstance()) {}
BorealisFeaturesFactory::~BorealisFeaturesFactory() = default;
KeyedService* BorealisFeaturesFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
return new BorealisFeatures(Profile::FromBrowserContext(context));
}
} // namespace borealis
// 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 CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_FEATURES_FACTORY_H_
#define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_FEATURES_FACTORY_H_
#include "base/no_destructor.h"
#include "chrome/browser/chromeos/borealis/borealis_features.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
namespace borealis {
// Implementation of the factory used to access profile-keyed instances of the
// features service.
class BorealisFeaturesFactory : public BrowserContextKeyedServiceFactory {
public:
static BorealisFeatures* GetForProfile(Profile* profile);
static BorealisFeaturesFactory* GetInstance();
// Can not be moved or copied.
BorealisFeaturesFactory(const BorealisFeaturesFactory&) = delete;
BorealisFeaturesFactory(BorealisFeaturesFactory&&) = delete;
BorealisFeaturesFactory& operator=(const BorealisFeaturesFactory&) = delete;
BorealisFeaturesFactory& operator=(BorealisFeaturesFactory&&) = delete;
private:
friend base::NoDestructor<BorealisFeaturesFactory>;
BorealisFeaturesFactory();
~BorealisFeaturesFactory() override;
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* context) const override;
};
} // namespace borealis
#endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_FEATURES_FACTORY_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 "chrome/browser/chromeos/borealis/borealis_features.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/chromeos/borealis/borealis_features_factory.h"
#include "chrome/browser/chromeos/borealis/borealis_prefs.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/testing_profile.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace borealis {
namespace {
class BorealisFeaturesTest : public testing::Test {
protected:
content::BrowserTaskEnvironment task_environment_;
TestingProfile profile_;
};
TEST_F(BorealisFeaturesTest, DisallowedWhenFeatureIsDisabled) {
base::test::ScopedFeatureList features;
features.InitAndDisableFeature(features::kBorealis);
EXPECT_FALSE(BorealisFeaturesFactory::GetForProfile(&profile_)->IsAllowed());
}
TEST_F(BorealisFeaturesTest, AllowedWhenFeatureIsEnabled) {
base::test::ScopedFeatureList features;
features.InitAndEnableFeature(features::kBorealis);
EXPECT_TRUE(BorealisFeaturesFactory::GetForProfile(&profile_)->IsAllowed());
}
TEST_F(BorealisFeaturesTest, EnablednessDependsOnInstallation) {
base::test::ScopedFeatureList features;
features.InitAndEnableFeature(features::kBorealis);
// The pref is false by default
EXPECT_FALSE(BorealisFeaturesFactory::GetForProfile(&profile_)->IsEnabled());
profile_.GetPrefs()->SetBoolean(prefs::kBorealisInstalledOnDevice, true);
EXPECT_TRUE(BorealisFeaturesFactory::GetForProfile(&profile_)->IsEnabled());
}
} // namespace
} // namespace borealis
......@@ -35,7 +35,7 @@ BorealisInstallerFactory::~BorealisInstallerFactory() = default;
KeyedService* BorealisInstallerFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
return new BorealisInstallerImpl();
return new BorealisInstallerImpl(Profile::FromBrowserContext(context));
}
content::BrowserContext* BorealisInstallerFactory::GetBrowserContextToUse(
......
......@@ -5,12 +5,18 @@
#include "chrome/browser/chromeos/borealis/borealis_installer_impl.h"
#include "base/bind.h"
#include "chrome/browser/chromeos/borealis/borealis_features.h"
#include "chrome/browser/chromeos/borealis/borealis_features_factory.h"
#include "chrome/browser/chromeos/borealis/borealis_util.h"
#include "content/public/browser/browser_thread.h"
namespace borealis {
BorealisInstallerImpl::BorealisInstallerImpl() = default;
BorealisInstallerImpl::BorealisInstallerImpl(Profile* profile)
: state_(State::kIdle),
installing_state_(InstallingState::kInactive),
profile_(profile),
weak_ptr_factory_(this) {}
BorealisInstallerImpl::~BorealisInstallerImpl() = default;
......@@ -19,7 +25,7 @@ bool BorealisInstallerImpl::IsProcessing() {
}
void BorealisInstallerImpl::Start() {
if (!IsBorealisAllowed()) {
if (!BorealisFeaturesFactory::GetForProfile(profile_)->IsAllowed()) {
LOG(ERROR) << "Installation of Borealis cannot be started because "
<< "Borealis is not allowed.";
InstallationEnded(InstallationResult::kNotAllowed);
......
......@@ -8,6 +8,8 @@
#include "chrome/browser/chromeos/borealis/borealis_installer.h"
#include "chromeos/dbus/dlcservice/dlcservice_client.h"
class Profile;
namespace borealis {
// This class is responsible for installing the Borealis VM. Currently
......@@ -16,7 +18,7 @@ namespace borealis {
// chrome/browser/ui/views/borealis/borealis_installer_view.h.
class BorealisInstallerImpl : public BorealisInstaller {
public:
BorealisInstallerImpl();
explicit BorealisInstallerImpl(Profile* profile);
// Disallow copy and assign.
BorealisInstallerImpl(const BorealisInstallerImpl&) = delete;
......@@ -51,11 +53,12 @@ class BorealisInstallerImpl : public BorealisInstaller {
void OnDlcInstallationCompleted(
const chromeos::DlcserviceClient::InstallResult& install_result);
State state_ = State::kIdle;
InstallingState installing_state_ = InstallingState::kInactive;
double progress_ = 0;
State state_;
InstallingState installing_state_;
double progress_;
Profile* profile_;
base::WeakPtrFactory<BorealisInstallerImpl> weak_ptr_factory_{this};
base::WeakPtrFactory<BorealisInstallerImpl> weak_ptr_factory_;
};
} // namespace borealis
......
// 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 "chrome/browser/chromeos/borealis/borealis_prefs.h"
#include "components/prefs/pref_registry_simple.h"
namespace borealis {
namespace prefs {
const char kBorealisInstalledOnDevice[] = "borealis.installed_on_device";
void RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(kBorealisInstalledOnDevice, false);
}
} // namespace prefs
} // namespace borealis
// 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 CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_PREFS_H_
#define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_PREFS_H_
class PrefRegistrySimple;
namespace borealis {
namespace prefs {
// A boolean pref which records whether borealis has been successfully installed
// on the device.
extern const char kBorealisInstalledOnDevice[];
void RegisterProfilePrefs(PrefRegistrySimple* registry);
} // namespace prefs
} // namespace borealis
#endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_PREFS_H_
......@@ -4,16 +4,9 @@
#include "chrome/browser/chromeos/borealis/borealis_util.h"
#include "chrome/common/chrome_features.h"
namespace borealis {
const char kBorealisAppId[] = "dkecggknbdokeipkgnhifhiokailichf";
const char kBorealisDlcName[] = "borealis-dlc";
bool IsBorealisAllowed() {
// Check that the Borealis feature is enabled.
return base::FeatureList::IsEnabled(features::kBorealis);
}
} // namespace borealis
......@@ -15,9 +15,6 @@ extern const char kBorealisAppId[];
// This is used to install the Borealis DLC component.
extern const char kBorealisDlcName[];
// Checks if Borealis is allowed to run in the current environment.
bool IsBorealisAllowed();
// Shows the Borealis installer (borealis_installer_view).
void ShowBorealisInstallerView(Profile* profile);
......
......@@ -273,6 +273,7 @@
#if defined(USE_CUPS)
#include "chrome/browser/chromeos/extensions/printing/printing_api_handler.h"
#endif
#include "chrome/browser/chromeos/borealis/borealis_prefs.h"
#include "chrome/browser/chromeos/child_accounts/secondary_account_consent_logger.h"
#include "chrome/browser/chromeos/file_system_provider/registry.h"
#include "chrome/browser/chromeos/first_run/first_run.h"
......@@ -963,6 +964,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
RegisterChromeLauncherUserPrefs(registry);
::onc::RegisterProfilePrefs(registry);
chromeos::cert_provisioning::RegisterProfilePrefs(registry);
borealis::prefs::RegisterProfilePrefs(registry);
#endif // defined(OS_CHROMEOS)
#if defined(OS_WIN)
......
......@@ -18,6 +18,8 @@
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/apps/app_service/app_service_test.h"
#include "chrome/browser/chromeos/borealis/borealis_features.h"
#include "chrome/browser/chromeos/borealis/borealis_features_factory.h"
#include "chrome/browser/chromeos/borealis/borealis_util.h"
#include "chrome/browser/chromeos/crostini/crostini_test_helper.h"
#include "chrome/browser/chromeos/crostini/crostini_util.h"
......@@ -1080,7 +1082,9 @@ class BorealisAppTest : public AppServiceAppModelBuilderTest {
};
TEST_P(BorealisAppTest, BorealisDisabled) {
EXPECT_FALSE(borealis::IsBorealisAllowed());
EXPECT_FALSE(
borealis::BorealisFeaturesFactory::GetForProfile(testing_profile_.get())
->IsAllowed());
EXPECT_EQ(std::vector<std::string>{}, GetModelContent(model_updater_.get()));
}
......@@ -1091,7 +1095,9 @@ TEST_P(BorealisAppTest, BorealisEnabled) {
// Borealis was enabled.
CreateBuilder(/*guest_mode=*/false);
EXPECT_TRUE(borealis::IsBorealisAllowed());
EXPECT_TRUE(
borealis::BorealisFeaturesFactory::GetForProfile(testing_profile_.get())
->IsAllowed());
EXPECT_EQ(
std::vector<std::string>{l10n_util::GetStringUTF8(IDS_BOREALIS_APP_NAME)},
GetModelContent(model_updater_.get()));
......
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