Commit e2e1a9ae authored by Xiaochu Liu's avatar Xiaochu Liu Committed by Commit Bot

component_updater: broadcast install signal to platform

On a successful install/update, component_updater sends a dbus signal to
platform. This allows compnoent consumers to be notified instead of
retrying calling the Load API.

Include dbus in chrome/browser/DEPS

BUG=chromium:822902
TEST=sudo -u root dbus-monitor --system  "type='signal',sender='org.chromium.ComponentUpdaterService',interface='org.chromium.ComponentUpdaterService'"

Change-Id: Ie913658329e6eb0cf0deb030fc772ec03fdbd8ea
Reviewed-on: https://chromium-review.googlesource.com/984600
Commit-Queue: Xiaochu Liu <xiaochu@chromium.org>
Reviewed-by: default avatarJoshua Pawlicki <waffles@chromium.org>
Reviewed-by: default avatarDan Erat <derat@chromium.org>
Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554921}
parent a02ed73c
......@@ -520,8 +520,6 @@ source_set("chromeos") {
"customization/customization_wallpaper_downloader.h",
"customization/customization_wallpaper_util.cc",
"customization/customization_wallpaper_util.h",
"dbus/chrome_component_updater_service_provider_delegate.cc",
"dbus/chrome_component_updater_service_provider_delegate.h",
"dbus/chrome_console_service_provider_delegate.cc",
"dbus/chrome_console_service_provider_delegate.h",
"dbus/chrome_display_power_service_provider_delegate.cc",
......@@ -530,6 +528,8 @@ source_set("chromeos") {
"dbus/chrome_proxy_resolution_service_provider_delegate.h",
"dbus/chrome_virtual_file_request_service_provider_delegate.cc",
"dbus/chrome_virtual_file_request_service_provider_delegate.h",
"dbus/component_updater_service_provider.cc",
"dbus/component_updater_service_provider.h",
"dbus/finch_features_service_provider_delegate.cc",
"dbus/finch_features_service_provider_delegate.h",
"dbus/kiosk_info_service_provider.cc",
......@@ -1750,6 +1750,7 @@ source_set("chromeos") {
copy("dbus_service_files") {
sources = [
"dbus/org.chromium.ComponentUpdaterService.conf",
"dbus/org.chromium.ScreenLockService.conf",
]
outputs = [
......
......@@ -46,11 +46,11 @@
#include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h"
#include "chrome/browser/chromeos/ash_config.h"
#include "chrome/browser/chromeos/boot_times_recorder.h"
#include "chrome/browser/chromeos/dbus/chrome_component_updater_service_provider_delegate.h"
#include "chrome/browser/chromeos/dbus/chrome_console_service_provider_delegate.h"
#include "chrome/browser/chromeos/dbus/chrome_display_power_service_provider_delegate.h"
#include "chrome/browser/chromeos/dbus/chrome_proxy_resolution_service_provider_delegate.h"
#include "chrome/browser/chromeos/dbus/chrome_virtual_file_request_service_provider_delegate.h"
#include "chrome/browser/chromeos/dbus/component_updater_service_provider.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/screen_lock_service_provider.h"
......@@ -125,7 +125,6 @@
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_policy_controller.h"
#include "chromeos/dbus/services/chrome_features_service_provider.h"
#include "chromeos/dbus/services/component_updater_service_provider.h"
#include "chromeos/dbus/services/console_service_provider.h"
#include "chromeos/dbus/services/cros_dbus_service.h"
#include "chromeos/dbus/services/display_power_service_provider.h"
......@@ -406,8 +405,7 @@ class DBusServices {
dbus::ObjectPath(kComponentUpdaterServicePath),
CrosDBusService::CreateServiceProviderList(
std::make_unique<ComponentUpdaterServiceProvider>(
std::make_unique<
ChromeComponentUpdaterServiceProviderDelegate>())));
g_browser_process->platform_part()->cros_component_manager())));
finch_features_service_ = CrosDBusService::Create(
kChromeFeaturesServiceName,
......@@ -671,6 +669,10 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() {
// device_event_log must be initialized after the message loop.
device_event_log::Initialize(0 /* default max entries */);
// This has to be initialized before DBusServices
// (ComponentUpdaterServiceProvider).
g_browser_process->platform_part()->InitializeCrosComponentManager();
dbus_services_.reset(new internal::DBusServices(parameters()));
// Need to be done after LoginState has been initialized in DBusServices().
......@@ -881,8 +883,6 @@ void ChromeBrowserMainPartsChromeos::PreProfileInit() {
VLOG(1) << "Relaunching browser for user: " << account_id.Serialize()
<< " with hash: " << user_id_hash;
}
g_browser_process->platform_part()->InitializeCrosComponentManager();
}
class GuestLanguageSetCallbackData {
......@@ -1221,14 +1221,16 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopRun() {
g_browser_process->platform_part()->ShutdownSessionManager();
// Ash needs to be closed before UserManager is destroyed.
g_browser_process->platform_part()->DestroyChromeUserManager();
g_browser_process->platform_part()->ShutdownCrosComponentManager();
}
void ChromeBrowserMainPartsChromeos::PostDestroyThreads() {
// Destroy DBus services immediately after threads are stopped.
dbus_services_.reset();
// This has to be destroyed after DBusServices
// (ComponentUpdaterServiceProvider).
g_browser_process->platform_part()->ShutdownCrosComponentManager();
dbus_pre_early_init_.reset();
// Reset SystemTokenCertDBInitializer after DBus services because it should
......
// Copyright 2017 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/chrome_component_updater_service_provider_delegate.h"
#include "base/bind.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/component_updater/cros_component_installer.h"
namespace chromeos {
namespace {
std::string ErrorToString(
component_updater::CrOSComponentManager::Error error) {
switch (error) {
case component_updater::CrOSComponentManager::Error::NONE:
return "NONE";
case component_updater::CrOSComponentManager::Error::UNKNOWN_COMPONENT:
return "UNKNOWN_COMPONENT";
case component_updater::CrOSComponentManager::Error::INSTALL_FAILURE:
return "INSTALL_FAILURE";
case component_updater::CrOSComponentManager::Error::MOUNT_FAILURE:
return "MOUNT_FAILURE";
case component_updater::CrOSComponentManager::Error::
COMPATIBILITY_CHECK_FAILED:
return "COMPATIBILITY_CHECK_FAILED";
case component_updater::CrOSComponentManager::Error::ERROR_MAX:
return "ERROR_MAX";
}
return "Unknown error code";
}
void OnLoadComponent(
ChromeComponentUpdaterServiceProviderDelegate::LoadCallback load_callback,
component_updater::CrOSComponentManager::Error error,
const base::FilePath& mount_path) {
if (error != component_updater::CrOSComponentManager::Error::NONE) {
LOG(ERROR) << "component updater Load API error: " << ErrorToString(error);
}
std::move(load_callback).Run(mount_path);
}
} // namespace
ChromeComponentUpdaterServiceProviderDelegate::
ChromeComponentUpdaterServiceProviderDelegate() {}
ChromeComponentUpdaterServiceProviderDelegate::
~ChromeComponentUpdaterServiceProviderDelegate() {}
void ChromeComponentUpdaterServiceProviderDelegate::LoadComponent(
const std::string& name,
bool mount,
LoadCallback load_callback) {
g_browser_process->platform_part()->cros_component_manager()->Load(
name,
mount ? component_updater::CrOSComponentManager::MountPolicy::kMount
: component_updater::CrOSComponentManager::MountPolicy::kDontMount,
base::BindOnce(OnLoadComponent, std::move(load_callback)));
}
bool ChromeComponentUpdaterServiceProviderDelegate::UnloadComponent(
const std::string& name) {
return g_browser_process->platform_part()->cros_component_manager()->Unload(
name);
}
} // namespace chromeos
// Copyright 2017 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_CHROME_COMPONENT_UPDATER_SERVICE_PROVIDER_DELEGATE_H_
#define CHROME_BROWSER_CHROMEOS_DBUS_CHROME_COMPONENT_UPDATER_SERVICE_PROVIDER_DELEGATE_H_
#include "base/macros.h"
#include "chromeos/dbus/services/component_updater_service_provider.h"
namespace chromeos {
// Chrome's implementation of ChromeComponentUpdaterServiceProvider::Delegate.
class ChromeComponentUpdaterServiceProviderDelegate
: public ComponentUpdaterServiceProvider::Delegate {
public:
ChromeComponentUpdaterServiceProviderDelegate();
~ChromeComponentUpdaterServiceProviderDelegate() override;
// ComponentUpdaterServiceProvider::Delegate:
void LoadComponent(const std::string& name,
bool mount,
LoadCallback load_callback) override;
bool UnloadComponent(const std::string& name) override;
private:
DISALLOW_COPY_AND_ASSIGN(ChromeComponentUpdaterServiceProviderDelegate);
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_DBUS_CHROME_COMPONENT_UPDATER_SERVICE_PROVIDER_DELEGATE_H_
// Copyright 2017 The Chromium Authors. All rights reserved.
// 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/component_updater_service_provider.h"
#include "chrome/browser/chromeos/dbus/component_updater_service_provider.h"
#include <utility>
#include "base/bind.h"
#include "base/files/file_path.h"
#include "chrome/browser/component_updater/cros_component_installer.h"
#include "content/public/browser/browser_thread.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
......@@ -15,15 +17,44 @@
namespace chromeos {
namespace {
const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs";
const char kErrorInternalError[] = "org.freedesktop.DBus.Error.InternalError";
std::string ErrorToString(
component_updater::CrOSComponentManager::Error error) {
switch (error) {
case component_updater::CrOSComponentManager::Error::NONE:
return "NONE";
case component_updater::CrOSComponentManager::Error::UNKNOWN_COMPONENT:
return "UNKNOWN_COMPONENT";
case component_updater::CrOSComponentManager::Error::INSTALL_FAILURE:
return "INSTALL_FAILURE";
case component_updater::CrOSComponentManager::Error::MOUNT_FAILURE:
return "MOUNT_FAILURE";
case component_updater::CrOSComponentManager::Error::
COMPATIBILITY_CHECK_FAILED:
return "COMPATIBILITY_CHECK_FAILED";
case component_updater::CrOSComponentManager::Error::ERROR_MAX:
return "ERROR_MAX";
}
return "Unknown error code";
}
} // namespace
ComponentUpdaterServiceProvider::ComponentUpdaterServiceProvider(
std::unique_ptr<Delegate> delegate)
: delegate_(std::move(delegate)), weak_ptr_factory_(this) {}
component_updater::CrOSComponentManager* cros_component_manager)
: weak_ptr_factory_(this) {
DCHECK(cros_component_manager);
ComponentUpdaterServiceProvider::~ComponentUpdaterServiceProvider() = default;
cros_component_manager_ = cros_component_manager;
cros_component_manager_->SetDelegate(this);
}
ComponentUpdaterServiceProvider::~ComponentUpdaterServiceProvider() {
cros_component_manager_->SetDelegate(nullptr);
}
void ComponentUpdaterServiceProvider::Start(
scoped_refptr<dbus::ExportedObject> exported_object) {
......@@ -42,6 +73,17 @@ void ComponentUpdaterServiceProvider::Start(
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&ComponentUpdaterServiceProvider::OnExported,
weak_ptr_factory_.GetWeakPtr()));
exported_object_ = exported_object;
}
void ComponentUpdaterServiceProvider::EmitInstalledSignal(
const std::string& component) {
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::BindOnce(
&ComponentUpdaterServiceProvider::EmitInstalledSignalInternal,
weak_ptr_factory_.GetWeakPtr(), component));
}
void ComponentUpdaterServiceProvider::OnExported(
......@@ -65,11 +107,14 @@ void ComponentUpdaterServiceProvider::LoadComponent(
// Resets |mount| to its default value on failure.
if (!reader.PopBool(&mount))
mount = true;
delegate_->LoadComponent(
component_name, mount,
base::BindOnce(&ComponentUpdaterServiceProvider::OnLoadComponent,
weak_ptr_factory_.GetWeakPtr(), method_call,
response_sender));
cros_component_manager_->Load(
component_name,
mount
? component_updater::CrOSComponentManager::MountPolicy::kMount
: component_updater::CrOSComponentManager::MountPolicy::kDontMount,
base::Bind(&ComponentUpdaterServiceProvider::OnLoadComponent,
weak_ptr_factory_.GetWeakPtr(), method_call,
response_sender));
} else {
std::unique_ptr<dbus::ErrorResponse> error_response =
dbus::ErrorResponse::FromMethodCall(
......@@ -82,7 +127,12 @@ void ComponentUpdaterServiceProvider::LoadComponent(
void ComponentUpdaterServiceProvider::OnLoadComponent(
dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender,
component_updater::CrOSComponentManager::Error error,
const base::FilePath& result) {
if (error != component_updater::CrOSComponentManager::Error::NONE) {
LOG(ERROR) << "Component updater Load API error: " << ErrorToString(error);
}
std::unique_ptr<dbus::Response> response =
dbus::Response::FromMethodCall(method_call);
dbus::MessageWriter writer(response.get());
......@@ -96,7 +146,7 @@ void ComponentUpdaterServiceProvider::UnloadComponent(
dbus::MessageReader reader(method_call);
std::string component_name;
if (reader.PopString(&component_name)) {
if (delegate_->UnloadComponent(component_name)) {
if (cros_component_manager_->Unload(component_name)) {
response_sender.Run(dbus::Response::FromMethodCall(method_call));
} else {
response_sender.Run(dbus::ErrorResponse::FromMethodCall(
......@@ -109,4 +159,17 @@ void ComponentUpdaterServiceProvider::UnloadComponent(
}
}
void ComponentUpdaterServiceProvider::EmitInstalledSignalInternal(
const std::string& component) {
DCHECK(exported_object_);
dbus::Signal signal(
chromeos::kComponentUpdaterServiceInterface,
chromeos::kComponentUpdaterServiceComponentInstalledSignal);
dbus::MessageWriter writer(&signal);
writer.AppendString(component);
exported_object_->SendSignal(&signal);
}
} // namespace chromeos
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// 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_COMPONENT_UPDATER_SERVICE_PROVIDER_H_
#define CHROMEOS_DBUS_SERVICES_COMPONENT_UPDATER_SERVICE_PROVIDER_H_
#ifndef CHROME_BROWSER_CHROMEOS_DBUS_COMPONENT_UPDATER_SERVICE_PROVIDER_H_
#define CHROME_BROWSER_CHROMEOS_DBUS_COMPONENT_UPDATER_SERVICE_PROVIDER_H_
#include <memory>
#include <string>
......@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/component_updater/cros_component_installer.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/services/cros_dbus_service.h"
#include "dbus/exported_object.h"
......@@ -43,7 +44,8 @@ namespace chromeos {
//
// % (returns empty response on success and error response on failure)
class CHROMEOS_EXPORT ComponentUpdaterServiceProvider
: public CrosDBusService::ServiceProviderInterface {
: public CrosDBusService::ServiceProviderInterface,
public component_updater::CrOSComponentManager::Delegate {
public:
// Delegate interface providing additional resources to
// ComponentUpdaterServiceProvider.
......@@ -64,12 +66,16 @@ class CHROMEOS_EXPORT ComponentUpdaterServiceProvider
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
explicit ComponentUpdaterServiceProvider(std::unique_ptr<Delegate> delegate);
explicit ComponentUpdaterServiceProvider(
component_updater::CrOSComponentManager* cros_component_manager);
~ComponentUpdaterServiceProvider() override;
// CrosDBusService::ServiceProviderInterface overrides:
void Start(scoped_refptr<dbus::ExportedObject> exported_object) override;
// component_updater::CrOSComponentManager::Delegate overrides:
void EmitInstalledSignal(const std::string& component) override;
private:
// Called from ExportedObject when LoadComponent() is exported as a D-Bus
// method or failed to be exported.
......@@ -84,13 +90,22 @@ class CHROMEOS_EXPORT ComponentUpdaterServiceProvider
// Callback executed after component loading operation is done.
void OnLoadComponent(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender,
component_updater::CrOSComponentManager::Error error,
const base::FilePath& result);
// Called on UI thread in response to a D-Bus request.
void UnloadComponent(dbus::MethodCall* method_call,
dbus::ExportedObject::ResponseSender response_sender);
std::unique_ptr<Delegate> delegate_;
// Implements EmitInstalledSignal.
void EmitInstalledSignalInternal(const std::string& component);
// A reference on ExportedObject for sending signals.
scoped_refptr<dbus::ExportedObject> exported_object_;
// Weak pointer to CrOSComponentManager to avoid calling BrowserProcess.
component_updater::CrOSComponentManager* cros_component_manager_;
// Keep this last so that all weak pointers will be invalidated at the
// beginning of destruction.
base::WeakPtrFactory<ComponentUpdaterServiceProvider> weak_ptr_factory_;
......@@ -100,4 +115,4 @@ class CHROMEOS_EXPORT ComponentUpdaterServiceProvider
} // namespace chromeos
#endif // CHROMEOS_DBUS_SERVICES_COMPONENT_UPDATER_SERVICE_PROVIDER_H_
#endif // CHROME_BROWSER_CHROMEOS_DBUS_COMPONENT_UPDATER_SERVICE_PROVIDER_H_
......@@ -125,6 +125,10 @@ CrOSComponentInstallerPolicy::OnCustomInstall(
// TODO(xiaochu): remove after M66 ships to stable. https://crbug.com/792203
CleanUpOldInstalls(name_);
g_browser_process->platform_part()
->cros_component_manager()
->EmitInstalledSignal(GetName());
return update_client::CrxInstaller::Result(update_client::InstallError::NONE);
}
......@@ -198,6 +202,10 @@ CrOSComponentManager::CrOSComponentManager() {}
CrOSComponentManager::~CrOSComponentManager() {}
void CrOSComponentManager::SetDelegate(Delegate* delegate) {
delegate_ = delegate;
}
void CrOSComponentManager::Load(const std::string& name,
MountPolicy mount_policy,
LoadCallback load_callback) {
......@@ -242,16 +250,17 @@ void CrOSComponentManager::UnregisterCompatiblePath(const std::string& name) {
compatible_components_.erase(name);
}
bool CrOSComponentManager::IsCompatible(const std::string& name) const {
return compatible_components_.count(name) > 0;
}
base::FilePath CrOSComponentManager::GetCompatiblePath(
const std::string& name) const {
const auto it = compatible_components_.find(name);
return it == compatible_components_.end() ? base::FilePath() : it->second;
}
void CrOSComponentManager::EmitInstalledSignal(const std::string& component) {
if (delegate_)
delegate_->EmitInstalledSignal(component);
}
void CrOSComponentManager::Register(ComponentUpdateService* cus,
const ComponentConfig& config,
base::OnceClosure register_callback) {
......@@ -354,4 +363,8 @@ void CrOSComponentManager::RegisterN(
}
}
bool CrOSComponentManager::IsCompatible(const std::string& name) const {
return compatible_components_.count(name) > 0;
}
} // namespace component_updater
......@@ -85,9 +85,18 @@ class CrOSComponentManager {
kDontMount,
};
class Delegate {
public:
virtual ~Delegate() {}
// Broadcasts a D-Bus signal for a successful component installation.
virtual void EmitInstalledSignal(const std::string& component) = 0;
};
CrOSComponentManager();
~CrOSComponentManager();
void SetDelegate(Delegate* delegate);
// Installs a component and keeps it up-to-date. |load_callback| returns the
// mount point path.
void Load(const std::string& name,
......@@ -109,16 +118,22 @@ class CrOSComponentManager {
// Removes the name and install path entry of a component.
void UnregisterCompatiblePath(const std::string& name);
// Checks if the current installed component is compatible given a component
// |name|. If compatible, sets |path| to be its installed path.
bool IsCompatible(const std::string& name) const;
// Returns installed path of a compatible component given |name|. Returns an
// empty path if the component isn't compatible.
base::FilePath GetCompatiblePath(const std::string& name) const;
// Called when a component is installed/updated.
// Broadcasts a D-Bus signal for a successful component installation.
void EmitInstalledSignal(const std::string& component);
private:
FRIEND_TEST_ALL_PREFIXES(CrOSComponentInstallerTest, RegisterComponent);
FRIEND_TEST_ALL_PREFIXES(CrOSComponentInstallerTest,
BPPPCompatibleCrOSComponent);
FRIEND_TEST_ALL_PREFIXES(CrOSComponentInstallerTest, CompatibilityOK);
FRIEND_TEST_ALL_PREFIXES(CrOSComponentInstallerTest,
CompatibilityMissingManifest);
FRIEND_TEST_ALL_PREFIXES(CrOSComponentInstallerTest, IsCompatibleOrNot);
// Registers a component with a dedicated ComponentUpdateService instance.
void Register(ComponentUpdateService* cus,
......@@ -155,9 +170,16 @@ class CrOSComponentManager {
// Registers component |configs| to be updated.
void RegisterN(const std::vector<ComponentConfig>& configs);
// Checks if the current installed component is compatible given a component
// |name|.
bool IsCompatible(const std::string& name) const;
// Maps from a compatible component name to its installed path.
base::flat_map<std::string, base::FilePath> compatible_components_;
// A weak pointer to a Delegate for emitting D-Bus signal.
Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(CrOSComponentManager);
};
......
......@@ -266,8 +266,6 @@ component("chromeos") {
"dbus/power_policy_controller.h",
"dbus/services/chrome_features_service_provider.cc",
"dbus/services/chrome_features_service_provider.h",
"dbus/services/component_updater_service_provider.cc",
"dbus/services/component_updater_service_provider.h",
"dbus/services/console_service_provider.cc",
"dbus/services/console_service_provider.h",
"dbus/services/cros_dbus_service.cc",
......@@ -551,7 +549,6 @@ component("chromeos") {
copy("dbus_service_files") {
sources = [
"dbus/services/org.chromium.ChromeFeaturesService.conf",
"dbus/services/org.chromium.ComponentUpdaterService.conf",
"dbus/services/org.chromium.DisplayService.conf",
"dbus/services/org.chromium.KioskAppService.conf",
"dbus/services/org.chromium.LibCrosService.conf",
......
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