Commit 71d65441 authored by Timothy Loh's avatar Timothy Loh Committed by Commit Bot

Add a D-Bus interface for updating the Crostini App Registry

This patch adds an interface for updating the Crostini App Registry
over D-Bus at org.chromium.VmApplicationsService:UpdateApplicationList.

The proto is being added in:
https://chromium-review.googlesource.com/q/I05b05f03

Bug: 821662
Change-Id: I7effada1c0de237ef3ec49da84d5c1f76415781e
Reviewed-on: https://chromium-review.googlesource.com/965803
Commit-Queue: Timothy Loh <timloh@chromium.org>
Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#547990}
parent 7c3b5377
...@@ -30,6 +30,7 @@ source_set("chromeos") { ...@@ -30,6 +30,7 @@ source_set("chromeos") {
"//chrome/app/theme:theme_resources", "//chrome/app/theme:theme_resources",
"//chromeos:concierge_proto", "//chromeos:concierge_proto",
"//chromeos:power_manager_proto", "//chromeos:power_manager_proto",
"//chromeos:vm_applications_apps_proto",
"//components/policy/proto", "//components/policy/proto",
"//content/app/resources", "//content/app/resources",
"//ui/chromeos/resources", "//ui/chromeos/resources",
...@@ -533,6 +534,8 @@ source_set("chromeos") { ...@@ -533,6 +534,8 @@ source_set("chromeos") {
"dbus/kiosk_info_service_provider.h", "dbus/kiosk_info_service_provider.h",
"dbus/screen_lock_service_provider.cc", "dbus/screen_lock_service_provider.cc",
"dbus/screen_lock_service_provider.h", "dbus/screen_lock_service_provider.h",
"dbus/vm_applications_service_provider_delegate.cc",
"dbus/vm_applications_service_provider_delegate.h",
"display/display_configuration_observer.cc", "display/display_configuration_observer.cc",
"display/display_configuration_observer.h", "display/display_configuration_observer.h",
"display/display_prefs.cc", "display/display_prefs.cc",
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include "chrome/browser/chromeos/dbus/finch_features_service_provider_delegate.h" #include "chrome/browser/chromeos/dbus/finch_features_service_provider_delegate.h"
#include "chrome/browser/chromeos/dbus/kiosk_info_service_provider.h" #include "chrome/browser/chromeos/dbus/kiosk_info_service_provider.h"
#include "chrome/browser/chromeos/dbus/screen_lock_service_provider.h" #include "chrome/browser/chromeos/dbus/screen_lock_service_provider.h"
#include "chrome/browser/chromeos/dbus/vm_applications_service_provider_delegate.h"
#include "chrome/browser/chromeos/display/quirks_manager_delegate_impl.h" #include "chrome/browser/chromeos/display/quirks_manager_delegate_impl.h"
#include "chrome/browser/chromeos/events/event_rewriter_controller.h" #include "chrome/browser/chromeos/events/event_rewriter_controller.h"
#include "chrome/browser/chromeos/events/event_rewriter_delegate_impl.h" #include "chrome/browser/chromeos/events/event_rewriter_delegate_impl.h"
...@@ -131,6 +132,7 @@ ...@@ -131,6 +132,7 @@
#include "chromeos/dbus/services/liveness_service_provider.h" #include "chromeos/dbus/services/liveness_service_provider.h"
#include "chromeos/dbus/services/proxy_resolution_service_provider.h" #include "chromeos/dbus/services/proxy_resolution_service_provider.h"
#include "chromeos/dbus/services/virtual_file_request_service_provider.h" #include "chromeos/dbus/services/virtual_file_request_service_provider.h"
#include "chromeos/dbus/services/vm_applications_service_provider.h"
#include "chromeos/dbus/session_manager_client.h" #include "chromeos/dbus/session_manager_client.h"
#include "chromeos/disks/disk_mount_manager.h" #include "chromeos/disks/disk_mount_manager.h"
#include "chromeos/login/login_state.h" #include "chromeos/login/login_state.h"
...@@ -402,6 +404,13 @@ class DBusServices { ...@@ -402,6 +404,13 @@ class DBusServices {
std::make_unique<ChromeFeaturesServiceProvider>( std::make_unique<ChromeFeaturesServiceProvider>(
std::make_unique<FinchFeaturesServiceProviderDelegate>()))); std::make_unique<FinchFeaturesServiceProviderDelegate>())));
vm_applications_service_ = CrosDBusService::Create(
vm_tools::apps::kVmApplicationsServiceName,
dbus::ObjectPath(vm_tools::apps::kVmApplicationsServicePath),
CrosDBusService::CreateServiceProviderList(
std::make_unique<VmApplicationsServiceProvider>(
std::make_unique<VmApplicationsServiceProviderDelegate>())));
// Initialize PowerDataCollector after DBusThreadManager is initialized. // Initialize PowerDataCollector after DBusThreadManager is initialized.
PowerDataCollector::Initialize(); PowerDataCollector::Initialize();
...@@ -446,6 +455,7 @@ class DBusServices { ...@@ -446,6 +455,7 @@ class DBusServices {
virtual_file_request_service_.reset(); virtual_file_request_service_.reset();
component_updater_service_.reset(); component_updater_service_.reset();
finch_features_service_.reset(); finch_features_service_.reset();
vm_applications_service_.reset();
PowerDataCollector::Shutdown(); PowerDataCollector::Shutdown();
PowerPolicyController::Shutdown(); PowerPolicyController::Shutdown();
device::BluetoothAdapterFactory::Shutdown(); device::BluetoothAdapterFactory::Shutdown();
...@@ -472,6 +482,7 @@ class DBusServices { ...@@ -472,6 +482,7 @@ class DBusServices {
std::unique_ptr<CrosDBusService> virtual_file_request_service_; std::unique_ptr<CrosDBusService> virtual_file_request_service_;
std::unique_ptr<CrosDBusService> component_updater_service_; std::unique_ptr<CrosDBusService> component_updater_service_;
std::unique_ptr<CrosDBusService> finch_features_service_; std::unique_ptr<CrosDBusService> finch_features_service_;
std::unique_ptr<CrosDBusService> vm_applications_service_;
ChromeConsoleServiceProviderDelegate console_service_provider_delegate_; ChromeConsoleServiceProviderDelegate console_service_provider_delegate_;
......
...@@ -6,11 +6,14 @@ ...@@ -6,11 +6,14 @@
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chromeos/dbus/vm_applications/apps.pb.h"
#include "components/crx_file/id_util.h" #include "components/crx_file/id_util.h"
#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h" #include "components/prefs/scoped_user_pref_update.h"
using vm_tools::apps::App;
namespace chromeos { namespace chromeos {
namespace { namespace {
...@@ -57,17 +60,38 @@ CrostiniRegistryService::GetRegistration(const std::string& app_id) const { ...@@ -57,17 +60,38 @@ CrostiniRegistryService::GetRegistration(const std::string& app_id) const {
name->GetString()); name->GetString());
} }
void CrostiniRegistryService::SetRegistration( void CrostiniRegistryService::UpdateApplicationList(
const Registration& registration) { const vm_tools::apps::ApplicationList& app_list) {
base::Value pref_registration(base::Value::Type::DICTIONARY);
pref_registration.SetKey(kAppDesktopFileIdKey,
base::Value(registration.desktop_file_id));
pref_registration.SetKey(kAppNameKey, base::Value(registration.name));
DictionaryPrefUpdate update(prefs_, kCrostiniRegistryPref); DictionaryPrefUpdate update(prefs_, kCrostiniRegistryPref);
base::DictionaryValue* apps = update.Get(); base::DictionaryValue* apps = update.Get();
apps->SetKey(GenerateAppId(registration.desktop_file_id), apps->Clear();
std::move(pref_registration));
for (const App& app : app_list.apps()) {
if (app.desktop_file_id().empty()) {
LOG(WARNING) << "Received app with missing desktop file id";
continue;
}
std::string default_name;
for (const App::LocaleString::Entry& localized_name : app.name().values()) {
if (localized_name.locale().empty()) {
default_name = localized_name.value();
break;
}
}
if (default_name.empty()) {
LOG(WARNING) << "Received app '" << app.desktop_file_id()
<< "' with missing unlocalized name";
continue;
}
base::Value pref_registration(base::Value::Type::DICTIONARY);
pref_registration.SetKey(kAppDesktopFileIdKey,
base::Value(app.desktop_file_id()));
pref_registration.SetKey(kAppNameKey, base::Value(default_name));
apps->SetKey(GenerateAppId(app.desktop_file_id()),
std::move(pref_registration));
}
} }
// static // static
......
...@@ -15,6 +15,12 @@ class Profile; ...@@ -15,6 +15,12 @@ class Profile;
class PrefRegistrySimple; class PrefRegistrySimple;
class PrefService; class PrefService;
namespace vm_tools {
namespace apps {
class ApplicationList;
} // namespace apps
} // namespace vm_tools
namespace chromeos { namespace chromeos {
// The CrostiniRegistryService stores information about Desktop Entries (apps) // The CrostiniRegistryService stores information about Desktop Entries (apps)
...@@ -46,9 +52,8 @@ class CrostiniRegistryService : public KeyedService { ...@@ -46,9 +52,8 @@ class CrostiniRegistryService : public KeyedService {
std::unique_ptr<CrostiniRegistryService::Registration> GetRegistration( std::unique_ptr<CrostiniRegistryService::Registration> GetRegistration(
const std::string& app_id) const; const std::string& app_id) const;
// If an app has already been registered for the given desktop file id, it // The existing list of apps is replaced by |application_list|.
// will be overriden. void UpdateApplicationList(const vm_tools::apps::ApplicationList& app_list);
void SetRegistration(const Registration& registration);
static void RegisterProfilePrefs(PrefRegistrySimple* registry); static void RegisterProfilePrefs(PrefRegistrySimple* registry);
......
...@@ -8,10 +8,14 @@ ...@@ -8,10 +8,14 @@
#include "base/macros.h" #include "base/macros.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "chromeos/dbus/vm_applications/apps.pb.h"
#include "components/crx_file/id_util.h" #include "components/crx_file/id_util.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using vm_tools::apps::App;
using vm_tools::apps::ApplicationList;
namespace chromeos { namespace chromeos {
class CrostiniRegistryServiceTest : public testing::Test { class CrostiniRegistryServiceTest : public testing::Test {
...@@ -45,8 +49,15 @@ TEST_F(CrostiniRegistryServiceTest, SetAndGetRegistration) { ...@@ -45,8 +49,15 @@ TEST_F(CrostiniRegistryServiceTest, SetAndGetRegistration) {
std::string app_id = GenerateAppId(desktop_file_id); std::string app_id = GenerateAppId(desktop_file_id);
EXPECT_EQ(nullptr, service()->GetRegistration(app_id)); EXPECT_EQ(nullptr, service()->GetRegistration(app_id));
CrostiniRegistryService::Registration registration(desktop_file_id, name); ApplicationList app_list;
service()->SetRegistration(registration); App* app = app_list.add_apps();
app->set_desktop_file_id(desktop_file_id);
App::LocaleString::Entry* name_with_locale =
app->mutable_name()->add_values();
name_with_locale->set_locale("");
name_with_locale->set_value(name);
service()->UpdateApplicationList(app_list);
auto result = service()->GetRegistration(app_id); auto result = service()->GetRegistration(app_id);
ASSERT_NE(nullptr, result); ASSERT_NE(nullptr, result);
EXPECT_EQ(result->desktop_file_id, desktop_file_id); EXPECT_EQ(result->desktop_file_id, desktop_file_id);
......
// Copyright 2018 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/dbus/vm_applications_service_provider_delegate.h"
#include "chrome/browser/chromeos/crostini/crostini_registry_service.h"
#include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile_manager.h"
namespace chromeos {
VmApplicationsServiceProviderDelegate::VmApplicationsServiceProviderDelegate() =
default;
VmApplicationsServiceProviderDelegate::
~VmApplicationsServiceProviderDelegate() = default;
void VmApplicationsServiceProviderDelegate::UpdateApplicationList(
const vm_tools::apps::ApplicationList& app_list) {
Profile* profile = ProfileManager::GetPrimaryUserProfile();
if (!ProfileHelper::IsPrimaryProfile(profile))
return;
CrostiniRegistryService* registry_service =
CrostiniRegistryServiceFactory::GetForProfile(profile);
registry_service->UpdateApplicationList(app_list);
}
} // namespace chromeos
// Copyright 2018 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_DBUS_VM_APPLICATIONS_SERVICE_PROVIDER_DELEGATE_H_
#define CHROME_BROWSER_CHROMEOS_DBUS_VM_APPLICATIONS_SERVICE_PROVIDER_DELEGATE_H_
#include "base/macros.h"
#include "chromeos/dbus/services/vm_applications_service_provider.h"
namespace chromeos {
class VmApplicationsServiceProviderDelegate
: public VmApplicationsServiceProvider::Delegate {
public:
VmApplicationsServiceProviderDelegate();
~VmApplicationsServiceProviderDelegate() override;
// VmApplicationsServiceProvider::Delegate:
void UpdateApplicationList(
const vm_tools::apps::ApplicationList& app_list) override;
private:
DISALLOW_COPY_AND_ASSIGN(VmApplicationsServiceProviderDelegate);
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_DBUS_VM_APPLICATIONS_SERVICE_PROVIDER_DELEGATE_H_
...@@ -29,6 +29,7 @@ component("chromeos") { ...@@ -29,6 +29,7 @@ component("chromeos") {
":media_perception_proto", ":media_perception_proto",
":power_manager_proto", ":power_manager_proto",
":smbprovider_proto", ":smbprovider_proto",
":vm_applications_apps_proto",
"//base", "//base",
"//base:i18n", "//base:i18n",
"//base/third_party/dynamic_annotations", "//base/third_party/dynamic_annotations",
...@@ -270,6 +271,8 @@ component("chromeos") { ...@@ -270,6 +271,8 @@ component("chromeos") {
"dbus/services/proxy_resolution_service_provider.h", "dbus/services/proxy_resolution_service_provider.h",
"dbus/services/virtual_file_request_service_provider.cc", "dbus/services/virtual_file_request_service_provider.cc",
"dbus/services/virtual_file_request_service_provider.h", "dbus/services/virtual_file_request_service_provider.h",
"dbus/services/vm_applications_service_provider.cc",
"dbus/services/vm_applications_service_provider.h",
"dbus/session_manager_client.cc", "dbus/session_manager_client.cc",
"dbus/session_manager_client.h", "dbus/session_manager_client.h",
"dbus/shill_client_helper.cc", "dbus/shill_client_helper.cc",
...@@ -542,6 +545,7 @@ copy("dbus_service_files") { ...@@ -542,6 +545,7 @@ copy("dbus_service_files") {
"dbus/services/org.chromium.LivenessService.conf", "dbus/services/org.chromium.LivenessService.conf",
"dbus/services/org.chromium.NetworkProxyService.conf", "dbus/services/org.chromium.NetworkProxyService.conf",
"dbus/services/org.chromium.VirtualFileRequestService.conf", "dbus/services/org.chromium.VirtualFileRequestService.conf",
"dbus/services/org.chromium.VmApplicationsService.conf",
] ]
outputs = [ outputs = [
"$root_out_dir/dbus/{{source_file_part}}", "$root_out_dir/dbus/{{source_file_part}}",
...@@ -873,3 +877,11 @@ proto_library("concierge_proto") { ...@@ -873,3 +877,11 @@ proto_library("concierge_proto") {
proto_out_dir = "chromeos/dbus/concierge" proto_out_dir = "chromeos/dbus/concierge"
} }
proto_library("vm_applications_apps_proto") {
sources = [
"//third_party/cros_system_api/dbus/vm_applications/apps.proto",
]
proto_out_dir = "chromeos/dbus/vm_applications"
}
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<!--
Copyright 2018 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.
-->
<busconfig>
<policy user="chronos">
<allow own="org.chromium.VmApplicationsService"/>
</policy>
<!-- The concierge service runs as crosvm -->
<policy user="crosvm">
<allow send_destination="org.chromium.VmApplicationsService"
send_interface="org.chromium.VmApplicationsService"/>
</policy>
</busconfig>
// Copyright 2018 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/dbus/services/vm_applications_service_provider.h"
#include "base/bind.h"
#include "chromeos/dbus/vm_applications/apps.pb.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
VmApplicationsServiceProvider::VmApplicationsServiceProvider(
std::unique_ptr<Delegate> delegate)
: delegate_(std::move(delegate)), weak_ptr_factory_(this) {}
VmApplicationsServiceProvider::~VmApplicationsServiceProvider() = default;
void VmApplicationsServiceProvider::Start(
scoped_refptr<dbus::ExportedObject> exported_object) {
exported_object->ExportMethod(
vm_tools::apps::kVmApplicationsServiceInterface,
vm_tools::apps::kVmApplicationsServiceUpdateApplicationListMethod,
base::BindRepeating(&VmApplicationsServiceProvider::UpdateApplicationList,
weak_ptr_factory_.GetWeakPtr()),
base::BindRepeating(&VmApplicationsServiceProvider::OnExported,
weak_ptr_factory_.GetWeakPtr()));
}
void VmApplicationsServiceProvider::OnExported(
const std::string& interface_name,
const std::string& method_name,
bool success) {
LOG_IF(ERROR, !success) << "Failed to export " << interface_name << "."
<< method_name;
}
void VmApplicationsServiceProvider::UpdateApplicationList(
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender) {
dbus::MessageReader reader(method_call);
vm_tools::apps::ApplicationList request;
if (!reader.PopArrayOfBytesAsProto(&request)) {
constexpr char error_message[] =
"Unable to parse ApplicationList from message";
LOG(ERROR) << error_message;
response_sender.Run(dbus::ErrorResponse::FromMethodCall(
method_call, DBUS_ERROR_INVALID_ARGS, error_message));
return;
}
delegate_->UpdateApplicationList(request);
response_sender.Run(dbus::Response::FromMethodCall(method_call));
}
} // namespace chromeos
// Copyright 2018 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_DBUS_SERVICES_VM_APPLICATIONS_SERVICE_PROVIDER_H_
#define CHROMEOS_DBUS_SERVICES_VM_APPLICATIONS_SERVICE_PROVIDER_H_
#include <memory>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/services/cros_dbus_service.h"
#include "dbus/exported_object.h"
namespace dbus {
class MethodCall;
} // namespace dbus
namespace vm_tools {
namespace apps {
class ApplicationList;
} // namespace apps
} // namespace vm_tools
namespace chromeos {
// This class exports D-Bus methods for functions that we want to be available
// to the Crostini container.
class CHROMEOS_EXPORT VmApplicationsServiceProvider
: public CrosDBusService::ServiceProviderInterface {
public:
// Delegate interface providing additional resources to
// VmApplicationsServiceProvider.
class Delegate {
public:
Delegate() = default;
virtual ~Delegate() = default;
virtual void UpdateApplicationList(
const vm_tools::apps::ApplicationList& app_list) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
explicit VmApplicationsServiceProvider(std::unique_ptr<Delegate> delegate);
~VmApplicationsServiceProvider() override;
// CrosDBusService::ServiceProviderInterface overrides:
void Start(scoped_refptr<dbus::ExportedObject> exported_object) override;
private:
// Called from ExportedObject when UpdateApplicationList() is exported as a
// D-Bus method or failed to be exported.
void OnExported(const std::string& interface_name,
const std::string& method_name,
bool success);
// Called on UI thread in response to a D-Bus request.
void UpdateApplicationList(
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
std::unique_ptr<Delegate> delegate_;
base::WeakPtrFactory<VmApplicationsServiceProvider> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(VmApplicationsServiceProvider);
};
} // namespace chromeos
#endif // CHROMEOS_DBUS_SERVICES_VM_APPLICATIONS_SERVICE_PROVIDER_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