Commit 83ff4432 authored by Nicholas Hollingum's avatar Nicholas Hollingum Committed by Commit Bot

Support GuestOsApps for borealis

This change allows GuestOsApps to be visible in the shelf/launcher, and
associates its windows with those items.

The behaviour is only partially completed, the current items will be
finished in a forthcoming CL:
 - Support launching the apps from the launcher/pinned shelf items
 - Have context-menus for our shelf/launcher items.

Bug: b/162562622
Change-Id: I7456fb8173cf1964663709fc015ba9cc9b79df12
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2454952
Commit-Queue: Nic Hollingum <hollingum@google.com>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarNancy Wang <nancylingwang@chromium.org>
Reviewed-by: default avatarDaniel Ng <danielng@google.com>
Reviewed-by: default avatarJoel Hockey <joelhockey@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816059}
parent 01b6d424
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "chrome/browser/apps/app_service/app_icon_source.h" #include "chrome/browser/apps/app_service/app_icon_source.h"
#include "chrome/browser/apps/app_service/app_service_metrics.h" #include "chrome/browser/apps/app_service/app_service_metrics.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/chromeos/guest_os/guest_os_registry_service_factory.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h"
#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_features.h"
...@@ -167,6 +168,11 @@ void AppServiceProxy::Initialize() { ...@@ -167,6 +168,11 @@ void AppServiceProxy::Initialize() {
built_in_chrome_os_apps_ = built_in_chrome_os_apps_ =
std::make_unique<BuiltInChromeOsApps>(app_service_, profile_); std::make_unique<BuiltInChromeOsApps>(app_service_, profile_);
} }
// TODO(b/170591339): Allow borealis to provide apps for the non-primary
// profile.
if (guest_os::GuestOsRegistryServiceFactory::GetForProfile(profile_)) {
borealis_apps_ = std::make_unique<BorealisApps>(app_service_, profile_);
}
crostini_apps_ = std::make_unique<CrostiniApps>(app_service_, profile_); crostini_apps_ = std::make_unique<CrostiniApps>(app_service_, profile_);
extension_apps_ = std::make_unique<ExtensionAppsChromeOs>( extension_apps_ = std::make_unique<ExtensionAppsChromeOs>(
app_service_, profile_, apps::mojom::AppType::kExtension, app_service_, profile_, apps::mojom::AppType::kExtension,
...@@ -191,7 +197,6 @@ void AppServiceProxy::Initialize() { ...@@ -191,7 +197,6 @@ void AppServiceProxy::Initialize() {
app_service_, profile_, apps::mojom::AppType::kWeb, app_service_, profile_, apps::mojom::AppType::kWeb,
&instance_registry_); &instance_registry_);
} }
borealis_apps_ = std::make_unique<BorealisApps>(app_service_, profile_);
#else #else
if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) { if (base::FeatureList::IsEnabled(features::kDesktopPWAsWithoutExtensions)) {
web_apps_ = std::make_unique<WebApps>(app_service_, profile_); web_apps_ = std::make_unique<WebApps>(app_service_, profile_);
...@@ -648,6 +653,7 @@ void AppServiceProxy::Shutdown() { ...@@ -648,6 +653,7 @@ void AppServiceProxy::Shutdown() {
extension_web_apps_->Shutdown(); extension_web_apps_->Shutdown();
} }
} }
borealis_apps_.reset();
#endif #endif
} }
......
...@@ -12,10 +12,14 @@ ...@@ -12,10 +12,14 @@
#include "chrome/browser/chromeos/borealis/borealis_features.h" #include "chrome/browser/chromeos/borealis/borealis_features.h"
#include "chrome/browser/chromeos/borealis/borealis_features_factory.h" #include "chrome/browser/chromeos/borealis/borealis_features_factory.h"
#include "chrome/browser/chromeos/borealis/borealis_util.h" #include "chrome/browser/chromeos/borealis/borealis_util.h"
#include "chrome/browser/chromeos/guest_os/guest_os_registry_service.h"
#include "chrome/browser/chromeos/guest_os/guest_os_registry_service_factory.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/app_management/app_management.mojom.h" #include "chrome/browser/ui/webui/app_management/app_management.mojom.h"
#include "chrome/common/chrome_features.h"
#include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/chrome_unscaled_resources.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "components/services/app_service/public/cpp/publisher_base.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
namespace { namespace {
...@@ -59,10 +63,67 @@ BorealisApps::BorealisApps( ...@@ -59,10 +63,67 @@ BorealisApps::BorealisApps(
const mojo::Remote<apps::mojom::AppService>& app_service, const mojo::Remote<apps::mojom::AppService>& app_service,
Profile* profile) Profile* profile)
: profile_(profile) { : profile_(profile) {
Registry()->AddObserver(this);
PublisherBase::Initialize(app_service, apps::mojom::AppType::kBorealis); PublisherBase::Initialize(app_service, apps::mojom::AppType::kBorealis);
// TODO(b/170264723): When uninstalling borealis is completed, ensure that we
// remove the apps from the apps service.
} }
BorealisApps::~BorealisApps() = default; BorealisApps::~BorealisApps() {
Registry()->RemoveObserver(this);
}
guest_os::GuestOsRegistryService* BorealisApps::Registry() {
guest_os::GuestOsRegistryService* registry =
guest_os::GuestOsRegistryServiceFactory::GetForProfile(profile_);
// The GuestOsRegistryService is a dependant of the apps service itself, so it
// is not possible for the apps service to be in a valid state while this is
// null.
DCHECK(registry);
return registry;
}
apps::mojom::AppPtr BorealisApps::Convert(
const guest_os::GuestOsRegistryService::Registration& registration,
bool new_icon_key) {
// We must only convert borealis apps.
DCHECK_EQ(registration.VmType(), guest_os::GuestOsRegistryService::VmType::
ApplicationList_VmType_BOREALIS);
// The installer app is not a GuestOs app, it doesnt have a registration and
// it can't be converted.
DCHECK_NE(registration.app_id(), borealis::kBorealisAppId);
apps::mojom::AppPtr app = PublisherBase::MakeApp(
apps::mojom::AppType::kBorealis, registration.app_id(),
apps::mojom::Readiness::kReady, registration.Name(),
apps::mojom::InstallSource::kUser);
const std::string& executable_file_name = registration.ExecutableFileName();
if (!executable_file_name.empty()) {
app->additional_search_terms.push_back(executable_file_name);
}
for (const std::string& keyword : registration.Keywords()) {
app->additional_search_terms.push_back(keyword);
}
if (new_icon_key) {
auto icon_effects =
base::FeatureList::IsEnabled(features::kAppServiceAdaptiveIcon)
? IconEffects::kCrOsStandardIcon
: IconEffects::kNone;
app->icon_key = icon_key_factory_.MakeIconKey(icon_effects);
}
app->last_launch_time = registration.LastLaunchTime();
app->install_time = registration.InstallTime();
SetAppAllowed(app.get(), !registration.NoDisplay());
return app;
}
void BorealisApps::Connect( void BorealisApps::Connect(
mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
...@@ -72,6 +133,14 @@ void BorealisApps::Connect( ...@@ -72,6 +133,14 @@ void BorealisApps::Connect(
profile_, profile_,
borealis::BorealisFeaturesFactory::GetForProfile(profile_)->IsAllowed())); borealis::BorealisFeaturesFactory::GetForProfile(profile_)->IsAllowed()));
for (const auto& pair :
Registry()->GetRegisteredApps(guest_os::GuestOsRegistryService::VmType::
ApplicationList_VmType_BOREALIS)) {
const guest_os::GuestOsRegistryService::Registration& registration =
pair.second;
apps.push_back(Convert(registration, /*new_icon_key=*/true));
}
mojo::Remote<apps::mojom::Subscriber> subscriber( mojo::Remote<apps::mojom::Subscriber> subscriber(
std::move(subscriber_remote)); std::move(subscriber_remote));
subscriber->OnApps(std::move(apps)); subscriber->OnApps(std::move(apps));
...@@ -84,16 +153,10 @@ void BorealisApps::LoadIcon(const std::string& app_id, ...@@ -84,16 +153,10 @@ void BorealisApps::LoadIcon(const std::string& app_id,
int32_t size_hint_in_dip, int32_t size_hint_in_dip,
bool allow_placeholder_icon, bool allow_placeholder_icon,
LoadIconCallback callback) { LoadIconCallback callback) {
constexpr bool is_placeholder_icon = false; Registry()->LoadIcon(app_id, std::move(icon_key), icon_type, size_hint_in_dip,
if (icon_key && allow_placeholder_icon,
(icon_key->resource_id != apps::mojom::IconKey::kInvalidResourceId)) { apps::mojom::IconKey::kInvalidResourceId,
LoadIconFromResource( std::move(callback));
icon_type, size_hint_in_dip, icon_key->resource_id, is_placeholder_icon,
static_cast<IconEffects>(icon_key->icon_effects), std::move(callback));
return;
}
// On failure, we still run the callback, with the zero IconValue.
std::move(callback).Run(apps::mojom::IconValue::New());
} }
void BorealisApps::Launch(const std::string& app_id, void BorealisApps::Launch(const std::string& app_id,
...@@ -109,6 +172,9 @@ void BorealisApps::Launch(const std::string& app_id, ...@@ -109,6 +172,9 @@ void BorealisApps::Launch(const std::string& app_id,
return; return;
} }
borealis::ShowBorealisInstallerView(profile_); borealis::ShowBorealisInstallerView(profile_);
// TODO(b/162562622): Fix the launcher so it runs borealis (if its already
// installed) and support launching apps.
} }
void BorealisApps::GetMenuModel(const std::string& app_id, void BorealisApps::GetMenuModel(const std::string& app_id,
...@@ -121,6 +187,41 @@ void BorealisApps::GetMenuModel(const std::string& app_id, ...@@ -121,6 +187,41 @@ void BorealisApps::GetMenuModel(const std::string& app_id,
AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, &menu_items); AddCommandItem(ash::MENU_CLOSE, IDS_SHELF_CONTEXT_MENU_CLOSE, &menu_items);
} }
// TODO(b/162562622): Menu models for borealis apps.
std::move(callback).Run(std::move(menu_items)); std::move(callback).Run(std::move(menu_items));
} }
void BorealisApps::OnRegistryUpdated(
guest_os::GuestOsRegistryService* registry_service,
guest_os::GuestOsRegistryService::VmType vm_type,
const std::vector<std::string>& updated_apps,
const std::vector<std::string>& removed_apps,
const std::vector<std::string>& inserted_apps) {
if (vm_type != guest_os::GuestOsRegistryService::VmType::
ApplicationList_VmType_BOREALIS) {
return;
}
for (const std::string& app_id : updated_apps) {
if (auto registration = registry_service->GetRegistration(app_id)) {
Publish(Convert(*registration, /*new_icon_key=*/false), subscribers_);
}
}
for (const std::string& app_id : removed_apps) {
apps::mojom::AppPtr app = apps::mojom::App::New();
app->app_type = apps::mojom::AppType::kBorealis;
app->app_id = app_id;
app->readiness = apps::mojom::Readiness::kUninstalledByUser;
Publish(std::move(app), subscribers_);
}
for (const std::string& app_id : inserted_apps) {
if (auto registration = registry_service->GetRegistration(app_id)) {
Publish(Convert(*registration, /*new_icon_key=*/true), subscribers_);
}
}
}
} // namespace apps } // namespace apps
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "chrome/browser/apps/app_service/icon_key_util.h"
#include "chrome/browser/chromeos/guest_os/guest_os_registry_service.h"
#include "components/services/app_service/public/cpp/publisher_base.h" #include "components/services/app_service/public/cpp/publisher_base.h"
#include "components/services/app_service/public/mojom/app_service.mojom.h" #include "components/services/app_service/public/mojom/app_service.mojom.h"
#include "components/services/app_service/public/mojom/types.mojom.h" #include "components/services/app_service/public/mojom/types.mojom.h"
...@@ -22,7 +24,8 @@ namespace apps { ...@@ -22,7 +24,8 @@ namespace apps {
// An app publisher (in the App Service sense) of Borealis apps. // An app publisher (in the App Service sense) of Borealis apps.
// See components/services/app_service/README.md. // See components/services/app_service/README.md.
class BorealisApps : public apps::PublisherBase { class BorealisApps : public apps::PublisherBase,
public guest_os::GuestOsRegistryService::Observer {
public: public:
BorealisApps(const mojo::Remote<apps::mojom::AppService>& app_service, BorealisApps(const mojo::Remote<apps::mojom::AppService>& app_service,
Profile* profile); Profile* profile);
...@@ -33,6 +36,14 @@ class BorealisApps : public apps::PublisherBase { ...@@ -33,6 +36,14 @@ class BorealisApps : public apps::PublisherBase {
BorealisApps& operator=(const BorealisApps&) = delete; BorealisApps& operator=(const BorealisApps&) = delete;
private: private:
// Helper method to get the registry used by this profile
guest_os::GuestOsRegistryService* Registry();
// Turns GuestOsRegistry's "app" into one the AppService can use.
apps::mojom::AppPtr Convert(
const guest_os::GuestOsRegistryService::Registration& registration,
bool new_icon_key);
// apps::PublisherBase overrides. // apps::PublisherBase overrides.
void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
apps::mojom::ConnectOptionsPtr opts) override; apps::mojom::ConnectOptionsPtr opts) override;
...@@ -51,8 +62,18 @@ class BorealisApps : public apps::PublisherBase { ...@@ -51,8 +62,18 @@ class BorealisApps : public apps::PublisherBase {
int64_t display_id, int64_t display_id,
GetMenuModelCallback callback) override; GetMenuModelCallback callback) override;
// GuestOsRegistryService::Observer overrides.
void OnRegistryUpdated(
guest_os::GuestOsRegistryService* registry_service,
guest_os::GuestOsRegistryService::VmType vm_type,
const std::vector<std::string>& updated_apps,
const std::vector<std::string>& removed_apps,
const std::vector<std::string>& inserted_apps) override;
mojo::RemoteSet<apps::mojom::Subscriber> subscribers_; mojo::RemoteSet<apps::mojom::Subscriber> subscribers_;
apps_util::IncrementingIconKeyFactory icon_key_factory_;
Profile* const profile_; Profile* const profile_;
}; };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <vector> #include <vector>
#include "base/bind.h" #include "base/bind.h"
#include "chrome/browser/chromeos/borealis/borealis_features_factory.h"
#include "chrome/browser/chromeos/crostini/crostini_features.h" #include "chrome/browser/chromeos/crostini/crostini_features.h"
#include "chrome/browser/chromeos/crostini/crostini_mime_types_service.h" #include "chrome/browser/chromeos/crostini/crostini_mime_types_service.h"
#include "chrome/browser/chromeos/crostini/crostini_mime_types_service_factory.h" #include "chrome/browser/chromeos/crostini/crostini_mime_types_service_factory.h"
...@@ -83,7 +84,8 @@ void VmApplicationsServiceProvider::UpdateApplicationList( ...@@ -83,7 +84,8 @@ void VmApplicationsServiceProvider::UpdateApplicationList(
Profile* profile = ProfileManager::GetPrimaryUserProfile(); Profile* profile = ProfileManager::GetPrimaryUserProfile();
if (crostini::CrostiniFeatures::Get()->IsEnabled(profile) || if (crostini::CrostiniFeatures::Get()->IsEnabled(profile) ||
plugin_vm::PluginVmFeatures::Get()->IsEnabled(profile)) { plugin_vm::PluginVmFeatures::Get()->IsEnabled(profile) ||
borealis::BorealisFeaturesFactory::GetForProfile(profile)->IsEnabled()) {
auto* registry_service = auto* registry_service =
guest_os::GuestOsRegistryServiceFactory::GetForProfile(profile); guest_os::GuestOsRegistryServiceFactory::GetForProfile(profile);
registry_service->UpdateApplicationList(request); registry_service->UpdateApplicationList(request);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/apps/app_service/dip_px_util.h" #include "chrome/browser/apps/app_service/dip_px_util.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/borealis/borealis_features_factory.h"
#include "chrome/browser/chromeos/crostini/crostini_features.h" #include "chrome/browser/chromeos/crostini/crostini_features.h"
#include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/chromeos/crostini/crostini_manager.h"
#include "chrome/browser/chromeos/crostini/crostini_shelf_utils.h" #include "chrome/browser/chromeos/crostini/crostini_shelf_utils.h"
...@@ -568,7 +569,9 @@ GuestOsRegistryService::GetEnabledApps() const { ...@@ -568,7 +569,9 @@ GuestOsRegistryService::GetEnabledApps() const {
crostini::CrostiniFeatures::Get()->IsEnabled(profile_); crostini::CrostiniFeatures::Get()->IsEnabled(profile_);
bool plugin_vm_enabled = bool plugin_vm_enabled =
plugin_vm::PluginVmFeatures::Get()->IsEnabled(profile_); plugin_vm::PluginVmFeatures::Get()->IsEnabled(profile_);
if (!crostini_enabled && !plugin_vm_enabled) bool borealis_enabled =
borealis::BorealisFeaturesFactory::GetForProfile(profile_)->IsEnabled();
if (!crostini_enabled && !plugin_vm_enabled && !borealis_enabled)
return {}; return {};
auto apps = GetAllRegisteredApps(); auto apps = GetAllRegisteredApps();
...@@ -581,6 +584,9 @@ GuestOsRegistryService::GetEnabledApps() const { ...@@ -581,6 +584,9 @@ GuestOsRegistryService::GetEnabledApps() const {
case VmType::ApplicationList_VmType_PLUGIN_VM: case VmType::ApplicationList_VmType_PLUGIN_VM:
enabled = plugin_vm_enabled; enabled = plugin_vm_enabled;
break; break;
case VmType::ApplicationList_VmType_BOREALIS:
enabled = borealis_enabled;
break;
default: default:
LOG(ERROR) << "Unsupported VmType: " LOG(ERROR) << "Unsupported VmType: "
<< static_cast<int>(it->second.VmType()); << static_cast<int>(it->second.VmType());
...@@ -632,7 +638,9 @@ void GuestOsRegistryService::RecordStartupMetrics() { ...@@ -632,7 +638,9 @@ void GuestOsRegistryService::RecordStartupMetrics() {
crostini::CrostiniFeatures::Get()->IsEnabled(profile_); crostini::CrostiniFeatures::Get()->IsEnabled(profile_);
bool plugin_vm_enabled = bool plugin_vm_enabled =
plugin_vm::PluginVmFeatures::Get()->IsEnabled(profile_); plugin_vm::PluginVmFeatures::Get()->IsEnabled(profile_);
if (!crostini_enabled && !plugin_vm_enabled) bool borealis_enabled =
borealis::BorealisFeaturesFactory::GetForProfile(profile_)->IsEnabled();
if (!crostini_enabled && !plugin_vm_enabled && !borealis_enabled)
return; return;
int num_crostini_apps = 0; int num_crostini_apps = 0;
...@@ -667,6 +675,8 @@ void GuestOsRegistryService::RecordStartupMetrics() { ...@@ -667,6 +675,8 @@ void GuestOsRegistryService::RecordStartupMetrics() {
if (plugin_vm_enabled) if (plugin_vm_enabled)
UMA_HISTOGRAM_COUNTS_1000(kPluginVmAppsInstalledHistogram, UMA_HISTOGRAM_COUNTS_1000(kPluginVmAppsInstalledHistogram,
num_plugin_vm_apps); num_plugin_vm_apps);
// TODO(b/166691285): borealis launch metrics.
} }
base::FilePath GuestOsRegistryService::GetAppPath( base::FilePath GuestOsRegistryService::GetAppPath(
......
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