blob: 397e431e84fc584cef1ba88213a8fece0ef97c57 [file] [log] [blame]
// 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/dbus_thread_manager.h"
#include "base/chromeos/chromeos_version.h"
#include "base/command_line.h"
#include "base/threading/thread.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/bluetooth_adapter_client.h"
#include "chromeos/dbus/bluetooth_device_client.h"
#include "chromeos/dbus/bluetooth_input_client.h"
#include "chromeos/dbus/bluetooth_manager_client.h"
#include "chromeos/dbus/bluetooth_node_client.h"
#include "chromeos/dbus/bluetooth_out_of_band_client.h"
#include "chromeos/dbus/cashew_client.h"
#include "chromeos/dbus/cros_disks_client.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "chromeos/dbus/dbus_client_implementation_type.h"
#include "chromeos/dbus/debug_daemon_client.h"
#include "chromeos/dbus/flimflam_device_client.h"
#include "chromeos/dbus/flimflam_ipconfig_client.h"
#include "chromeos/dbus/flimflam_manager_client.h"
#include "chromeos/dbus/flimflam_network_client.h"
#include "chromeos/dbus/flimflam_profile_client.h"
#include "chromeos/dbus/flimflam_service_client.h"
#include "chromeos/dbus/gsm_sms_client.h"
#include "chromeos/dbus/ibus/ibus_client.h"
#include "chromeos/dbus/ibus/ibus_engine_factory_service.h"
#include "chromeos/dbus/ibus/ibus_engine_service.h"
#include "chromeos/dbus/ibus/ibus_input_context_client.h"
#include "chromeos/dbus/image_burner_client.h"
#include "chromeos/dbus/introspectable_client.h"
#include "chromeos/dbus/modem_messaging_client.h"
#include "chromeos/dbus/power_manager_client.h"
#include "chromeos/dbus/session_manager_client.h"
#include "chromeos/dbus/sms_client.h"
#include "chromeos/dbus/speech_synthesizer_client.h"
#include "chromeos/dbus/update_engine_client.h"
#include "dbus/bus.h"
namespace chromeos {
static DBusThreadManager* g_dbus_thread_manager = NULL;
// The DBusThreadManager implementation used in production.
class DBusThreadManagerImpl : public DBusThreadManager {
public:
explicit DBusThreadManagerImpl(DBusClientImplementationType client_type) {
// If --dbus-stub was requested, pass STUB to specific components;
// Many components like login are not useful with a stub implementation.
DBusClientImplementationType client_type_maybe_stub = client_type;
if (CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kDbusStub))
client_type_maybe_stub = STUB_DBUS_CLIENT_IMPLEMENTATION;
// Create the D-Bus thread.
base::Thread::Options thread_options;
thread_options.message_loop_type = MessageLoop::TYPE_IO;
dbus_thread_.reset(new base::Thread("D-Bus thread"));
dbus_thread_->StartWithOptions(thread_options);
// Create the connection to the system bus.
dbus::Bus::Options system_bus_options;
system_bus_options.bus_type = dbus::Bus::SYSTEM;
system_bus_options.connection_type = dbus::Bus::PRIVATE;
system_bus_options.dbus_thread_message_loop_proxy =
dbus_thread_->message_loop_proxy();
system_bus_ = new dbus::Bus(system_bus_options);
// Create the bluetooth clients.
bluetooth_manager_client_.reset(BluetoothManagerClient::Create(
client_type, system_bus_.get()));
bluetooth_adapter_client_.reset(BluetoothAdapterClient::Create(
client_type, system_bus_.get(), bluetooth_manager_client_.get()));
bluetooth_device_client_.reset(BluetoothDeviceClient::Create(
client_type, system_bus_.get(), bluetooth_adapter_client_.get()));
bluetooth_input_client_.reset(BluetoothInputClient::Create(
client_type, system_bus_.get(), bluetooth_adapter_client_.get()));
bluetooth_node_client_.reset(BluetoothNodeClient::Create(
client_type, system_bus_.get(), bluetooth_device_client_.get()));
bluetooth_out_of_band_client_.reset(BluetoothOutOfBandClient::Create(
client_type, system_bus_.get()));
// Create the Cashew client.
cashew_client_.reset(CashewClient::Create(client_type, system_bus_.get()));
// Create the cros-disks client.
cros_disks_client_.reset(
CrosDisksClient::Create(client_type, system_bus_.get()));
// Create the Cryptohome client.
cryptohome_client_.reset(
CryptohomeClient::Create(client_type, system_bus_.get()));
// Create the debugdaemon client.
debugdaemon_client_.reset(
DebugDaemonClient::Create(client_type, system_bus_.get()));
// Create the Flimflam Device client.
flimflam_device_client_.reset(
FlimflamDeviceClient::Create(client_type, system_bus_.get()));
// Create the Flimflam IPConfig client.
flimflam_ipconfig_client_.reset(
FlimflamIPConfigClient::Create(client_type, system_bus_.get()));
// Create the Flimflam Manager client.
flimflam_manager_client_.reset(
FlimflamManagerClient::Create(client_type, system_bus_.get()));
// Create the Flimflam Network client.
flimflam_network_client_.reset(
FlimflamNetworkClient::Create(client_type, system_bus_.get()));
// Create the Flimflam Profile client.
flimflam_profile_client_.reset(
FlimflamProfileClient::Create(client_type, system_bus_.get()));
// Create the Flimflam Service client.
flimflam_service_client_.reset(
FlimflamServiceClient::Create(client_type, system_bus_.get()));
// Create the Gsm SMS client.
gsm_sms_client_.reset(
GsmSMSClient::Create(client_type, system_bus_.get()));
// Create the image burner client.
image_burner_client_.reset(ImageBurnerClient::Create(client_type,
system_bus_.get()));
// Create the introspectable object client.
introspectable_client_.reset(
IntrospectableClient::Create(client_type, system_bus_.get()));
// Create the ModemMessaging client.
modem_messaging_client_.reset(
ModemMessagingClient::Create(client_type, system_bus_.get()));
// Create the power manager client.
power_manager_client_.reset(
PowerManagerClient::Create(client_type_maybe_stub, system_bus_.get()));
// Create the session manager client.
session_manager_client_.reset(
SessionManagerClient::Create(client_type, system_bus_.get()));
// Create the SMS client.
sms_client_.reset(
SMSClient::Create(client_type, system_bus_.get()));
// Create the speech synthesizer client.
speech_synthesizer_client_.reset(
SpeechSynthesizerClient::Create(client_type, system_bus_.get()));
// Create the update engine client.
update_engine_client_.reset(
UpdateEngineClient::Create(client_type, system_bus_.get()));
}
virtual ~DBusThreadManagerImpl() {
// Shut down the bus. During the browser shutdown, it's ok to shut down
// the bus synchronously.
system_bus_->ShutdownOnDBusThreadAndBlock();
if (ibus_bus_.get())
ibus_bus_->ShutdownOnDBusThreadAndBlock();
// Release IBusEngineService instances.
for (std::map<dbus::ObjectPath, IBusEngineService*>::iterator it
= ibus_engine_services_.begin();
it != ibus_engine_services_.end(); it++) {
delete it->second;
}
// Stop the D-Bus thread.
dbus_thread_->Stop();
}
// DBusThreadManager override.
virtual void InitIBusBus(const std::string &ibus_address) OVERRIDE {
DCHECK(!ibus_bus_);
dbus::Bus::Options ibus_bus_options;
ibus_bus_options.bus_type = dbus::Bus::CUSTOM_ADDRESS;
ibus_bus_options.address = ibus_address;
ibus_bus_options.connection_type = dbus::Bus::PRIVATE;
ibus_bus_options.dbus_thread_message_loop_proxy =
dbus_thread_->message_loop_proxy();
ibus_bus_ = new dbus::Bus(ibus_bus_options);
ibus_address_ = ibus_address;
VLOG(1) << "Connected to ibus-daemon: " << ibus_address;
DBusClientImplementationType client_type =
base::chromeos::IsRunningOnChromeOS() ? REAL_DBUS_CLIENT_IMPLEMENTATION
: STUB_DBUS_CLIENT_IMPLEMENTATION;
// Create the ibus client.
ibus_client_.reset(
IBusClient::Create(client_type, ibus_bus_.get()));
// Create the ibus input context client.
ibus_input_context_client_.reset(
IBusInputContextClient::Create(client_type));
// Create the ibus engine factory service.
ibus_engine_factory_service_.reset(
IBusEngineFactoryService::Create(ibus_bus_.get(), client_type));
ibus_engine_services_.clear();
}
// DBusThreadManager override.
virtual dbus::Bus* GetSystemBus() OVERRIDE {
return system_bus_.get();
}
// DBusThreadManager override.
virtual dbus::Bus* GetIBusBus() OVERRIDE {
return ibus_bus_.get();
}
// DBusThreadManager override.
virtual BluetoothAdapterClient* GetBluetoothAdapterClient() OVERRIDE {
return bluetooth_adapter_client_.get();
}
// DBusThreadManager override.
virtual BluetoothDeviceClient* GetBluetoothDeviceClient() OVERRIDE {
return bluetooth_device_client_.get();
}
// DBusThreadManager override.
virtual BluetoothInputClient* GetBluetoothInputClient() OVERRIDE {
return bluetooth_input_client_.get();
}
// DBusThreadManager override.
virtual BluetoothManagerClient* GetBluetoothManagerClient() OVERRIDE {
return bluetooth_manager_client_.get();
}
// DBusThreadManager override.
virtual BluetoothNodeClient* GetBluetoothNodeClient() OVERRIDE {
return bluetooth_node_client_.get();
}
// DBusThreadManager override.
virtual BluetoothOutOfBandClient* GetBluetoothOutOfBandClient() OVERRIDE {
return bluetooth_out_of_band_client_.get();
}
// DBusThreadManager override.
virtual CashewClient* GetCashewClient() OVERRIDE {
return cashew_client_.get();
}
// DBusThreadManager override.
virtual CrosDisksClient* GetCrosDisksClient() OVERRIDE {
return cros_disks_client_.get();
}
// DBusThreadManager override.
virtual CryptohomeClient* GetCryptohomeClient() OVERRIDE {
return cryptohome_client_.get();
}
// DBusThreadManager override.
virtual DebugDaemonClient* GetDebugDaemonClient() OVERRIDE {
return debugdaemon_client_.get();
}
// DBusThreadManager override.
virtual FlimflamDeviceClient* GetFlimflamDeviceClient() OVERRIDE {
return flimflam_device_client_.get();
}
// DBusThreadManager override.
virtual FlimflamIPConfigClient* GetFlimflamIPConfigClient() OVERRIDE {
return flimflam_ipconfig_client_.get();
}
// DBusThreadManager override.
virtual FlimflamManagerClient* GetFlimflamManagerClient() OVERRIDE {
return flimflam_manager_client_.get();
}
// DBusThreadManager override.
virtual FlimflamNetworkClient* GetFlimflamNetworkClient() OVERRIDE {
return flimflam_network_client_.get();
}
// DBusThreadManager override.
virtual FlimflamProfileClient* GetFlimflamProfileClient() OVERRIDE {
return flimflam_profile_client_.get();
}
// DBusThreadManager override.
virtual FlimflamServiceClient* GetFlimflamServiceClient() OVERRIDE {
return flimflam_service_client_.get();
}
// DBusThreadManager override.
virtual GsmSMSClient* GetGsmSMSClient() OVERRIDE {
return gsm_sms_client_.get();
}
// DBusThreadManager override.
virtual ImageBurnerClient* GetImageBurnerClient() OVERRIDE {
return image_burner_client_.get();
}
// DBusThreadManager override.
virtual IntrospectableClient* GetIntrospectableClient() OVERRIDE {
return introspectable_client_.get();
}
// DBusThreadManager override.
virtual ModemMessagingClient* GetModemMessagingClient() OVERRIDE {
return modem_messaging_client_.get();
}
// DBusThreadManager override.
virtual PowerManagerClient* GetPowerManagerClient() OVERRIDE {
return power_manager_client_.get();
}
// DBusThreadManager override.
virtual SessionManagerClient* GetSessionManagerClient() OVERRIDE {
return session_manager_client_.get();
}
// DBusThreadManager override.
virtual SMSClient* GetSMSClient() OVERRIDE {
return sms_client_.get();
}
// DBusThreadManager override.
virtual SpeechSynthesizerClient* GetSpeechSynthesizerClient() OVERRIDE {
return speech_synthesizer_client_.get();
}
// DBusThreadManager override.
virtual UpdateEngineClient* GetUpdateEngineClient() OVERRIDE {
return update_engine_client_.get();
}
// DBusThreadManager override.
virtual IBusClient* GetIBusClient() OVERRIDE {
return ibus_client_.get();
}
// DBusThreadManager override.
virtual IBusInputContextClient* GetIBusInputContextClient() OVERRIDE {
return ibus_input_context_client_.get();
}
// DBusThreadManager override.
virtual IBusEngineFactoryService* GetIBusEngineFactoryService() OVERRIDE {
return ibus_engine_factory_service_.get();
}
// DBusThreadManager override.
virtual IBusEngineService* GetIBusEngineService(
const dbus::ObjectPath& object_path) OVERRIDE {
const DBusClientImplementationType client_type =
base::chromeos::IsRunningOnChromeOS() ? REAL_DBUS_CLIENT_IMPLEMENTATION
: STUB_DBUS_CLIENT_IMPLEMENTATION;
if (ibus_engine_services_.find(object_path)
== ibus_engine_services_.end()) {
ibus_engine_services_[object_path] =
IBusEngineService::Create(client_type, ibus_bus_.get(), object_path);
}
return ibus_engine_services_[object_path];
}
scoped_ptr<base::Thread> dbus_thread_;
scoped_refptr<dbus::Bus> system_bus_;
scoped_refptr<dbus::Bus> ibus_bus_;
scoped_ptr<BluetoothAdapterClient> bluetooth_adapter_client_;
scoped_ptr<BluetoothDeviceClient> bluetooth_device_client_;
scoped_ptr<BluetoothInputClient> bluetooth_input_client_;
scoped_ptr<BluetoothManagerClient> bluetooth_manager_client_;
scoped_ptr<BluetoothNodeClient> bluetooth_node_client_;
scoped_ptr<BluetoothOutOfBandClient> bluetooth_out_of_band_client_;
scoped_ptr<CashewClient> cashew_client_;
scoped_ptr<CrosDisksClient> cros_disks_client_;
scoped_ptr<CryptohomeClient> cryptohome_client_;
scoped_ptr<DebugDaemonClient> debugdaemon_client_;
scoped_ptr<FlimflamDeviceClient> flimflam_device_client_;
scoped_ptr<FlimflamIPConfigClient> flimflam_ipconfig_client_;
scoped_ptr<FlimflamManagerClient> flimflam_manager_client_;
scoped_ptr<FlimflamNetworkClient> flimflam_network_client_;
scoped_ptr<FlimflamProfileClient> flimflam_profile_client_;
scoped_ptr<FlimflamServiceClient> flimflam_service_client_;
scoped_ptr<GsmSMSClient> gsm_sms_client_;
scoped_ptr<ImageBurnerClient> image_burner_client_;
scoped_ptr<IntrospectableClient> introspectable_client_;
scoped_ptr<ModemMessagingClient> modem_messaging_client_;
scoped_ptr<PowerManagerClient> power_manager_client_;
scoped_ptr<SessionManagerClient> session_manager_client_;
scoped_ptr<SMSClient> sms_client_;
scoped_ptr<SpeechSynthesizerClient> speech_synthesizer_client_;
scoped_ptr<UpdateEngineClient> update_engine_client_;
scoped_ptr<IBusClient> ibus_client_;
scoped_ptr<IBusInputContextClient> ibus_input_context_client_;
scoped_ptr<IBusEngineFactoryService> ibus_engine_factory_service_;
std::map<dbus::ObjectPath, IBusEngineService*> ibus_engine_services_;
std::string ibus_address_;
};
// static
void DBusThreadManager::Initialize() {
if (g_dbus_thread_manager) {
LOG(WARNING) << "DBusThreadManager was already initialized";
return;
}
// Determine whether we use stub or real client implementations.
if (base::chromeos::IsRunningOnChromeOS()) {
g_dbus_thread_manager =
new DBusThreadManagerImpl(REAL_DBUS_CLIENT_IMPLEMENTATION);
VLOG(1) << "DBusThreadManager initialized for ChromeOS";
} else {
g_dbus_thread_manager =
new DBusThreadManagerImpl(STUB_DBUS_CLIENT_IMPLEMENTATION);
VLOG(1) << "DBusThreadManager initialized with Stub";
}
}
// static
void DBusThreadManager::InitializeForTesting(
DBusThreadManager* dbus_thread_manager) {
if (g_dbus_thread_manager) {
LOG(WARNING) << "DBusThreadManager was already initialized";
return;
}
CHECK(dbus_thread_manager);
g_dbus_thread_manager = dbus_thread_manager;
VLOG(1) << "DBusThreadManager initialized with test implementation";
}
// static
void DBusThreadManager::InitializeWithStub() {
g_dbus_thread_manager =
new DBusThreadManagerImpl(STUB_DBUS_CLIENT_IMPLEMENTATION);
VLOG(1) << "DBusThreadManager initialized with stub implementation";
}
// static
void DBusThreadManager::Shutdown() {
if (!g_dbus_thread_manager) {
// TODO(satorux): Make it a DCHECK() once it's ready.
LOG(WARNING) << "DBusThreadManager::Shutdown() called with NULL manager";
return;
}
delete g_dbus_thread_manager;
g_dbus_thread_manager = NULL;
VLOG(1) << "DBusThreadManager Shutdown completed";
}
DBusThreadManager::DBusThreadManager() {
}
DBusThreadManager::~DBusThreadManager() {
}
// static
DBusThreadManager* DBusThreadManager::Get() {
CHECK(g_dbus_thread_manager)
<< "DBusThreadManager::Get() called before Initialize()";
return g_dbus_thread_manager;
}
} // namespace chromeos