Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / dbus_thread_manager.cc
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.
4
5 #include "chromeos/dbus/dbus_thread_manager.h"
6
7 #include "base/command_line.h"
8 #include "base/sys_info.h"
9 #include "base/threading/thread.h"
10 #include "chromeos/chromeos_switches.h"
11 #include "chromeos/dbus/bluetooth_adapter_client.h"
12 #include "chromeos/dbus/bluetooth_agent_manager_client.h"
13 #include "chromeos/dbus/bluetooth_device_client.h"
14 #include "chromeos/dbus/bluetooth_gatt_characteristic_client.h"
15 #include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
16 #include "chromeos/dbus/bluetooth_gatt_manager_client.h"
17 #include "chromeos/dbus/bluetooth_gatt_service_client.h"
18 #include "chromeos/dbus/bluetooth_input_client.h"
19 #include "chromeos/dbus/bluetooth_profile_manager_client.h"
20 #include "chromeos/dbus/cras_audio_client.h"
21 #include "chromeos/dbus/cros_disks_client.h"
22 #include "chromeos/dbus/cryptohome_client.h"
23 #include "chromeos/dbus/dbus_client.h"
24 #include "chromeos/dbus/dbus_client_bundle.h"
25 #include "chromeos/dbus/debug_daemon_client.h"
26 #include "chromeos/dbus/easy_unlock_client.h"
27 #include "chromeos/dbus/fake_dbus_thread_manager.h"
28 #include "chromeos/dbus/gsm_sms_client.h"
29 #include "chromeos/dbus/image_burner_client.h"
30 #include "chromeos/dbus/introspectable_client.h"
31 #include "chromeos/dbus/lorgnette_manager_client.h"
32 #include "chromeos/dbus/modem_messaging_client.h"
33 #include "chromeos/dbus/nfc_adapter_client.h"
34 #include "chromeos/dbus/nfc_device_client.h"
35 #include "chromeos/dbus/nfc_manager_client.h"
36 #include "chromeos/dbus/nfc_record_client.h"
37 #include "chromeos/dbus/nfc_tag_client.h"
38 #include "chromeos/dbus/permission_broker_client.h"
39 #include "chromeos/dbus/power_manager_client.h"
40 #include "chromeos/dbus/power_policy_controller.h"
41 #include "chromeos/dbus/session_manager_client.h"
42 #include "chromeos/dbus/shill_device_client.h"
43 #include "chromeos/dbus/shill_ipconfig_client.h"
44 #include "chromeos/dbus/shill_manager_client.h"
45 #include "chromeos/dbus/shill_profile_client.h"
46 #include "chromeos/dbus/shill_service_client.h"
47 #include "chromeos/dbus/sms_client.h"
48 #include "chromeos/dbus/system_clock_client.h"
49 #include "chromeos/dbus/update_engine_client.h"
50 #include "dbus/bus.h"
51 #include "dbus/dbus_statistics.h"
52
53 namespace chromeos {
54
55 static DBusThreadManager* g_dbus_thread_manager = NULL;
56 static DBusThreadManager* g_dbus_thread_manager_for_testing = NULL;
57
58 DBusClientBundle::DBusClientTypeMask
59     DBusThreadManager::unstub_client_mask_ = DBusClientBundle::NO_CLIENTS;
60
61 // The DBusThreadManager implementation used in production.
62 class DBusThreadManagerImpl : public DBusThreadManager {
63  public:
64   DBusThreadManagerImpl() {
65     // Create the D-Bus thread.
66     base::Thread::Options thread_options;
67     thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
68     dbus_thread_.reset(new base::Thread("D-Bus thread"));
69     dbus_thread_->StartWithOptions(thread_options);
70
71     // Create the connection to the system bus.
72     dbus::Bus::Options system_bus_options;
73     system_bus_options.bus_type = dbus::Bus::SYSTEM;
74     system_bus_options.connection_type = dbus::Bus::PRIVATE;
75     system_bus_options.dbus_task_runner = dbus_thread_->message_loop_proxy();
76     system_bus_ = new dbus::Bus(system_bus_options);
77
78     CreateDefaultClients();
79   }
80
81   virtual ~DBusThreadManagerImpl() {
82     // PowerPolicyController's destructor depends on PowerManagerClient.
83     power_policy_controller_.reset();
84
85     // Delete all D-Bus clients before shutting down the system bus.
86     client_bundle_.reset();
87
88     // Shut down the bus. During the browser shutdown, it's ok to shut down
89     // the bus synchronously.
90     system_bus_->ShutdownOnDBusThreadAndBlock();
91
92     // Stop the D-Bus thread.
93     dbus_thread_->Stop();
94   }
95
96   void SetupDefaultEnvironment() {
97     return client_bundle_->SetupDefaultEnvironment();
98   }
99
100   virtual dbus::Bus* GetSystemBus() OVERRIDE {
101     return system_bus_.get();
102   }
103
104   virtual BluetoothAdapterClient* GetBluetoothAdapterClient() OVERRIDE {
105     return client_bundle_->bluetooth_adapter_client();
106   }
107
108   virtual BluetoothAgentManagerClient* GetBluetoothAgentManagerClient()
109       OVERRIDE {
110     return client_bundle_->bluetooth_agent_manager_client();
111   }
112
113   virtual BluetoothDeviceClient* GetBluetoothDeviceClient() OVERRIDE {
114     return client_bundle_->bluetooth_device_client();
115   }
116
117   virtual BluetoothGattCharacteristicClient*
118       GetBluetoothGattCharacteristicClient() OVERRIDE {
119     return client_bundle_->bluetooth_gatt_characteristic_client();
120   }
121
122   virtual BluetoothGattDescriptorClient* GetBluetoothGattDescriptorClient()
123       OVERRIDE {
124     return client_bundle_->bluetooth_gatt_descriptor_client();
125   }
126
127   virtual BluetoothGattManagerClient* GetBluetoothGattManagerClient() OVERRIDE {
128     return client_bundle_->bluetooth_gatt_manager_client();
129   }
130
131   virtual BluetoothGattServiceClient* GetBluetoothGattServiceClient() OVERRIDE {
132     return client_bundle_->bluetooth_gatt_service_client();
133   }
134
135   virtual BluetoothInputClient* GetBluetoothInputClient() OVERRIDE {
136     return client_bundle_->bluetooth_input_client();
137   }
138
139   virtual BluetoothProfileManagerClient* GetBluetoothProfileManagerClient()
140       OVERRIDE {
141     return client_bundle_->bluetooth_profile_manager_client();
142   }
143
144   virtual CrasAudioClient* GetCrasAudioClient() OVERRIDE {
145     return client_bundle_->cras_audio_client();
146   }
147
148   virtual CrosDisksClient* GetCrosDisksClient() OVERRIDE {
149     return client_bundle_->cros_disks_client();
150   }
151
152   virtual CryptohomeClient* GetCryptohomeClient() OVERRIDE {
153     return client_bundle_->cryptohome_client();
154   }
155
156   virtual DebugDaemonClient* GetDebugDaemonClient() OVERRIDE {
157     return client_bundle_->debug_daemon_client();
158   }
159
160   virtual EasyUnlockClient* GetEasyUnlockClient() OVERRIDE {
161     return client_bundle_->easy_unlock_client();
162   }
163   virtual LorgnetteManagerClient* GetLorgnetteManagerClient() OVERRIDE {
164     return client_bundle_->lorgnette_manager_client();
165   }
166
167   virtual ShillDeviceClient* GetShillDeviceClient() OVERRIDE {
168     return client_bundle_->shill_device_client();
169   }
170
171   virtual ShillIPConfigClient* GetShillIPConfigClient() OVERRIDE {
172     return client_bundle_->shill_ipconfig_client();
173   }
174
175   virtual ShillManagerClient* GetShillManagerClient() OVERRIDE {
176     return client_bundle_->shill_manager_client();
177   }
178
179   virtual ShillServiceClient* GetShillServiceClient() OVERRIDE {
180     return client_bundle_->shill_service_client();
181   }
182
183   virtual ShillProfileClient* GetShillProfileClient() OVERRIDE {
184     return client_bundle_->shill_profile_client();
185   }
186
187   virtual GsmSMSClient* GetGsmSMSClient() OVERRIDE {
188     return client_bundle_->gsm_sms_client();
189   }
190
191   virtual ImageBurnerClient* GetImageBurnerClient() OVERRIDE {
192     return client_bundle_->image_burner_client();
193   }
194
195   virtual IntrospectableClient* GetIntrospectableClient() OVERRIDE {
196     return client_bundle_->introspectable_client();
197   }
198
199   virtual ModemMessagingClient* GetModemMessagingClient() OVERRIDE {
200     return client_bundle_->modem_messaging_client();
201   }
202
203   virtual NfcAdapterClient* GetNfcAdapterClient() OVERRIDE {
204     return client_bundle_->nfc_adapter_client();
205   }
206
207   virtual NfcDeviceClient* GetNfcDeviceClient() OVERRIDE {
208     return client_bundle_->nfc_device_client();
209   }
210
211   virtual NfcManagerClient* GetNfcManagerClient() OVERRIDE {
212     return client_bundle_->nfc_manager_client();
213   }
214
215   virtual NfcRecordClient* GetNfcRecordClient() OVERRIDE {
216     return client_bundle_->nfc_record_client();
217   }
218
219   virtual NfcTagClient* GetNfcTagClient() OVERRIDE {
220     return client_bundle_->nfc_tag_client();
221   }
222
223   virtual PermissionBrokerClient* GetPermissionBrokerClient() OVERRIDE {
224     return client_bundle_->permission_broker_client();
225   }
226
227   virtual PowerManagerClient* GetPowerManagerClient() OVERRIDE {
228     return client_bundle_->power_manager_client();
229   }
230
231   virtual SessionManagerClient* GetSessionManagerClient() OVERRIDE {
232     return client_bundle_->session_manager_client();
233   }
234
235   virtual SMSClient* GetSMSClient() OVERRIDE {
236     return client_bundle_->sms_client();
237   }
238
239   virtual SystemClockClient* GetSystemClockClient() OVERRIDE {
240     return client_bundle_->system_clock_client();
241   }
242
243   virtual UpdateEngineClient* GetUpdateEngineClient() OVERRIDE {
244     return client_bundle_->update_engine_client();
245   }
246
247   virtual PowerPolicyController* GetPowerPolicyController() OVERRIDE {
248     return power_policy_controller_.get();
249   }
250
251  private:
252   // Constructs all clients and stores them in the respective *_client_ member
253   // variable.
254   void CreateDefaultClients() {
255     client_bundle_.reset(new DBusClientBundle());
256     // TODO(crbug.com/345586): Move PowerPolicyController out of
257     // DBusThreadManagerImpl.
258     power_policy_controller_.reset(new PowerPolicyController);
259   }
260
261   scoped_ptr<base::Thread> dbus_thread_;
262   scoped_refptr<dbus::Bus> system_bus_;
263   scoped_ptr<DBusClientBundle> client_bundle_;
264   scoped_ptr<PowerPolicyController> power_policy_controller_;
265
266   DISALLOW_COPY_AND_ASSIGN(DBusThreadManagerImpl);
267 };
268
269 // static
270 bool DBusThreadManager::IsUsingStub(DBusClientBundle::DBusClientType client) {
271   return !(unstub_client_mask_ & client);
272 }
273
274 // static
275 void DBusThreadManager::Initialize() {
276   // If we initialize DBusThreadManager twice we may also be shutting it down
277   // early; do not allow that.
278   CHECK(g_dbus_thread_manager == NULL);
279
280   if (g_dbus_thread_manager_for_testing) {
281     g_dbus_thread_manager = g_dbus_thread_manager_for_testing;
282     InitializeClients();
283     VLOG(1) << "DBusThreadManager initialized with test implementation";
284     return;
285   }
286
287   bool use_dbus_stub = !base::SysInfo::IsRunningOnChromeOS() ||
288       CommandLine::ForCurrentProcess()->HasSwitch(
289           chromeos::switches::kDbusStub);
290   bool force_unstub_clients = CommandLine::ForCurrentProcess()->HasSwitch(
291       chromeos::switches::kDbusUnstubClients);
292   // Determine whether we use stub or real client implementations.
293   if (force_unstub_clients) {
294     InitializeWithPartialStub(
295         CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
296             chromeos::switches::kDbusUnstubClients));
297   } else if (use_dbus_stub) {
298     InitializeWithStub();
299   } else {
300     InitializeRegular();
301   }
302 }
303
304 // static
305 void DBusThreadManager::SetInstanceForTesting(
306     DBusThreadManager* dbus_thread_manager) {
307   CHECK(!g_dbus_thread_manager);
308   CHECK(!g_dbus_thread_manager_for_testing);
309   g_dbus_thread_manager_for_testing = dbus_thread_manager;
310 }
311
312 // static
313 void DBusThreadManager::InitializeForTesting(
314     DBusThreadManager* dbus_thread_manager) {
315   unstub_client_mask_ = DBusClientBundle::NO_CLIENTS;
316   SetInstanceForTesting(dbus_thread_manager);
317   Initialize();
318 }
319
320 // static
321 void DBusThreadManager::InitializeRegular() {
322   unstub_client_mask_ = DBusClientBundle::ALL_CLIENTS;
323   g_dbus_thread_manager = new DBusThreadManagerImpl();
324   InitializeClients();
325   VLOG(1) << "DBusThreadManager initialized for Chrome OS";
326 }
327
328 // static
329 void DBusThreadManager::InitializeWithPartialStub(
330     const std::string& unstub_clients) {
331   // If we initialize DBusThreadManager twice we may also be shutting it down
332   // early; do not allow that.
333   CHECK(g_dbus_thread_manager == NULL);
334
335   unstub_client_mask_ = DBusClientBundle::ParseUnstubList(unstub_clients);
336   // We should have something parsed correctly here.
337   if (unstub_client_mask_ == 0) {
338     LOG(FATAL) << "Switch values for --"
339                << chromeos::switches::kDbusUnstubClients
340                << " cannot be parsed: "
341                << unstub_clients;
342   }
343   DBusThreadManagerImpl* dbus_thread_manager = new DBusThreadManagerImpl();
344   VLOG(1) << "DBusThreadManager initialized for mixed runtime environment";
345   g_dbus_thread_manager = dbus_thread_manager;
346   InitializeClients();
347   dbus_thread_manager->SetupDefaultEnvironment();
348 }
349
350 // static
351 void DBusThreadManager::InitializeWithStub() {
352   unstub_client_mask_ = DBusClientBundle::NO_CLIENTS;
353   // If we initialize DBusThreadManager twice we may also be shutting it down
354   // early; do not allow that.
355   CHECK(g_dbus_thread_manager == NULL);
356   FakeDBusThreadManager* fake_dbus_thread_manager = new FakeDBusThreadManager;
357   fake_dbus_thread_manager->SetFakeClients();
358   g_dbus_thread_manager = fake_dbus_thread_manager;
359   InitializeClients();
360   fake_dbus_thread_manager->SetupDefaultEnvironment();
361   VLOG(1) << "DBusThreadManager initialized with stub implementation";
362 }
363
364 // static
365 bool DBusThreadManager::IsInitialized() {
366   return g_dbus_thread_manager != NULL;
367 }
368
369 // static
370 void DBusThreadManager::Shutdown() {
371   // If we called InitializeForTesting, this may get called more than once.
372   // Ensure that we only shutdown DBusThreadManager once.
373   CHECK(g_dbus_thread_manager || g_dbus_thread_manager_for_testing);
374   DBusThreadManager* dbus_thread_manager = g_dbus_thread_manager;
375   g_dbus_thread_manager = NULL;
376   g_dbus_thread_manager_for_testing = NULL;
377   delete dbus_thread_manager;
378   VLOG(1) << "DBusThreadManager Shutdown completed";
379 }
380
381 DBusThreadManager::DBusThreadManager() {
382   dbus::statistics::Initialize();
383 }
384
385 DBusThreadManager::~DBusThreadManager() {
386   dbus::statistics::Shutdown();
387   if (g_dbus_thread_manager == NULL)
388     return;  // Called form Shutdown() or local test instance.
389   // There should never be both a global instance and a local instance.
390   CHECK(this == g_dbus_thread_manager);
391   if (g_dbus_thread_manager_for_testing) {
392     g_dbus_thread_manager = NULL;
393     g_dbus_thread_manager_for_testing = NULL;
394     VLOG(1) << "DBusThreadManager destroyed";
395   } else {
396     LOG(FATAL) << "~DBusThreadManager() called outside of Shutdown()";
397   }
398 }
399
400 // static
401 DBusThreadManager* DBusThreadManager::Get() {
402   CHECK(g_dbus_thread_manager)
403       << "DBusThreadManager::Get() called before Initialize()";
404   return g_dbus_thread_manager;
405 }
406
407 // static
408 void DBusThreadManager::InitializeClients() {
409   InitClient(g_dbus_thread_manager->GetBluetoothAdapterClient());
410   InitClient(g_dbus_thread_manager->GetBluetoothAgentManagerClient());
411   InitClient(g_dbus_thread_manager->GetBluetoothDeviceClient());
412   InitClient(g_dbus_thread_manager->GetBluetoothGattCharacteristicClient());
413   InitClient(g_dbus_thread_manager->GetBluetoothGattDescriptorClient());
414   InitClient(g_dbus_thread_manager->GetBluetoothGattManagerClient());
415   InitClient(g_dbus_thread_manager->GetBluetoothGattServiceClient());
416   InitClient(g_dbus_thread_manager->GetBluetoothInputClient());
417   InitClient(g_dbus_thread_manager->GetBluetoothProfileManagerClient());
418   InitClient(g_dbus_thread_manager->GetCrasAudioClient());
419   InitClient(g_dbus_thread_manager->GetCrosDisksClient());
420   InitClient(g_dbus_thread_manager->GetCryptohomeClient());
421   InitClient(g_dbus_thread_manager->GetDebugDaemonClient());
422   InitClient(g_dbus_thread_manager->GetEasyUnlockClient());
423   InitClient(g_dbus_thread_manager->GetGsmSMSClient());
424   InitClient(g_dbus_thread_manager->GetImageBurnerClient());
425   InitClient(g_dbus_thread_manager->GetIntrospectableClient());
426   InitClient(g_dbus_thread_manager->GetLorgnetteManagerClient());
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());
439
440   // Initialize the NFC clients in the correct order. The order of
441   // initialization matters due to dependencies that exist between the
442   // client objects.
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());
448
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);
454   }
455
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();
460 }
461
462 // static
463 void DBusThreadManager::InitClient(DBusClient* client) {
464   if (client)
465     client->Init(g_dbus_thread_manager->GetSystemBus());
466 }
467
468 }  // namespace chromeos