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/dbus_thread_manager.h"
9 #include "base/command_line.h"
10 #include "base/observer_list.h"
11 #include "base/sys_info.h"
12 #include "base/threading/thread.h"
13 #include "chromeos/chromeos_switches.h"
14 #include "chromeos/dbus/bluetooth_adapter_client.h"
15 #include "chromeos/dbus/bluetooth_agent_manager_client.h"
16 #include "chromeos/dbus/bluetooth_device_client.h"
17 #include "chromeos/dbus/bluetooth_input_client.h"
18 #include "chromeos/dbus/bluetooth_profile_manager_client.h"
19 #include "chromeos/dbus/cras_audio_client.h"
20 #include "chromeos/dbus/cros_disks_client.h"
21 #include "chromeos/dbus/cryptohome_client.h"
22 #include "chromeos/dbus/dbus_client.h"
23 #include "chromeos/dbus/dbus_thread_manager_observer.h"
24 #include "chromeos/dbus/debug_daemon_client.h"
25 #include "chromeos/dbus/fake_dbus_thread_manager.h"
26 #include "chromeos/dbus/gsm_sms_client.h"
27 #include "chromeos/dbus/image_burner_client.h"
28 #include "chromeos/dbus/introspectable_client.h"
29 #include "chromeos/dbus/modem_messaging_client.h"
30 #include "chromeos/dbus/nfc_adapter_client.h"
31 #include "chromeos/dbus/nfc_device_client.h"
32 #include "chromeos/dbus/nfc_manager_client.h"
33 #include "chromeos/dbus/nfc_record_client.h"
34 #include "chromeos/dbus/nfc_tag_client.h"
35 #include "chromeos/dbus/permission_broker_client.h"
36 #include "chromeos/dbus/power_manager_client.h"
37 #include "chromeos/dbus/power_policy_controller.h"
38 #include "chromeos/dbus/session_manager_client.h"
39 #include "chromeos/dbus/shill_device_client.h"
40 #include "chromeos/dbus/shill_ipconfig_client.h"
41 #include "chromeos/dbus/shill_manager_client.h"
42 #include "chromeos/dbus/shill_profile_client.h"
43 #include "chromeos/dbus/shill_service_client.h"
44 #include "chromeos/dbus/shill_stub_helper.h"
45 #include "chromeos/dbus/sms_client.h"
46 #include "chromeos/dbus/system_clock_client.h"
47 #include "chromeos/dbus/update_engine_client.h"
49 #include "dbus/dbus_statistics.h"
53 static DBusThreadManager
* g_dbus_thread_manager
= NULL
;
54 static DBusThreadManager
* g_dbus_thread_manager_for_testing
= NULL
;
56 // The DBusThreadManager implementation used in production.
57 class DBusThreadManagerImpl
: public DBusThreadManager
{
59 explicit DBusThreadManagerImpl() {
60 // Create the D-Bus thread.
61 base::Thread::Options thread_options
;
62 thread_options
.message_loop_type
= base::MessageLoop::TYPE_IO
;
63 dbus_thread_
.reset(new base::Thread("D-Bus thread"));
64 dbus_thread_
->StartWithOptions(thread_options
);
66 // Create the connection to the system bus.
67 dbus::Bus::Options system_bus_options
;
68 system_bus_options
.bus_type
= dbus::Bus::SYSTEM
;
69 system_bus_options
.connection_type
= dbus::Bus::PRIVATE
;
70 system_bus_options
.dbus_task_runner
= dbus_thread_
->message_loop_proxy();
71 system_bus_
= new dbus::Bus(system_bus_options
);
73 CreateDefaultClients();
76 virtual ~DBusThreadManagerImpl() {
77 FOR_EACH_OBSERVER(DBusThreadManagerObserver
, observers_
,
78 OnDBusThreadManagerDestroying(this));
80 // Shut down the bus. During the browser shutdown, it's ok to shut down
81 // the bus synchronously.
82 system_bus_
->ShutdownOnDBusThreadAndBlock();
84 // Stop the D-Bus thread.
88 // DBusThreadManager overrides:
89 virtual void AddObserver(DBusThreadManagerObserver
* observer
) OVERRIDE
{
91 observers_
.AddObserver(observer
);
94 virtual void RemoveObserver(DBusThreadManagerObserver
* observer
) OVERRIDE
{
96 observers_
.RemoveObserver(observer
);
99 virtual dbus::Bus
* GetSystemBus() OVERRIDE
{
100 return system_bus_
.get();
103 virtual BluetoothAdapterClient
* GetBluetoothAdapterClient() OVERRIDE
{
104 return bluetooth_adapter_client_
.get();
107 virtual BluetoothAgentManagerClient
* GetBluetoothAgentManagerClient()
109 return bluetooth_agent_manager_client_
.get();
112 virtual BluetoothDeviceClient
* GetBluetoothDeviceClient() OVERRIDE
{
113 return bluetooth_device_client_
.get();
116 virtual BluetoothInputClient
* GetBluetoothInputClient() OVERRIDE
{
117 return bluetooth_input_client_
.get();
120 virtual BluetoothProfileManagerClient
* GetBluetoothProfileManagerClient()
122 return bluetooth_profile_manager_client_
.get();
125 virtual CrasAudioClient
* GetCrasAudioClient() OVERRIDE
{
126 return cras_audio_client_
.get();
129 virtual CrosDisksClient
* GetCrosDisksClient() OVERRIDE
{
130 return cros_disks_client_
.get();
133 virtual CryptohomeClient
* GetCryptohomeClient() OVERRIDE
{
134 return cryptohome_client_
.get();
137 virtual DebugDaemonClient
* GetDebugDaemonClient() OVERRIDE
{
138 return debug_daemon_client_
.get();
141 virtual ShillDeviceClient
* GetShillDeviceClient() OVERRIDE
{
142 return shill_device_client_
.get();
145 virtual ShillIPConfigClient
* GetShillIPConfigClient() OVERRIDE
{
146 return shill_ipconfig_client_
.get();
149 virtual ShillManagerClient
* GetShillManagerClient() OVERRIDE
{
150 return shill_manager_client_
.get();
153 virtual ShillServiceClient
* GetShillServiceClient() OVERRIDE
{
154 return shill_service_client_
.get();
157 virtual ShillProfileClient
* GetShillProfileClient() OVERRIDE
{
158 return shill_profile_client_
.get();
161 virtual GsmSMSClient
* GetGsmSMSClient() OVERRIDE
{
162 return gsm_sms_client_
.get();
165 virtual ImageBurnerClient
* GetImageBurnerClient() OVERRIDE
{
166 return image_burner_client_
.get();
169 virtual IntrospectableClient
* GetIntrospectableClient() OVERRIDE
{
170 return introspectable_client_
.get();
173 virtual ModemMessagingClient
* GetModemMessagingClient() OVERRIDE
{
174 return modem_messaging_client_
.get();
177 virtual NfcAdapterClient
* GetNfcAdapterClient() OVERRIDE
{
178 return nfc_adapter_client_
.get();
181 virtual NfcDeviceClient
* GetNfcDeviceClient() OVERRIDE
{
182 return nfc_device_client_
.get();
185 virtual NfcManagerClient
* GetNfcManagerClient() OVERRIDE
{
186 return nfc_manager_client_
.get();
189 virtual NfcRecordClient
* GetNfcRecordClient() OVERRIDE
{
190 return nfc_record_client_
.get();
193 virtual NfcTagClient
* GetNfcTagClient() OVERRIDE
{
194 return nfc_tag_client_
.get();
197 virtual PermissionBrokerClient
* GetPermissionBrokerClient() OVERRIDE
{
198 return permission_broker_client_
.get();
201 virtual PowerManagerClient
* GetPowerManagerClient() OVERRIDE
{
202 return power_manager_client_
.get();
205 virtual PowerPolicyController
* GetPowerPolicyController() OVERRIDE
{
206 return power_policy_controller_
.get();
209 virtual SessionManagerClient
* GetSessionManagerClient() OVERRIDE
{
210 return session_manager_client_
.get();
213 virtual SMSClient
* GetSMSClient() OVERRIDE
{
214 return sms_client_
.get();
217 virtual SystemClockClient
* GetSystemClockClient() OVERRIDE
{
218 return system_clock_client_
.get();
221 virtual UpdateEngineClient
* GetUpdateEngineClient() OVERRIDE
{
222 return update_engine_client_
.get();
226 // Constructs all clients and stores them in the respective *_client_ member
228 void CreateDefaultClients() {
229 DBusClientImplementationType client_type
= REAL_DBUS_CLIENT_IMPLEMENTATION
;
230 DBusClientImplementationType client_type_override
=
231 REAL_DBUS_CLIENT_IMPLEMENTATION
;
232 // If --dbus-stub was requested, pass STUB to specific components;
233 // Many components like login are not useful with a stub implementation.
234 if (CommandLine::ForCurrentProcess()->HasSwitch(
235 chromeos::switches::kDbusStub
)) {
236 client_type_override
= STUB_DBUS_CLIENT_IMPLEMENTATION
;
239 bluetooth_adapter_client_
.reset(BluetoothAdapterClient::Create());
240 bluetooth_agent_manager_client_
.reset(
241 BluetoothAgentManagerClient::Create());
242 bluetooth_device_client_
.reset(BluetoothDeviceClient::Create());
243 bluetooth_input_client_
.reset(BluetoothInputClient::Create());
244 bluetooth_profile_manager_client_
.reset(
245 BluetoothProfileManagerClient::Create());
246 cras_audio_client_
.reset(CrasAudioClient::Create());
247 cros_disks_client_
.reset(CrosDisksClient::Create(client_type
));
248 cryptohome_client_
.reset(CryptohomeClient::Create());
249 debug_daemon_client_
.reset(DebugDaemonClient::Create());
250 shill_manager_client_
.reset(ShillManagerClient::Create());
251 shill_device_client_
.reset(ShillDeviceClient::Create());
252 shill_ipconfig_client_
.reset(ShillIPConfigClient::Create());
253 shill_service_client_
.reset(ShillServiceClient::Create());
254 shill_profile_client_
.reset(ShillProfileClient::Create());
255 gsm_sms_client_
.reset(GsmSMSClient::Create());
256 image_burner_client_
.reset(ImageBurnerClient::Create());
257 introspectable_client_
.reset(IntrospectableClient::Create());
258 modem_messaging_client_
.reset(ModemMessagingClient::Create());
259 // Create the NFC clients in the correct order based on their dependencies.
260 nfc_manager_client_
.reset(NfcManagerClient::Create());
261 nfc_adapter_client_
.reset(
262 NfcAdapterClient::Create(nfc_manager_client_
.get()));
263 nfc_device_client_
.reset(
264 NfcDeviceClient::Create(nfc_adapter_client_
.get()));
265 nfc_tag_client_
.reset(NfcTagClient::Create(nfc_adapter_client_
.get()));
266 nfc_record_client_
.reset(NfcRecordClient::Create(nfc_device_client_
.get(),
267 nfc_tag_client_
.get()));
268 permission_broker_client_
.reset(PermissionBrokerClient::Create());
269 power_manager_client_
.reset(
270 PowerManagerClient::Create(client_type_override
));
271 session_manager_client_
.reset(SessionManagerClient::Create(client_type
));
272 sms_client_
.reset(SMSClient::Create());
273 system_clock_client_
.reset(SystemClockClient::Create());
274 update_engine_client_
.reset(UpdateEngineClient::Create(client_type
));
276 power_policy_controller_
.reset(new PowerPolicyController
);
279 // Note: Keep this before other members so they can call AddObserver() in
281 ObserverList
<DBusThreadManagerObserver
> observers_
;
283 scoped_ptr
<base::Thread
> dbus_thread_
;
284 scoped_refptr
<dbus::Bus
> system_bus_
;
285 scoped_ptr
<BluetoothAdapterClient
> bluetooth_adapter_client_
;
286 scoped_ptr
<BluetoothAgentManagerClient
> bluetooth_agent_manager_client_
;
287 scoped_ptr
<BluetoothDeviceClient
> bluetooth_device_client_
;
288 scoped_ptr
<BluetoothInputClient
> bluetooth_input_client_
;
289 scoped_ptr
<BluetoothProfileManagerClient
> bluetooth_profile_manager_client_
;
290 scoped_ptr
<CrasAudioClient
> cras_audio_client_
;
291 scoped_ptr
<CrosDisksClient
> cros_disks_client_
;
292 scoped_ptr
<CryptohomeClient
> cryptohome_client_
;
293 scoped_ptr
<DebugDaemonClient
> debug_daemon_client_
;
294 scoped_ptr
<ShillDeviceClient
> shill_device_client_
;
295 scoped_ptr
<ShillIPConfigClient
> shill_ipconfig_client_
;
296 scoped_ptr
<ShillManagerClient
> shill_manager_client_
;
297 scoped_ptr
<ShillServiceClient
> shill_service_client_
;
298 scoped_ptr
<ShillProfileClient
> shill_profile_client_
;
299 scoped_ptr
<GsmSMSClient
> gsm_sms_client_
;
300 scoped_ptr
<ImageBurnerClient
> image_burner_client_
;
301 scoped_ptr
<IntrospectableClient
> introspectable_client_
;
302 scoped_ptr
<ModemMessagingClient
> modem_messaging_client_
;
303 // The declaration order for NFC client objects is important. See
304 // DBusThreadManager::CreateDefaultClients for the dependencies.
305 scoped_ptr
<NfcManagerClient
> nfc_manager_client_
;
306 scoped_ptr
<NfcAdapterClient
> nfc_adapter_client_
;
307 scoped_ptr
<NfcDeviceClient
> nfc_device_client_
;
308 scoped_ptr
<NfcTagClient
> nfc_tag_client_
;
309 scoped_ptr
<NfcRecordClient
> nfc_record_client_
;
310 scoped_ptr
<PermissionBrokerClient
> permission_broker_client_
;
311 scoped_ptr
<SystemClockClient
> system_clock_client_
;
312 scoped_ptr
<PowerManagerClient
> power_manager_client_
;
313 scoped_ptr
<SessionManagerClient
> session_manager_client_
;
314 scoped_ptr
<SMSClient
> sms_client_
;
315 scoped_ptr
<UpdateEngineClient
> update_engine_client_
;
317 scoped_ptr
<PowerPolicyController
> power_policy_controller_
;
321 void DBusThreadManager::Initialize() {
322 // If we initialize DBusThreadManager twice we may also be shutting it down
323 // early; do not allow that.
324 CHECK(g_dbus_thread_manager
== NULL
);
326 if (g_dbus_thread_manager_for_testing
) {
327 g_dbus_thread_manager
= g_dbus_thread_manager_for_testing
;
329 VLOG(1) << "DBusThreadManager initialized with test implementation";
332 // Determine whether we use stub or real client implementations.
333 if (base::SysInfo::IsRunningOnChromeOS()) {
334 g_dbus_thread_manager
= new DBusThreadManagerImpl
;
336 VLOG(1) << "DBusThreadManager initialized for ChromeOS";
338 InitializeWithStub();
343 void DBusThreadManager::SetInstanceForTesting(
344 DBusThreadManager
* dbus_thread_manager
) {
345 CHECK(!g_dbus_thread_manager
);
346 CHECK(!g_dbus_thread_manager_for_testing
);
347 g_dbus_thread_manager_for_testing
= dbus_thread_manager
;
351 void DBusThreadManager::InitializeForTesting(
352 DBusThreadManager
* dbus_thread_manager
) {
353 SetInstanceForTesting(dbus_thread_manager
);
358 void DBusThreadManager::InitializeWithStub() {
359 // If we initialize DBusThreadManager twice we may also be shutting it down
360 // early; do not allow that.
361 CHECK(g_dbus_thread_manager
== NULL
);
362 FakeDBusThreadManager
* fake_dbus_thread_manager
= new FakeDBusThreadManager
;
363 fake_dbus_thread_manager
->SetFakeClients();
364 g_dbus_thread_manager
= fake_dbus_thread_manager
;
366 shill_stub_helper::SetupDefaultEnvironment();
367 VLOG(1) << "DBusThreadManager initialized with stub implementation";
371 bool DBusThreadManager::IsInitialized() {
372 return g_dbus_thread_manager
!= NULL
;
376 void DBusThreadManager::Shutdown() {
377 // If we called InitializeForTesting, this may get called more than once.
378 // Ensure that we only shutdown DBusThreadManager once.
379 CHECK(g_dbus_thread_manager
|| g_dbus_thread_manager_for_testing
);
380 DBusThreadManager
* dbus_thread_manager
= g_dbus_thread_manager
;
381 g_dbus_thread_manager
= NULL
;
382 g_dbus_thread_manager_for_testing
= NULL
;
383 delete dbus_thread_manager
;
384 VLOG(1) << "DBusThreadManager Shutdown completed";
387 DBusThreadManager::DBusThreadManager() {
388 dbus::statistics::Initialize();
391 DBusThreadManager::~DBusThreadManager() {
392 dbus::statistics::Shutdown();
393 if (g_dbus_thread_manager
== NULL
)
394 return; // Called form Shutdown() or local test instance.
395 // There should never be both a global instance and a local instance.
396 CHECK(this == g_dbus_thread_manager
);
397 if (g_dbus_thread_manager_for_testing
) {
398 g_dbus_thread_manager
= NULL
;
399 g_dbus_thread_manager_for_testing
= NULL
;
400 VLOG(1) << "DBusThreadManager destroyed";
402 LOG(FATAL
) << "~DBusThreadManager() called outside of Shutdown()";
407 DBusThreadManager
* DBusThreadManager::Get() {
408 CHECK(g_dbus_thread_manager
)
409 << "DBusThreadManager::Get() called before Initialize()";
410 return g_dbus_thread_manager
;
414 void DBusThreadManager::InitializeClients() {
415 InitClient(g_dbus_thread_manager
->GetBluetoothAdapterClient());
416 InitClient(g_dbus_thread_manager
->GetBluetoothAgentManagerClient());
417 InitClient(g_dbus_thread_manager
->GetBluetoothDeviceClient());
418 InitClient(g_dbus_thread_manager
->GetBluetoothInputClient());
419 InitClient(g_dbus_thread_manager
->GetBluetoothProfileManagerClient());
420 InitClient(g_dbus_thread_manager
->GetCrasAudioClient());
421 InitClient(g_dbus_thread_manager
->GetCrosDisksClient());
422 InitClient(g_dbus_thread_manager
->GetCryptohomeClient());
423 InitClient(g_dbus_thread_manager
->GetDebugDaemonClient());
424 InitClient(g_dbus_thread_manager
->GetGsmSMSClient());
425 InitClient(g_dbus_thread_manager
->GetImageBurnerClient());
426 InitClient(g_dbus_thread_manager
->GetIntrospectableClient());
427 InitClient(g_dbus_thread_manager
->GetModemMessagingClient());
428 InitClient(g_dbus_thread_manager
->GetPermissionBrokerClient());
429 InitClient(g_dbus_thread_manager
->GetPowerManagerClient());
430 InitClient(g_dbus_thread_manager
->GetSessionManagerClient());
431 InitClient(g_dbus_thread_manager
->GetShillDeviceClient());
432 InitClient(g_dbus_thread_manager
->GetShillIPConfigClient());
433 InitClient(g_dbus_thread_manager
->GetShillManagerClient());
434 InitClient(g_dbus_thread_manager
->GetShillServiceClient());
435 InitClient(g_dbus_thread_manager
->GetShillProfileClient());
436 InitClient(g_dbus_thread_manager
->GetSMSClient());
437 InitClient(g_dbus_thread_manager
->GetSystemClockClient());
438 InitClient(g_dbus_thread_manager
->GetUpdateEngineClient());
440 // Initialize the NFC clients in the correct order. The order of
441 // initialization matters due to dependencies that exist between the
443 InitClient(g_dbus_thread_manager
->GetNfcManagerClient());
444 InitClient(g_dbus_thread_manager
->GetNfcAdapterClient());
445 InitClient(g_dbus_thread_manager
->GetNfcDeviceClient());
446 InitClient(g_dbus_thread_manager
->GetNfcTagClient());
447 InitClient(g_dbus_thread_manager
->GetNfcRecordClient());
449 // PowerPolicyController is dependent on PowerManagerClient, so
450 // initialize it after the main list of clients.
451 if (g_dbus_thread_manager
->GetPowerPolicyController()) {
452 g_dbus_thread_manager
->GetPowerPolicyController()->Init(
453 g_dbus_thread_manager
);
456 // This must be called after the list of clients so they've each had a
457 // chance to register with their object g_dbus_thread_managers.
458 if (g_dbus_thread_manager
->GetSystemBus())
459 g_dbus_thread_manager
->GetSystemBus()->GetManagedObjects();
463 void DBusThreadManager::InitClient(DBusClient
* client
) {
465 client
->Init(g_dbus_thread_manager
->GetSystemBus());
468 } // namespace chromeos