From 1472afec75d2289eed4d754c2108441f75da6e70 Mon Sep 17 00:00:00 2001 From: hashimoto Date: Mon, 17 Nov 2014 22:18:40 -0800 Subject: Move CrosDBusService to chromeos Create a new directory chromeos/dbus/services. Move CrosDBusService, LivenessServiceProvider and ServiceProviderTestHelper to the new directory. BUG=429354 Review URL: https://codereview.chromium.org/732963005 Cr-Commit-Position: refs/heads/master@{#304569} --- .../chromeos/chrome_browser_main_chromeos.cc | 4 +- .../chromeos/dbus/console_service_provider.h | 2 +- chrome/browser/chromeos/dbus/cros_dbus_service.cc | 150 ------------------- chrome/browser/chromeos/dbus/cros_dbus_service.h | 67 --------- .../chromeos/dbus/cros_dbus_service_unittest.cc | 92 ------------ .../chromeos/dbus/display_power_service_provider.h | 2 +- .../chromeos/dbus/liveness_service_provider.cc | 44 ------ .../chromeos/dbus/liveness_service_provider.h | 66 --------- .../chromeos/dbus/printer_service_provider.h | 2 +- .../dbus/printer_service_provider_unittest.cc | 2 +- .../dbus/proxy_resolution_service_provider.h | 2 +- .../proxy_resolution_service_provider_unittest.cc | 2 +- .../chromeos/dbus/screen_lock_service_provider.h | 2 +- .../chromeos/dbus/service_provider_test_helper.cc | 164 --------------------- .../chromeos/dbus/service_provider_test_helper.h | 98 ------------ chrome/chrome_browser_chromeos.gypi | 4 - chrome/chrome_tests_unit.gypi | 3 - chromeos/BUILD.gn | 2 + chromeos/chromeos.gyp | 7 + chromeos/dbus/services/cros_dbus_service.cc | 150 +++++++++++++++++++ chromeos/dbus/services/cros_dbus_service.h | 68 +++++++++ .../dbus/services/cros_dbus_service_unittest.cc | 92 ++++++++++++ .../dbus/services/liveness_service_provider.cc | 44 ++++++ chromeos/dbus/services/liveness_service_provider.h | 67 +++++++++ .../dbus/services/service_provider_test_helper.cc | 164 +++++++++++++++++++++ .../dbus/services/service_provider_test_helper.h | 98 ++++++++++++ 26 files changed, 701 insertions(+), 697 deletions(-) delete mode 100644 chrome/browser/chromeos/dbus/cros_dbus_service.cc delete mode 100644 chrome/browser/chromeos/dbus/cros_dbus_service.h delete mode 100644 chrome/browser/chromeos/dbus/cros_dbus_service_unittest.cc delete mode 100644 chrome/browser/chromeos/dbus/liveness_service_provider.cc delete mode 100644 chrome/browser/chromeos/dbus/liveness_service_provider.h delete mode 100644 chrome/browser/chromeos/dbus/service_provider_test_helper.cc delete mode 100644 chrome/browser/chromeos/dbus/service_provider_test_helper.h create mode 100644 chromeos/dbus/services/cros_dbus_service.cc create mode 100644 chromeos/dbus/services/cros_dbus_service.h create mode 100644 chromeos/dbus/services/cros_dbus_service_unittest.cc create mode 100644 chromeos/dbus/services/liveness_service_provider.cc create mode 100644 chromeos/dbus/services/liveness_service_provider.h create mode 100644 chromeos/dbus/services/service_provider_test_helper.cc create mode 100644 chromeos/dbus/services/service_provider_test_helper.h diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index f26b713..8758015 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -30,9 +30,7 @@ #include "chrome/browser/chromeos/app_mode/kiosk_mode_idle_app_name_notification.h" #include "chrome/browser/chromeos/boot_times_loader.h" #include "chrome/browser/chromeos/dbus/console_service_provider.h" -#include "chrome/browser/chromeos/dbus/cros_dbus_service.h" #include "chrome/browser/chromeos/dbus/display_power_service_provider.h" -#include "chrome/browser/chromeos/dbus/liveness_service_provider.h" #include "chrome/browser/chromeos/dbus/printer_service_provider.h" #include "chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h" #include "chrome/browser/chromeos/dbus/screen_lock_service_provider.h" @@ -97,6 +95,8 @@ #include "chromeos/cryptohome/system_salt_getter.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/power_policy_controller.h" +#include "chromeos/dbus/services/cros_dbus_service.h" +#include "chromeos/dbus/services/liveness_service_provider.h" #include "chromeos/dbus/session_manager_client.h" #include "chromeos/disks/disk_mount_manager.h" #include "chromeos/ime/ime_keyboard.h" diff --git a/chrome/browser/chromeos/dbus/console_service_provider.h b/chrome/browser/chromeos/dbus/console_service_provider.h index 2df5fee..864161d 100644 --- a/chrome/browser/chromeos/dbus/console_service_provider.h +++ b/chrome/browser/chromeos/dbus/console_service_provider.h @@ -8,7 +8,7 @@ #include #include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/dbus/cros_dbus_service.h" +#include "chromeos/dbus/services/cros_dbus_service.h" #include "dbus/exported_object.h" namespace chromeos { diff --git a/chrome/browser/chromeos/dbus/cros_dbus_service.cc b/chrome/browser/chromeos/dbus/cros_dbus_service.cc deleted file mode 100644 index 7f9598e..0000000 --- a/chrome/browser/chromeos/dbus/cros_dbus_service.cc +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2012 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/cros_dbus_service.h" - -#include "base/bind.h" -#include "base/stl_util.h" -#include "base/sys_info.h" -#include "base/threading/platform_thread.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "dbus/bus.h" -#include "dbus/exported_object.h" -#include "dbus/object_path.h" -#include "third_party/cros_system_api/dbus/service_constants.h" - -namespace chromeos { - -namespace { - -CrosDBusService* g_cros_dbus_service = NULL; - -} // namespace - -// The CrosDBusService implementation used in production, and unit tests. -class CrosDBusServiceImpl : public CrosDBusService { - public: - CrosDBusServiceImpl(dbus::Bus* bus, - ScopedVector service_providers) - : service_started_(false), - origin_thread_id_(base::PlatformThread::CurrentId()), - bus_(bus), - service_providers_(service_providers.Pass()) { - } - - ~CrosDBusServiceImpl() override { - } - - // Starts the D-Bus service. - void Start() { - // Make sure we're running on the origin thread (i.e. the UI thread in - // production). - DCHECK(OnOriginThread()); - - // Return if the service has been already started. - if (service_started_) - return; - - // There are some situations, described in http://crbug.com/234382#c27, - // where processes on Linux can wind up stuck in an uninterruptible state - // for tens of seconds. If this happens when Chrome is trying to exit, - // this unkillable process can wind up clinging to ownership of - // kLibCrosServiceName while the system is trying to restart the browser. - // This leads to a fatal situation if we don't allow the new browser - // instance to replace the old as the owner of kLibCrosServiceName as seen - // in http://crbug.com/234382. Hence, REQUIRE_PRIMARY_ALLOW_REPLACEMENT. - bus_->RequestOwnership(kLibCrosServiceName, - dbus::Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT, - base::Bind(&CrosDBusServiceImpl::OnOwnership, - base::Unretained(this))); - - exported_object_ = bus_->GetExportedObject( - dbus::ObjectPath(kLibCrosServicePath)); - - for (size_t i = 0; i < service_providers_.size(); ++i) - service_providers_[i]->Start(exported_object_); - - service_started_ = true; - - VLOG(1) << "CrosDBusServiceImpl started."; - } - - private: - // Returns true if the current thread is on the origin thread. - bool OnOriginThread() { - return base::PlatformThread::CurrentId() == origin_thread_id_; - } - - // Called when an ownership request is completed. - void OnOwnership(const std::string& service_name, - bool success) { - LOG_IF(FATAL, !success) << "Failed to own: " << service_name; - } - - bool service_started_; - base::PlatformThreadId origin_thread_id_; - dbus::Bus* bus_; - scoped_refptr exported_object_; - - // Service providers that form CrosDBusService. - ScopedVector service_providers_; -}; - -// The stub CrosDBusService implementation used on Linux desktop, -// which does nothing as of now. -class CrosDBusServiceStubImpl : public CrosDBusService { - public: - CrosDBusServiceStubImpl() { - } - - virtual ~CrosDBusServiceStubImpl() { - } -}; - -// static -void CrosDBusService::Initialize( - ScopedVector service_providers) { - if (g_cros_dbus_service) { - LOG(WARNING) << "CrosDBusService was already initialized"; - return; - } - dbus::Bus* bus = DBusThreadManager::Get()->GetSystemBus(); - if (base::SysInfo::IsRunningOnChromeOS() && bus) { - auto* service = new CrosDBusServiceImpl(bus, service_providers.Pass()); - g_cros_dbus_service = service; - service->Start(); - } else { - g_cros_dbus_service = new CrosDBusServiceStubImpl; - } - VLOG(1) << "CrosDBusService initialized"; -} - -// static -void CrosDBusService::InitializeForTesting( - dbus::Bus* bus, - ScopedVector service_providers) { - if (g_cros_dbus_service) { - LOG(WARNING) << "CrosDBusService was already initialized"; - return; - } - auto* service = new CrosDBusServiceImpl(bus, service_providers.Pass()); - service->Start(); - g_cros_dbus_service = service; - VLOG(1) << "CrosDBusService initialized"; -} - -// static -void CrosDBusService::Shutdown() { - delete g_cros_dbus_service; - g_cros_dbus_service = NULL; - VLOG(1) << "CrosDBusService Shutdown completed"; -} - -CrosDBusService::~CrosDBusService() { -} - -CrosDBusService::ServiceProviderInterface::~ServiceProviderInterface() { -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/dbus/cros_dbus_service.h b/chrome/browser/chromeos/dbus/cros_dbus_service.h deleted file mode 100644 index d745af8..0000000 --- a/chrome/browser/chromeos/dbus/cros_dbus_service.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2012 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_CROS_DBUS_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_DBUS_CROS_DBUS_SERVICE_H_ - -#include - -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_vector.h" -#include "base/threading/platform_thread.h" - -namespace dbus { -class Bus; -class ExportedObject; -} - -namespace chromeos { - -// CrosDBusService is used to run a D-Bus service inside Chrome for Chrome -// OS. The service will be registered as follows: -// -// Service name: org.chromium.LibCrosService (kLibCrosServiceName) -// Object path: chromium/LibCrosService (kLibCrosServicePath) -// -// For historical reasons, the rather irrelevant name "LibCrosService" is -// used in the D-Bus constants such as the service name. -// -// CrosDBusService exports D-Bus methods through service provider classes -// that implement CrosDBusService::ServiceProviderInterface. - -class CrosDBusService { - public: - // CrosDBusService consists of service providers that implement this - // interface. - class ServiceProviderInterface { - public: - // Starts the service provider. |exported_object| is used to export - // D-Bus methods. - virtual void Start( - scoped_refptr exported_object) = 0; - - virtual ~ServiceProviderInterface(); - }; - - // Initializes the global instance. - static void Initialize( - ScopedVector service_providers); - // Destroys the global instance. - static void Shutdown(); - - protected: - virtual ~CrosDBusService(); - - private: - friend class CrosDBusServiceTest; - - // Initializes the global instance for testing. - static void InitializeForTesting( - dbus::Bus* bus, - ScopedVector service_providers); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_DBUS_CROS_DBUS_SERVICE_H_ diff --git a/chrome/browser/chromeos/dbus/cros_dbus_service_unittest.cc b/chrome/browser/chromeos/dbus/cros_dbus_service_unittest.cc deleted file mode 100644 index 6aba129..0000000 --- a/chrome/browser/chromeos/dbus/cros_dbus_service_unittest.cc +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2012 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/cros_dbus_service.h" - -#include "base/bind.h" -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "dbus/message.h" -#include "dbus/mock_bus.h" -#include "dbus/mock_exported_object.h" -#include "dbus/mock_object_proxy.h" -#include "dbus/object_path.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/cros_system_api/dbus/service_constants.h" - -using ::testing::Eq; -using ::testing::Invoke; -using ::testing::Return; - -namespace chromeos { - -class MockProxyResolutionService - : public CrosDBusService::ServiceProviderInterface { - public: - MOCK_METHOD1(Start, void(scoped_refptr - exported_object)); -}; - -class CrosDBusServiceTest : public testing::Test { - public: - CrosDBusServiceTest() { - } - - // Creates an instance of CrosDBusService with mocks injected. - virtual void SetUp() { - // Create a mock bus. - dbus::Bus::Options options; - options.bus_type = dbus::Bus::SYSTEM; - mock_bus_ = new dbus::MockBus(options); - - // ShutdownAndBlock() will be called in TearDown(). - EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); - - // Create a mock exported object that behaves as - // org.chromium.CrosDBusService. - mock_exported_object_ = - new dbus::MockExportedObject(mock_bus_.get(), - dbus::ObjectPath(kLibCrosServicePath)); - - // |mock_bus_|'s GetExportedObject() will return mock_exported_object_| - // for the given service name and the object path. - EXPECT_CALL(*mock_bus_.get(), - GetExportedObject(dbus::ObjectPath(kLibCrosServicePath))) - .WillOnce(Return(mock_exported_object_.get())); - - // Create a mock proxy resolution service. - MockProxyResolutionService* mock_proxy_resolution_service_provider = - new MockProxyResolutionService; - - // Start() will be called with |mock_exported_object_|. - EXPECT_CALL(*mock_proxy_resolution_service_provider, - Start(Eq(mock_exported_object_))).WillOnce(Return()); - // Initialize the cros service with the mocks injected. - ScopedVector service_providers; - service_providers.push_back(mock_proxy_resolution_service_provider); - CrosDBusService::InitializeForTesting( - mock_bus_.get(), service_providers.Pass()); - } - - virtual void TearDown() { - // Shutdown the cros service. - CrosDBusService::Shutdown(); - - // Shutdown the bus. - mock_bus_->ShutdownAndBlock(); - } - - protected: - scoped_refptr mock_bus_; - scoped_refptr mock_exported_object_; -}; - -TEST_F(CrosDBusServiceTest, Start) { - // Simply start the service and see if mock expectations are met: - // - The service object is exported by GetExportedObject() - // - The proxy resolution service is started. -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/dbus/display_power_service_provider.h b/chrome/browser/chromeos/dbus/display_power_service_provider.h index 691fb29..f725284 100644 --- a/chrome/browser/chromeos/dbus/display_power_service_provider.h +++ b/chrome/browser/chromeos/dbus/display_power_service_provider.h @@ -11,7 +11,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/dbus/cros_dbus_service.h" +#include "chromeos/dbus/services/cros_dbus_service.h" #include "dbus/exported_object.h" namespace dbus { diff --git a/chrome/browser/chromeos/dbus/liveness_service_provider.cc b/chrome/browser/chromeos/dbus/liveness_service_provider.cc deleted file mode 100644 index fa53212..0000000 --- a/chrome/browser/chromeos/dbus/liveness_service_provider.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2012 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/liveness_service_provider.h" - -#include "base/bind.h" -#include "dbus/bus.h" -#include "dbus/message.h" -#include "third_party/cros_system_api/dbus/service_constants.h" - -namespace chromeos { - -LivenessServiceProvider::LivenessServiceProvider() : weak_ptr_factory_(this) {} - -LivenessServiceProvider::~LivenessServiceProvider() {} - -void LivenessServiceProvider::Start( - scoped_refptr exported_object) { - exported_object->ExportMethod( - kLibCrosServiceInterface, - kCheckLiveness, - base::Bind(&LivenessServiceProvider::CheckLiveness, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&LivenessServiceProvider::OnExported, - weak_ptr_factory_.GetWeakPtr())); -} - -void LivenessServiceProvider::OnExported(const std::string& interface_name, - const std::string& method_name, - bool success) { - if (!success) { - LOG(ERROR) << "Failed to export " << interface_name << "." - << method_name; - } -} - -void LivenessServiceProvider::CheckLiveness( - dbus::MethodCall* method_call, - dbus::ExportedObject::ResponseSender response_sender) { - response_sender.Run(dbus::Response::FromMethodCall(method_call)); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/dbus/liveness_service_provider.h b/chrome/browser/chromeos/dbus/liveness_service_provider.h deleted file mode 100644 index 8d0c87e..0000000 --- a/chrome/browser/chromeos/dbus/liveness_service_provider.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2012 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_LIVENESS_SERVICE_PROVIDER_H_ -#define CHROME_BROWSER_CHROMEOS_DBUS_LIVENESS_SERVICE_PROVIDER_H_ - -#include - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/dbus/cros_dbus_service.h" -#include "dbus/exported_object.h" - -namespace dbus { -class MethodCall; -class Response; -} - -namespace chromeos { - -// This class exports a "CheckLiveness" D-Bus method that the session manager -// calls periodically to confirm that Chrome's UI thread is responsive to D-Bus -// messages. It can be tested with the following command: -// -// % dbus-send --system --type=method_call --print-reply -// --dest=org.chromium.LibCrosService -// /org/chromium/LibCrosService -// org.chromium.LibCrosServiceInterface.CheckLiveness -// -// -> method return sender=:1.9 -> dest=:1.27 reply_serial=2 -// -// (An empty response should be returned.) -class LivenessServiceProvider - : public CrosDBusService::ServiceProviderInterface { - public: - LivenessServiceProvider(); - virtual ~LivenessServiceProvider(); - - // CrosDBusService::ServiceProviderInterface overrides: - virtual void Start( - scoped_refptr exported_object) override; - - private: - // Called from ExportedObject when CheckLiveness() 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 CheckLiveness(dbus::MethodCall* method_call, - dbus::ExportedObject::ResponseSender response_sender); - - // Keep this last so that all weak pointers will be invalidated at the - // beginning of destruction. - base::WeakPtrFactory weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(LivenessServiceProvider); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_DBUS_LIVENESS_SERVICE_PROVIDER_H_ diff --git a/chrome/browser/chromeos/dbus/printer_service_provider.h b/chrome/browser/chromeos/dbus/printer_service_provider.h index 988a51d..3ab8971 100644 --- a/chrome/browser/chromeos/dbus/printer_service_provider.h +++ b/chrome/browser/chromeos/dbus/printer_service_provider.h @@ -8,7 +8,7 @@ #include #include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/dbus/cros_dbus_service.h" +#include "chromeos/dbus/services/cros_dbus_service.h" #include "dbus/exported_object.h" namespace dbus { diff --git a/chrome/browser/chromeos/dbus/printer_service_provider_unittest.cc b/chrome/browser/chromeos/dbus/printer_service_provider_unittest.cc index ebf09e4..f7f7434 100644 --- a/chrome/browser/chromeos/dbus/printer_service_provider_unittest.cc +++ b/chrome/browser/chromeos/dbus/printer_service_provider_unittest.cc @@ -4,7 +4,7 @@ #include "chrome/browser/chromeos/dbus/printer_service_provider.h" -#include "chrome/browser/chromeos/dbus/service_provider_test_helper.h" +#include "chromeos/dbus/services/service_provider_test_helper.h" #include "dbus/message.h" #include "third_party/cros_system_api/dbus/service_constants.h" diff --git a/chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h b/chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h index 3fea2ef..70d0c1f 100644 --- a/chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h +++ b/chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h @@ -13,7 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" -#include "chrome/browser/chromeos/dbus/cros_dbus_service.h" +#include "chromeos/dbus/services/cros_dbus_service.h" #include "dbus/exported_object.h" namespace dbus { diff --git a/chrome/browser/chromeos/dbus/proxy_resolution_service_provider_unittest.cc b/chrome/browser/chromeos/dbus/proxy_resolution_service_provider_unittest.cc index 08eb756..f01b433 100644 --- a/chrome/browser/chromeos/dbus/proxy_resolution_service_provider_unittest.cc +++ b/chrome/browser/chromeos/dbus/proxy_resolution_service_provider_unittest.cc @@ -15,7 +15,7 @@ #include "chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h" #include "base/bind.h" -#include "chrome/browser/chromeos/dbus/service_provider_test_helper.h" +#include "chromeos/dbus/services/service_provider_test_helper.h" #include "dbus/message.h" #include "dbus/mock_exported_object.h" #include "third_party/cros_system_api/dbus/service_constants.h" diff --git a/chrome/browser/chromeos/dbus/screen_lock_service_provider.h b/chrome/browser/chromeos/dbus/screen_lock_service_provider.h index 83a0658..68a619b 100644 --- a/chrome/browser/chromeos/dbus/screen_lock_service_provider.h +++ b/chrome/browser/chromeos/dbus/screen_lock_service_provider.h @@ -11,7 +11,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/dbus/cros_dbus_service.h" +#include "chromeos/dbus/services/cros_dbus_service.h" #include "dbus/exported_object.h" namespace dbus { diff --git a/chrome/browser/chromeos/dbus/service_provider_test_helper.cc b/chrome/browser/chromeos/dbus/service_provider_test_helper.cc deleted file mode 100644 index f28248c..0000000 --- a/chrome/browser/chromeos/dbus/service_provider_test_helper.cc +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) 2012 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/service_provider_test_helper.h" - -#include "base/bind.h" -#include "dbus/message.h" -#include "dbus/mock_bus.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/cros_system_api/dbus/service_constants.h" - -using ::testing::_; -using ::testing::AllOf; -using ::testing::Invoke; -using ::testing::ResultOf; -using ::testing::Return; -using ::testing::Unused; - -namespace chromeos { - -ServiceProviderTestHelper::ServiceProviderTestHelper() - : response_received_(false) { -} - -ServiceProviderTestHelper::~ServiceProviderTestHelper() { -} - -void ServiceProviderTestHelper::SetUp( - const std::string& exported_method_name, - CrosDBusService::ServiceProviderInterface* service_provider) { - // Create a mock bus. - dbus::Bus::Options options; - options.bus_type = dbus::Bus::SYSTEM; - mock_bus_ = new dbus::MockBus(options); - - // ShutdownAndBlock() will be called in TearDown(). - EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); - - // Create a mock exported object that behaves as - // org.chromium.CrosDBusService. - mock_exported_object_ = - new dbus::MockExportedObject(mock_bus_.get(), - dbus::ObjectPath(kLibCrosServicePath)); - - // |mock_exported_object_|'s ExportMethod() will use - // |MockExportedObject(). - EXPECT_CALL( - *mock_exported_object_.get(), - ExportMethod(kLibCrosServiceInterface, exported_method_name, _, _)) - .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockExportMethod)); - - // Create a mock object proxy, with which we call a method of - // |mock_exported_object_|. - mock_object_proxy_ = - new dbus::MockObjectProxy(mock_bus_.get(), - kLibCrosServiceName, - dbus::ObjectPath(kLibCrosServicePath)); - // |mock_object_proxy_|'s MockCallMethodAndBlock() will use - // MockCallMethodAndBlock() to return responses. - EXPECT_CALL(*mock_object_proxy_.get(), - MockCallMethodAndBlock( - AllOf(ResultOf(std::mem_fun(&dbus::MethodCall::GetInterface), - kLibCrosServiceInterface), - ResultOf(std::mem_fun(&dbus::MethodCall::GetMember), - exported_method_name)), - _)) - .WillOnce( - Invoke(this, &ServiceProviderTestHelper::MockCallMethodAndBlock)); - - service_provider->Start(mock_exported_object_.get()); -} - -void ServiceProviderTestHelper::TearDown() { - mock_bus_->ShutdownAndBlock(); - mock_exported_object_ = NULL; - mock_object_proxy_ = NULL; - mock_bus_ = NULL; -} - -void ServiceProviderTestHelper::SetUpReturnSignal( - const std::string& interface_name, - const std::string& signal_name, - dbus::ObjectProxy::SignalCallback signal_callback, - dbus::ObjectProxy::OnConnectedCallback on_connected_callback) { - // |mock_exported_object_|'s SendSignal() will use - // MockSendSignal(). - EXPECT_CALL(*mock_exported_object_.get(), SendSignal(_)) - .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockSendSignal)); - - // |mock_object_proxy_|'s ConnectToSignal will use - // MockConnectToSignal(). - EXPECT_CALL(*mock_object_proxy_.get(), - ConnectToSignal(interface_name, signal_name, _, _)) - .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockConnectToSignal)); - - mock_object_proxy_->ConnectToSignal(interface_name, signal_name, - signal_callback, on_connected_callback); -} - -scoped_ptr ServiceProviderTestHelper::CallMethod( - dbus::MethodCall* method_call) { - return mock_object_proxy_->CallMethodAndBlock( - method_call, - dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); -} - -void ServiceProviderTestHelper::MockExportMethod( - const std::string& interface_name, - const std::string& method_name, - dbus::ExportedObject::MethodCallCallback method_callback, - dbus::ExportedObject::OnExportedCallback on_exported_callback) { - // Tell the call back that the method is exported successfully. - on_exported_callback.Run(interface_name, method_name, true); - // Capture the callback, so we can run this at a later time. - method_callback_ = method_callback; -} - -dbus::Response* ServiceProviderTestHelper::MockCallMethodAndBlock( - dbus::MethodCall* method_call, - Unused) { - // Set the serial number to non-zero, so - // dbus_message_new_method_return() won't emit a warning. - method_call->SetSerial(1); - // Run the callback captured in MockExportMethod(). In addition to returning - // a response that the caller will ignore, this will send a signal, which - // will be received by |on_signal_callback_|. - method_callback_.Run(method_call, - base::Bind(&ServiceProviderTestHelper::OnResponse, - base::Unretained(this))); - // Check for a response. - if (!response_received_) - message_loop_.Run(); - // Return response. - return response_.release(); -} - -void ServiceProviderTestHelper::MockConnectToSignal( - const std::string& interface_name, - const std::string& signal_name, - dbus::ObjectProxy::SignalCallback signal_callback, - dbus::ObjectProxy::OnConnectedCallback connected_callback) { - // Tell the callback that the object proxy is connected to the signal. - connected_callback.Run(interface_name, signal_name, true); - // Capture the callback, so we can run this at a later time. - on_signal_callback_ = signal_callback; -} - -void ServiceProviderTestHelper::MockSendSignal(dbus::Signal* signal) { - // Run the callback captured in MockConnectToSignal(). This will call - // OnSignalReceived(). - on_signal_callback_.Run(signal); -} - -void ServiceProviderTestHelper::OnResponse( - scoped_ptr response) { - response_ = response.Pass(); - response_received_ = true; - if (message_loop_.is_running()) - message_loop_.Quit(); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/dbus/service_provider_test_helper.h b/chrome/browser/chromeos/dbus/service_provider_test_helper.h deleted file mode 100644 index 04d2da0..0000000 --- a/chrome/browser/chromeos/dbus/service_provider_test_helper.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2012 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_SERVICE_PROVIDER_TEST_HELPER_H_ -#define CHROME_BROWSER_CHROMEOS_DBUS_SERVICE_PROVIDER_TEST_HELPER_H_ - -#include - -#include "base/message_loop/message_loop.h" -#include "chrome/browser/chromeos/dbus/cros_dbus_service.h" -#include "dbus/mock_exported_object.h" -#include "dbus/mock_object_proxy.h" -#include "dbus/object_proxy.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace dbus { - -class MockBus; - -} // namespace dbus - -namespace chromeos { - -// Helps to implement |CrosDBusService::ServiceProviderInterface| unittests. -// Setups mocking of dbus classes. -// Class can test only one method call in time. SetUp() must be called before -// testing new call to the same method or different method. -// -// Sample usage: -// ServiceProviderTestHelper helper; -// helper.Setup(...); -// helper.SetUpReturnSignal(...); // optional. -// helper.CallMethod(...); -// helper.TearDown(); -class ServiceProviderTestHelper { - public: - ServiceProviderTestHelper(); - ~ServiceProviderTestHelper(); - - // Sets up helper. Should be called before |CallMethod()|. - void SetUp(const std::string& exported_method_name, - CrosDBusService::ServiceProviderInterface* service_provider); - - // Setups return signal callback. It's optional and don't need to be called - // if tested method doesn't use signal to return results. - void SetUpReturnSignal( - const std::string& interface_name, - const std::string& signal_name, - dbus::ObjectProxy::SignalCallback signal_callback, - dbus::ObjectProxy::OnConnectedCallback on_connected_callback); - - // Calls tested dbus method. - scoped_ptr CallMethod(dbus::MethodCall* method_call); - - // Cleanups helper. Should be called after |CallMethod()|. - void TearDown(); - - private: - // Behaves as |mock_exported_object_|'s ExportMethod(). - void MockExportMethod( - const std::string& interface_name, - const std::string& method_name, - dbus::ExportedObject::MethodCallCallback method_callback, - dbus::ExportedObject::OnExportedCallback on_exported_callback); - - // Calls exported method and waits for a response for |mock_object_proxy_|. - dbus::Response* MockCallMethodAndBlock( - dbus::MethodCall* method_call, - ::testing::Unused); - - // Behaves as |mock_object_proxy_|'s ConnectToSignal(). - void MockConnectToSignal( - const std::string& interface_name, - const std::string& signal_name, - dbus::ObjectProxy::SignalCallback signal_callback, - dbus::ObjectProxy::OnConnectedCallback connected_callback); - - // Behaves as |mock_exported_object_|'s SendSignal(). - void MockSendSignal(dbus::Signal* signal); - - // Receives a response and makes it available to MockCallMethodAndBlock(). - void OnResponse(scoped_ptr response); - - scoped_refptr mock_bus_; - scoped_refptr mock_exported_object_; - scoped_refptr mock_object_proxy_; - dbus::ExportedObject::MethodCallCallback method_callback_; - dbus::ObjectProxy::SignalCallback on_signal_callback_; - base::MessageLoop message_loop_; - bool response_received_; - scoped_ptr response_; -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_DBUS_SERVICE_PROVIDER_TEST_HELPER_H_ diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index b2749ef..c1484cc 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -79,12 +79,8 @@ 'browser/chromeos/display/overscan_calibrator.h', 'browser/chromeos/dbus/console_service_provider.cc', 'browser/chromeos/dbus/console_service_provider.h', - 'browser/chromeos/dbus/cros_dbus_service.cc', - 'browser/chromeos/dbus/cros_dbus_service.h', 'browser/chromeos/dbus/display_power_service_provider.cc', 'browser/chromeos/dbus/display_power_service_provider.h', - 'browser/chromeos/dbus/liveness_service_provider.cc', - 'browser/chromeos/dbus/liveness_service_provider.h', 'browser/chromeos/dbus/printer_service_provider.cc', 'browser/chromeos/dbus/printer_service_provider.h', 'browser/chromeos/dbus/proxy_resolution_service_provider.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index e0fa030..8408ab1 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -79,11 +79,8 @@ 'browser/chromeos/attestation/fake_certificate.h', 'browser/chromeos/attestation/platform_verification_flow_unittest.cc', 'browser/chromeos/customization_document_unittest.cc', - 'browser/chromeos/dbus/cros_dbus_service_unittest.cc', 'browser/chromeos/dbus/printer_service_provider_unittest.cc', 'browser/chromeos/dbus/proxy_resolution_service_provider_unittest.cc', - 'browser/chromeos/dbus/service_provider_test_helper.cc', - 'browser/chromeos/dbus/service_provider_test_helper.h', 'browser/chromeos/display/display_preferences_unittest.cc', 'browser/chromeos/drive/change_list_loader_unittest.cc', 'browser/chromeos/drive/change_list_processor_unittest.cc', diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index 6d677b2..33c47b1 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn @@ -87,6 +87,8 @@ static_library("test_support") { "dbus/mock_shill_profile_client.h", "dbus/mock_shill_service_client.cc", "dbus/mock_shill_service_client.h", + "dbus/services/service_provider_test_helper.cc", + "dbus/services/service_provider_test_helper.h", "disks/mock_disk_mount_manager.cc", "disks/mock_disk_mount_manager.h", "ime/mock_component_extension_ime_manager_delegate.cc", diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index ed5ebe6..6e3cb62 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp @@ -212,6 +212,10 @@ 'dbus/power_policy_controller.h', 'dbus/privet_daemon_client.cc', 'dbus/privet_daemon_client.h', + 'dbus/services/cros_dbus_service.cc', + 'dbus/services/cros_dbus_service.h', + 'dbus/services/liveness_service_provider.cc', + 'dbus/services/liveness_service_provider.h', 'dbus/session_manager_client.cc', 'dbus/session_manager_client.h', 'dbus/shill_client_helper.cc', @@ -428,6 +432,7 @@ 'dbus/modem_messaging_client_unittest.cc', 'dbus/nfc_client_unittest.cc', 'dbus/power_policy_controller_unittest.cc', + 'dbus/services/cros_dbus_service_unittest.cc', 'dbus/shill_client_unittest_base.cc', 'dbus/shill_client_unittest_base.h', 'dbus/shill_device_client_unittest.cc', @@ -559,6 +564,8 @@ 'dbus/mock_shill_profile_client.h', 'dbus/mock_shill_service_client.cc', 'dbus/mock_shill_service_client.h', + 'dbus/services/service_provider_test_helper.cc', + 'dbus/services/service_provider_test_helper.h', 'disks/mock_disk_mount_manager.cc', 'disks/mock_disk_mount_manager.h', 'ime/mock_component_extension_ime_manager_delegate.cc', diff --git a/chromeos/dbus/services/cros_dbus_service.cc b/chromeos/dbus/services/cros_dbus_service.cc new file mode 100644 index 0000000..3e04416 --- /dev/null +++ b/chromeos/dbus/services/cros_dbus_service.cc @@ -0,0 +1,150 @@ +// Copyright (c) 2012 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/cros_dbus_service.h" + +#include "base/bind.h" +#include "base/stl_util.h" +#include "base/sys_info.h" +#include "base/threading/platform_thread.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "dbus/bus.h" +#include "dbus/exported_object.h" +#include "dbus/object_path.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace chromeos { + +namespace { + +CrosDBusService* g_cros_dbus_service = NULL; + +} // namespace + +// The CrosDBusService implementation used in production, and unit tests. +class CrosDBusServiceImpl : public CrosDBusService { + public: + CrosDBusServiceImpl(dbus::Bus* bus, + ScopedVector service_providers) + : service_started_(false), + origin_thread_id_(base::PlatformThread::CurrentId()), + bus_(bus), + service_providers_(service_providers.Pass()) { + } + + ~CrosDBusServiceImpl() override { + } + + // Starts the D-Bus service. + void Start() { + // Make sure we're running on the origin thread (i.e. the UI thread in + // production). + DCHECK(OnOriginThread()); + + // Return if the service has been already started. + if (service_started_) + return; + + // There are some situations, described in http://crbug.com/234382#c27, + // where processes on Linux can wind up stuck in an uninterruptible state + // for tens of seconds. If this happens when Chrome is trying to exit, + // this unkillable process can wind up clinging to ownership of + // kLibCrosServiceName while the system is trying to restart the browser. + // This leads to a fatal situation if we don't allow the new browser + // instance to replace the old as the owner of kLibCrosServiceName as seen + // in http://crbug.com/234382. Hence, REQUIRE_PRIMARY_ALLOW_REPLACEMENT. + bus_->RequestOwnership(kLibCrosServiceName, + dbus::Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT, + base::Bind(&CrosDBusServiceImpl::OnOwnership, + base::Unretained(this))); + + exported_object_ = bus_->GetExportedObject( + dbus::ObjectPath(kLibCrosServicePath)); + + for (size_t i = 0; i < service_providers_.size(); ++i) + service_providers_[i]->Start(exported_object_); + + service_started_ = true; + + VLOG(1) << "CrosDBusServiceImpl started."; + } + + private: + // Returns true if the current thread is on the origin thread. + bool OnOriginThread() { + return base::PlatformThread::CurrentId() == origin_thread_id_; + } + + // Called when an ownership request is completed. + void OnOwnership(const std::string& service_name, + bool success) { + LOG_IF(FATAL, !success) << "Failed to own: " << service_name; + } + + bool service_started_; + base::PlatformThreadId origin_thread_id_; + dbus::Bus* bus_; + scoped_refptr exported_object_; + + // Service providers that form CrosDBusService. + ScopedVector service_providers_; +}; + +// The stub CrosDBusService implementation used on Linux desktop, +// which does nothing as of now. +class CrosDBusServiceStubImpl : public CrosDBusService { + public: + CrosDBusServiceStubImpl() { + } + + virtual ~CrosDBusServiceStubImpl() { + } +}; + +// static +void CrosDBusService::Initialize( + ScopedVector service_providers) { + if (g_cros_dbus_service) { + LOG(WARNING) << "CrosDBusService was already initialized"; + return; + } + dbus::Bus* bus = DBusThreadManager::Get()->GetSystemBus(); + if (base::SysInfo::IsRunningOnChromeOS() && bus) { + auto* service = new CrosDBusServiceImpl(bus, service_providers.Pass()); + g_cros_dbus_service = service; + service->Start(); + } else { + g_cros_dbus_service = new CrosDBusServiceStubImpl; + } + VLOG(1) << "CrosDBusService initialized"; +} + +// static +void CrosDBusService::InitializeForTesting( + dbus::Bus* bus, + ScopedVector service_providers) { + if (g_cros_dbus_service) { + LOG(WARNING) << "CrosDBusService was already initialized"; + return; + } + auto* service = new CrosDBusServiceImpl(bus, service_providers.Pass()); + service->Start(); + g_cros_dbus_service = service; + VLOG(1) << "CrosDBusService initialized"; +} + +// static +void CrosDBusService::Shutdown() { + delete g_cros_dbus_service; + g_cros_dbus_service = NULL; + VLOG(1) << "CrosDBusService Shutdown completed"; +} + +CrosDBusService::~CrosDBusService() { +} + +CrosDBusService::ServiceProviderInterface::~ServiceProviderInterface() { +} + +} // namespace chromeos diff --git a/chromeos/dbus/services/cros_dbus_service.h b/chromeos/dbus/services/cros_dbus_service.h new file mode 100644 index 0000000..50d2297 --- /dev/null +++ b/chromeos/dbus/services/cros_dbus_service.h @@ -0,0 +1,68 @@ +// Copyright (c) 2012 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_CROS_DBUS_SERVICE_H_ +#define CHROMEOS_DBUS_SERVICES_CROS_DBUS_SERVICE_H_ + +#include + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_vector.h" +#include "base/threading/platform_thread.h" +#include "chromeos/chromeos_export.h" + +namespace dbus { +class Bus; +class ExportedObject; +} + +namespace chromeos { + +// CrosDBusService is used to run a D-Bus service inside Chrome for Chrome +// OS. The service will be registered as follows: +// +// Service name: org.chromium.LibCrosService (kLibCrosServiceName) +// Object path: chromium/LibCrosService (kLibCrosServicePath) +// +// For historical reasons, the rather irrelevant name "LibCrosService" is +// used in the D-Bus constants such as the service name. +// +// CrosDBusService exports D-Bus methods through service provider classes +// that implement CrosDBusService::ServiceProviderInterface. + +class CHROMEOS_EXPORT CrosDBusService { + public: + // CrosDBusService consists of service providers that implement this + // interface. + class ServiceProviderInterface { + public: + // Starts the service provider. |exported_object| is used to export + // D-Bus methods. + virtual void Start( + scoped_refptr exported_object) = 0; + + virtual ~ServiceProviderInterface(); + }; + + // Initializes the global instance. + static void Initialize( + ScopedVector service_providers); + // Destroys the global instance. + static void Shutdown(); + + protected: + virtual ~CrosDBusService(); + + private: + friend class CrosDBusServiceTest; + + // Initializes the global instance for testing. + static void InitializeForTesting( + dbus::Bus* bus, + ScopedVector service_providers); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DBUS_SERVICES_CROS_DBUS_SERVICE_H_ diff --git a/chromeos/dbus/services/cros_dbus_service_unittest.cc b/chromeos/dbus/services/cros_dbus_service_unittest.cc new file mode 100644 index 0000000..fa4a0df --- /dev/null +++ b/chromeos/dbus/services/cros_dbus_service_unittest.cc @@ -0,0 +1,92 @@ +// Copyright (c) 2012 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/cros_dbus_service.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "dbus/message.h" +#include "dbus/mock_bus.h" +#include "dbus/mock_exported_object.h" +#include "dbus/mock_object_proxy.h" +#include "dbus/object_path.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +using ::testing::Eq; +using ::testing::Invoke; +using ::testing::Return; + +namespace chromeos { + +class MockProxyResolutionService + : public CrosDBusService::ServiceProviderInterface { + public: + MOCK_METHOD1(Start, void(scoped_refptr + exported_object)); +}; + +class CrosDBusServiceTest : public testing::Test { + public: + CrosDBusServiceTest() { + } + + // Creates an instance of CrosDBusService with mocks injected. + virtual void SetUp() { + // Create a mock bus. + dbus::Bus::Options options; + options.bus_type = dbus::Bus::SYSTEM; + mock_bus_ = new dbus::MockBus(options); + + // ShutdownAndBlock() will be called in TearDown(). + EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); + + // Create a mock exported object that behaves as + // org.chromium.CrosDBusService. + mock_exported_object_ = + new dbus::MockExportedObject(mock_bus_.get(), + dbus::ObjectPath(kLibCrosServicePath)); + + // |mock_bus_|'s GetExportedObject() will return mock_exported_object_| + // for the given service name and the object path. + EXPECT_CALL(*mock_bus_.get(), + GetExportedObject(dbus::ObjectPath(kLibCrosServicePath))) + .WillOnce(Return(mock_exported_object_.get())); + + // Create a mock proxy resolution service. + MockProxyResolutionService* mock_proxy_resolution_service_provider = + new MockProxyResolutionService; + + // Start() will be called with |mock_exported_object_|. + EXPECT_CALL(*mock_proxy_resolution_service_provider, + Start(Eq(mock_exported_object_))).WillOnce(Return()); + // Initialize the cros service with the mocks injected. + ScopedVector service_providers; + service_providers.push_back(mock_proxy_resolution_service_provider); + CrosDBusService::InitializeForTesting( + mock_bus_.get(), service_providers.Pass()); + } + + virtual void TearDown() { + // Shutdown the cros service. + CrosDBusService::Shutdown(); + + // Shutdown the bus. + mock_bus_->ShutdownAndBlock(); + } + + protected: + scoped_refptr mock_bus_; + scoped_refptr mock_exported_object_; +}; + +TEST_F(CrosDBusServiceTest, Start) { + // Simply start the service and see if mock expectations are met: + // - The service object is exported by GetExportedObject() + // - The proxy resolution service is started. +} + +} // namespace chromeos diff --git a/chromeos/dbus/services/liveness_service_provider.cc b/chromeos/dbus/services/liveness_service_provider.cc new file mode 100644 index 0000000..1648793 --- /dev/null +++ b/chromeos/dbus/services/liveness_service_provider.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2012 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/liveness_service_provider.h" + +#include "base/bind.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace chromeos { + +LivenessServiceProvider::LivenessServiceProvider() : weak_ptr_factory_(this) {} + +LivenessServiceProvider::~LivenessServiceProvider() {} + +void LivenessServiceProvider::Start( + scoped_refptr exported_object) { + exported_object->ExportMethod( + kLibCrosServiceInterface, + kCheckLiveness, + base::Bind(&LivenessServiceProvider::CheckLiveness, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&LivenessServiceProvider::OnExported, + weak_ptr_factory_.GetWeakPtr())); +} + +void LivenessServiceProvider::OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + if (!success) { + LOG(ERROR) << "Failed to export " << interface_name << "." + << method_name; + } +} + +void LivenessServiceProvider::CheckLiveness( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + response_sender.Run(dbus::Response::FromMethodCall(method_call)); +} + +} // namespace chromeos diff --git a/chromeos/dbus/services/liveness_service_provider.h b/chromeos/dbus/services/liveness_service_provider.h new file mode 100644 index 0000000..559d071 --- /dev/null +++ b/chromeos/dbus/services/liveness_service_provider.h @@ -0,0 +1,67 @@ +// Copyright (c) 2012 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_LIVENESS_SERVICE_PROVIDER_H_ +#define CHROMEOS_DBUS_SERVICES_LIVENESS_SERVICE_PROVIDER_H_ + +#include + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.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; +class Response; +} + +namespace chromeos { + +// This class exports a "CheckLiveness" D-Bus method that the session manager +// calls periodically to confirm that Chrome's UI thread is responsive to D-Bus +// messages. It can be tested with the following command: +// +// % dbus-send --system --type=method_call --print-reply +// --dest=org.chromium.LibCrosService +// /org/chromium/LibCrosService +// org.chromium.LibCrosServiceInterface.CheckLiveness +// +// -> method return sender=:1.9 -> dest=:1.27 reply_serial=2 +// +// (An empty response should be returned.) +class CHROMEOS_EXPORT LivenessServiceProvider + : public CrosDBusService::ServiceProviderInterface { + public: + LivenessServiceProvider(); + virtual ~LivenessServiceProvider(); + + // CrosDBusService::ServiceProviderInterface overrides: + virtual void Start( + scoped_refptr exported_object) override; + + private: + // Called from ExportedObject when CheckLiveness() 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 CheckLiveness(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender); + + // Keep this last so that all weak pointers will be invalidated at the + // beginning of destruction. + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(LivenessServiceProvider); +}; + +} // namespace chromeos + +#endif // CHROMEOS_DBUS_SERVICES_LIVENESS_SERVICE_PROVIDER_H_ diff --git a/chromeos/dbus/services/service_provider_test_helper.cc b/chromeos/dbus/services/service_provider_test_helper.cc new file mode 100644 index 0000000..b3030ac --- /dev/null +++ b/chromeos/dbus/services/service_provider_test_helper.cc @@ -0,0 +1,164 @@ +// Copyright (c) 2012 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/service_provider_test_helper.h" + +#include "base/bind.h" +#include "dbus/message.h" +#include "dbus/mock_bus.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +using ::testing::_; +using ::testing::AllOf; +using ::testing::Invoke; +using ::testing::ResultOf; +using ::testing::Return; +using ::testing::Unused; + +namespace chromeos { + +ServiceProviderTestHelper::ServiceProviderTestHelper() + : response_received_(false) { +} + +ServiceProviderTestHelper::~ServiceProviderTestHelper() { +} + +void ServiceProviderTestHelper::SetUp( + const std::string& exported_method_name, + CrosDBusService::ServiceProviderInterface* service_provider) { + // Create a mock bus. + dbus::Bus::Options options; + options.bus_type = dbus::Bus::SYSTEM; + mock_bus_ = new dbus::MockBus(options); + + // ShutdownAndBlock() will be called in TearDown(). + EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); + + // Create a mock exported object that behaves as + // org.chromium.CrosDBusService. + mock_exported_object_ = + new dbus::MockExportedObject(mock_bus_.get(), + dbus::ObjectPath(kLibCrosServicePath)); + + // |mock_exported_object_|'s ExportMethod() will use + // |MockExportedObject(). + EXPECT_CALL( + *mock_exported_object_.get(), + ExportMethod(kLibCrosServiceInterface, exported_method_name, _, _)) + .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockExportMethod)); + + // Create a mock object proxy, with which we call a method of + // |mock_exported_object_|. + mock_object_proxy_ = + new dbus::MockObjectProxy(mock_bus_.get(), + kLibCrosServiceName, + dbus::ObjectPath(kLibCrosServicePath)); + // |mock_object_proxy_|'s MockCallMethodAndBlock() will use + // MockCallMethodAndBlock() to return responses. + EXPECT_CALL(*mock_object_proxy_.get(), + MockCallMethodAndBlock( + AllOf(ResultOf(std::mem_fun(&dbus::MethodCall::GetInterface), + kLibCrosServiceInterface), + ResultOf(std::mem_fun(&dbus::MethodCall::GetMember), + exported_method_name)), + _)) + .WillOnce( + Invoke(this, &ServiceProviderTestHelper::MockCallMethodAndBlock)); + + service_provider->Start(mock_exported_object_.get()); +} + +void ServiceProviderTestHelper::TearDown() { + mock_bus_->ShutdownAndBlock(); + mock_exported_object_ = NULL; + mock_object_proxy_ = NULL; + mock_bus_ = NULL; +} + +void ServiceProviderTestHelper::SetUpReturnSignal( + const std::string& interface_name, + const std::string& signal_name, + dbus::ObjectProxy::SignalCallback signal_callback, + dbus::ObjectProxy::OnConnectedCallback on_connected_callback) { + // |mock_exported_object_|'s SendSignal() will use + // MockSendSignal(). + EXPECT_CALL(*mock_exported_object_.get(), SendSignal(_)) + .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockSendSignal)); + + // |mock_object_proxy_|'s ConnectToSignal will use + // MockConnectToSignal(). + EXPECT_CALL(*mock_object_proxy_.get(), + ConnectToSignal(interface_name, signal_name, _, _)) + .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockConnectToSignal)); + + mock_object_proxy_->ConnectToSignal(interface_name, signal_name, + signal_callback, on_connected_callback); +} + +scoped_ptr ServiceProviderTestHelper::CallMethod( + dbus::MethodCall* method_call) { + return mock_object_proxy_->CallMethodAndBlock( + method_call, + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); +} + +void ServiceProviderTestHelper::MockExportMethod( + const std::string& interface_name, + const std::string& method_name, + dbus::ExportedObject::MethodCallCallback method_callback, + dbus::ExportedObject::OnExportedCallback on_exported_callback) { + // Tell the call back that the method is exported successfully. + on_exported_callback.Run(interface_name, method_name, true); + // Capture the callback, so we can run this at a later time. + method_callback_ = method_callback; +} + +dbus::Response* ServiceProviderTestHelper::MockCallMethodAndBlock( + dbus::MethodCall* method_call, + Unused) { + // Set the serial number to non-zero, so + // dbus_message_new_method_return() won't emit a warning. + method_call->SetSerial(1); + // Run the callback captured in MockExportMethod(). In addition to returning + // a response that the caller will ignore, this will send a signal, which + // will be received by |on_signal_callback_|. + method_callback_.Run(method_call, + base::Bind(&ServiceProviderTestHelper::OnResponse, + base::Unretained(this))); + // Check for a response. + if (!response_received_) + message_loop_.Run(); + // Return response. + return response_.release(); +} + +void ServiceProviderTestHelper::MockConnectToSignal( + const std::string& interface_name, + const std::string& signal_name, + dbus::ObjectProxy::SignalCallback signal_callback, + dbus::ObjectProxy::OnConnectedCallback connected_callback) { + // Tell the callback that the object proxy is connected to the signal. + connected_callback.Run(interface_name, signal_name, true); + // Capture the callback, so we can run this at a later time. + on_signal_callback_ = signal_callback; +} + +void ServiceProviderTestHelper::MockSendSignal(dbus::Signal* signal) { + // Run the callback captured in MockConnectToSignal(). This will call + // OnSignalReceived(). + on_signal_callback_.Run(signal); +} + +void ServiceProviderTestHelper::OnResponse( + scoped_ptr response) { + response_ = response.Pass(); + response_received_ = true; + if (message_loop_.is_running()) + message_loop_.Quit(); +} + +} // namespace chromeos diff --git a/chromeos/dbus/services/service_provider_test_helper.h b/chromeos/dbus/services/service_provider_test_helper.h new file mode 100644 index 0000000..196f6a6 --- /dev/null +++ b/chromeos/dbus/services/service_provider_test_helper.h @@ -0,0 +1,98 @@ +// Copyright (c) 2012 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_SERVICE_PROVIDER_TEST_HELPER_H_ +#define CHROMEOS_DBUS_SERVICES_SERVICE_PROVIDER_TEST_HELPER_H_ + +#include + +#include "base/message_loop/message_loop.h" +#include "chromeos/dbus/services/cros_dbus_service.h" +#include "dbus/mock_exported_object.h" +#include "dbus/mock_object_proxy.h" +#include "dbus/object_proxy.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace dbus { + +class MockBus; + +} // namespace dbus + +namespace chromeos { + +// Helps to implement |CrosDBusService::ServiceProviderInterface| unittests. +// Setups mocking of dbus classes. +// Class can test only one method call in time. SetUp() must be called before +// testing new call to the same method or different method. +// +// Sample usage: +// ServiceProviderTestHelper helper; +// helper.Setup(...); +// helper.SetUpReturnSignal(...); // optional. +// helper.CallMethod(...); +// helper.TearDown(); +class ServiceProviderTestHelper { + public: + ServiceProviderTestHelper(); + ~ServiceProviderTestHelper(); + + // Sets up helper. Should be called before |CallMethod()|. + void SetUp(const std::string& exported_method_name, + CrosDBusService::ServiceProviderInterface* service_provider); + + // Setups return signal callback. It's optional and don't need to be called + // if tested method doesn't use signal to return results. + void SetUpReturnSignal( + const std::string& interface_name, + const std::string& signal_name, + dbus::ObjectProxy::SignalCallback signal_callback, + dbus::ObjectProxy::OnConnectedCallback on_connected_callback); + + // Calls tested dbus method. + scoped_ptr CallMethod(dbus::MethodCall* method_call); + + // Cleanups helper. Should be called after |CallMethod()|. + void TearDown(); + + private: + // Behaves as |mock_exported_object_|'s ExportMethod(). + void MockExportMethod( + const std::string& interface_name, + const std::string& method_name, + dbus::ExportedObject::MethodCallCallback method_callback, + dbus::ExportedObject::OnExportedCallback on_exported_callback); + + // Calls exported method and waits for a response for |mock_object_proxy_|. + dbus::Response* MockCallMethodAndBlock( + dbus::MethodCall* method_call, + ::testing::Unused); + + // Behaves as |mock_object_proxy_|'s ConnectToSignal(). + void MockConnectToSignal( + const std::string& interface_name, + const std::string& signal_name, + dbus::ObjectProxy::SignalCallback signal_callback, + dbus::ObjectProxy::OnConnectedCallback connected_callback); + + // Behaves as |mock_exported_object_|'s SendSignal(). + void MockSendSignal(dbus::Signal* signal); + + // Receives a response and makes it available to MockCallMethodAndBlock(). + void OnResponse(scoped_ptr response); + + scoped_refptr mock_bus_; + scoped_refptr mock_exported_object_; + scoped_refptr mock_object_proxy_; + dbus::ExportedObject::MethodCallCallback method_callback_; + dbus::ObjectProxy::SignalCallback on_signal_callback_; + base::MessageLoop message_loop_; + bool response_received_; + scoped_ptr response_; +}; + +} // namespace chromeos + +#endif // CHROMEOS_DBUS_SERVICES_SERVICE_PROVIDER_TEST_HELPER_H_ -- cgit v1.1