[ServiceWorker] Implement WebServiceWorkerContextClient::openWindow().
[chromium-blink-merge.git] / chromeos / dbus / services / cros_dbus_service.cc
blobbfcd405bf1e52e150f763a9399d38d4d2b3e4868
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/dbus/services/cros_dbus_service.h"
7 #include "base/bind.h"
8 #include "base/stl_util.h"
9 #include "base/sys_info.h"
10 #include "base/threading/platform_thread.h"
11 #include "chromeos/dbus/dbus_thread_manager.h"
12 #include "dbus/bus.h"
13 #include "dbus/exported_object.h"
14 #include "dbus/object_path.h"
15 #include "third_party/cros_system_api/dbus/service_constants.h"
17 namespace chromeos {
19 namespace {
21 CrosDBusService* g_cros_dbus_service = NULL;
23 } // namespace
25 // The CrosDBusService implementation used in production, and unit tests.
26 class CrosDBusServiceImpl : public CrosDBusService {
27 public:
28 CrosDBusServiceImpl(dbus::Bus* bus,
29 ScopedVector<ServiceProviderInterface> service_providers)
30 : service_started_(false),
31 origin_thread_id_(base::PlatformThread::CurrentId()),
32 bus_(bus),
33 service_providers_(service_providers.Pass()) {
36 ~CrosDBusServiceImpl() override {
39 // Starts the D-Bus service.
40 void Start() {
41 // Make sure we're running on the origin thread (i.e. the UI thread in
42 // production).
43 DCHECK(OnOriginThread());
45 // Return if the service has been already started.
46 if (service_started_)
47 return;
49 // There are some situations, described in http://crbug.com/234382#c27,
50 // where processes on Linux can wind up stuck in an uninterruptible state
51 // for tens of seconds. If this happens when Chrome is trying to exit,
52 // this unkillable process can wind up clinging to ownership of
53 // kLibCrosServiceName while the system is trying to restart the browser.
54 // This leads to a fatal situation if we don't allow the new browser
55 // instance to replace the old as the owner of kLibCrosServiceName as seen
56 // in http://crbug.com/234382. Hence, REQUIRE_PRIMARY_ALLOW_REPLACEMENT.
57 bus_->RequestOwnership(kLibCrosServiceName,
58 dbus::Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT,
59 base::Bind(&CrosDBusServiceImpl::OnOwnership,
60 base::Unretained(this)));
62 exported_object_ = bus_->GetExportedObject(
63 dbus::ObjectPath(kLibCrosServicePath));
65 for (size_t i = 0; i < service_providers_.size(); ++i)
66 service_providers_[i]->Start(exported_object_);
68 service_started_ = true;
70 VLOG(1) << "CrosDBusServiceImpl started.";
73 private:
74 // Returns true if the current thread is on the origin thread.
75 bool OnOriginThread() {
76 return base::PlatformThread::CurrentId() == origin_thread_id_;
79 // Called when an ownership request is completed.
80 void OnOwnership(const std::string& service_name,
81 bool success) {
82 LOG_IF(FATAL, !success) << "Failed to own: " << service_name;
85 bool service_started_;
86 base::PlatformThreadId origin_thread_id_;
87 dbus::Bus* bus_;
88 scoped_refptr<dbus::ExportedObject> exported_object_;
90 // Service providers that form CrosDBusService.
91 ScopedVector<ServiceProviderInterface> service_providers_;
94 // The stub CrosDBusService implementation used on Linux desktop,
95 // which does nothing as of now.
96 class CrosDBusServiceStubImpl : public CrosDBusService {
97 public:
98 CrosDBusServiceStubImpl() {
101 ~CrosDBusServiceStubImpl() override {}
104 // static
105 void CrosDBusService::Initialize(
106 ScopedVector<ServiceProviderInterface> service_providers) {
107 if (g_cros_dbus_service) {
108 LOG(WARNING) << "CrosDBusService was already initialized";
109 return;
111 dbus::Bus* bus = DBusThreadManager::Get()->GetSystemBus();
112 if (base::SysInfo::IsRunningOnChromeOS() && bus) {
113 auto* service = new CrosDBusServiceImpl(bus, service_providers.Pass());
114 g_cros_dbus_service = service;
115 service->Start();
116 } else {
117 g_cros_dbus_service = new CrosDBusServiceStubImpl;
119 VLOG(1) << "CrosDBusService initialized";
122 // static
123 void CrosDBusService::InitializeForTesting(
124 dbus::Bus* bus,
125 ScopedVector<ServiceProviderInterface> service_providers) {
126 if (g_cros_dbus_service) {
127 LOG(WARNING) << "CrosDBusService was already initialized";
128 return;
130 auto* service = new CrosDBusServiceImpl(bus, service_providers.Pass());
131 service->Start();
132 g_cros_dbus_service = service;
133 VLOG(1) << "CrosDBusService initialized";
136 // static
137 void CrosDBusService::Shutdown() {
138 delete g_cros_dbus_service;
139 g_cros_dbus_service = NULL;
140 VLOG(1) << "CrosDBusService Shutdown completed";
143 CrosDBusService::~CrosDBusService() {
146 CrosDBusService::ServiceProviderInterface::~ServiceProviderInterface() {
149 } // namespace chromeos