Index: chromeos/dbus/dbus_thread_manager.cc |
diff --git a/chromeos/dbus/dbus_thread_manager.cc b/chromeos/dbus/dbus_thread_manager.cc |
index e372005dc52663ba1a7723190b1fe63da211a494..784aa0119b05a5ff07a144fc1aea95c90ad37d69 100644 |
--- a/chromeos/dbus/dbus_thread_manager.cc |
+++ b/chromeos/dbus/dbus_thread_manager.cc |
@@ -6,6 +6,8 @@ |
#include "base/command_line.h" |
#include "base/observer_list.h" |
+#include "base/strings/string_split.h" |
+#include "base/strings/string_util.h" |
#include "base/sys_info.h" |
#include "base/threading/thread.h" |
#include "chromeos/chromeos_switches.h" |
@@ -22,6 +24,7 @@ |
#include "chromeos/dbus/cros_disks_client.h" |
#include "chromeos/dbus/cryptohome_client.h" |
#include "chromeos/dbus/dbus_client.h" |
+#include "chromeos/dbus/dbus_client_bundle.h" |
#include "chromeos/dbus/dbus_thread_manager_observer.h" |
#include "chromeos/dbus/debug_daemon_client.h" |
#include "chromeos/dbus/easy_unlock_client.h" |
@@ -30,6 +33,7 @@ |
#include "chromeos/dbus/image_burner_client.h" |
#include "chromeos/dbus/introspectable_client.h" |
#include "chromeos/dbus/lorgnette_manager_client.h" |
+#include "chromeos/dbus/mixed_dbus_thread_manager.h" |
#include "chromeos/dbus/modem_messaging_client.h" |
#include "chromeos/dbus/nfc_adapter_client.h" |
#include "chromeos/dbus/nfc_device_client.h" |
@@ -56,212 +60,73 @@ namespace chromeos { |
static DBusThreadManager* g_dbus_thread_manager = NULL; |
static DBusThreadManager* g_dbus_thread_manager_for_testing = NULL; |
-// The bundle of all D-Bus clients used in DBusThreadManagerImpl. The bundle |
-// is used to delete them at once in the right order before shutting down the |
-// system bus. See also the comment in the destructor of DBusThreadManagerImpl. |
-class DBusClientBundle { |
- public: |
- DBusClientBundle() { |
- const DBusClientImplementationType type = REAL_DBUS_CLIENT_IMPLEMENTATION; |
- |
- bluetooth_adapter_client_.reset(BluetoothAdapterClient::Create()); |
- bluetooth_agent_manager_client_.reset( |
- BluetoothAgentManagerClient::Create()); |
- bluetooth_device_client_.reset(BluetoothDeviceClient::Create()); |
- bluetooth_gatt_characteristic_client_.reset( |
- BluetoothGattCharacteristicClient::Create()); |
- bluetooth_gatt_descriptor_client_.reset( |
- BluetoothGattDescriptorClient::Create()); |
- bluetooth_gatt_manager_client_.reset(BluetoothGattManagerClient::Create()); |
- bluetooth_gatt_service_client_.reset(BluetoothGattServiceClient::Create()); |
- bluetooth_input_client_.reset(BluetoothInputClient::Create()); |
- bluetooth_profile_manager_client_.reset( |
- BluetoothProfileManagerClient::Create()); |
- cras_audio_client_.reset(CrasAudioClient::Create()); |
- cros_disks_client_.reset(CrosDisksClient::Create(type)); |
- cryptohome_client_.reset(CryptohomeClient::Create()); |
- debug_daemon_client_.reset(DebugDaemonClient::Create()); |
- easy_unlock_client_.reset(EasyUnlockClient::Create()); |
- lorgnette_manager_client_.reset(LorgnetteManagerClient::Create()); |
- shill_manager_client_.reset(ShillManagerClient::Create()); |
- shill_device_client_.reset(ShillDeviceClient::Create()); |
- shill_ipconfig_client_.reset(ShillIPConfigClient::Create()); |
- shill_service_client_.reset(ShillServiceClient::Create()); |
- shill_profile_client_.reset(ShillProfileClient::Create()); |
- gsm_sms_client_.reset(GsmSMSClient::Create()); |
- image_burner_client_.reset(ImageBurnerClient::Create()); |
- introspectable_client_.reset(IntrospectableClient::Create()); |
- modem_messaging_client_.reset(ModemMessagingClient::Create()); |
- // Create the NFC clients in the correct order based on their dependencies. |
- nfc_manager_client_.reset(NfcManagerClient::Create()); |
- nfc_adapter_client_.reset( |
- NfcAdapterClient::Create(nfc_manager_client_.get())); |
- nfc_device_client_.reset( |
- NfcDeviceClient::Create(nfc_adapter_client_.get())); |
- nfc_tag_client_.reset(NfcTagClient::Create(nfc_adapter_client_.get())); |
- nfc_record_client_.reset(NfcRecordClient::Create(nfc_device_client_.get(), |
- nfc_tag_client_.get())); |
- permission_broker_client_.reset(PermissionBrokerClient::Create()); |
- power_manager_client_.reset(PowerManagerClient::Create(type)); |
- session_manager_client_.reset(SessionManagerClient::Create(type)); |
- sms_client_.reset(SMSClient::Create()); |
- system_clock_client_.reset(SystemClockClient::Create()); |
- update_engine_client_.reset(UpdateEngineClient::Create(type)); |
- } |
- |
- BluetoothAdapterClient* bluetooth_adapter_client() { |
- return bluetooth_adapter_client_.get(); |
- } |
- BluetoothAgentManagerClient* bluetooth_agent_manager_client() { |
- return bluetooth_agent_manager_client_.get(); |
- } |
- BluetoothDeviceClient* bluetooth_device_client() { |
- return bluetooth_device_client_.get(); |
- } |
- BluetoothGattCharacteristicClient* bluetooth_gatt_characteristic_client() { |
- return bluetooth_gatt_characteristic_client_.get(); |
- } |
- BluetoothGattDescriptorClient* bluetooth_gatt_descriptor_client() { |
- return bluetooth_gatt_descriptor_client_.get(); |
- } |
- BluetoothGattManagerClient* bluetooth_gatt_manager_client() { |
- return bluetooth_gatt_manager_client_.get(); |
- } |
- BluetoothGattServiceClient* bluetooth_gatt_service_client() { |
- return bluetooth_gatt_service_client_.get(); |
- } |
- BluetoothInputClient* bluetooth_input_client() { |
- return bluetooth_input_client_.get(); |
- } |
- BluetoothProfileManagerClient* bluetooth_profile_manager_client() { |
- return bluetooth_profile_manager_client_.get(); |
- } |
- CrasAudioClient* cras_audio_client() { |
- return cras_audio_client_.get(); |
- } |
- CrosDisksClient* cros_disks_client() { |
- return cros_disks_client_.get(); |
- } |
- CryptohomeClient* cryptohome_client() { |
- return cryptohome_client_.get(); |
- } |
- DebugDaemonClient* debug_daemon_client() { |
- return debug_daemon_client_.get(); |
- } |
- EasyUnlockClient* easy_unlock_client() { |
- return easy_unlock_client_.get(); |
- } |
- LorgnetteManagerClient* lorgnette_manager_client() { |
- return lorgnette_manager_client_.get(); |
- } |
- ShillDeviceClient* shill_device_client() { |
- return shill_device_client_.get(); |
- } |
- ShillIPConfigClient* shill_ipconfig_client() { |
- return shill_ipconfig_client_.get(); |
- } |
- ShillManagerClient* shill_manager_client() { |
- return shill_manager_client_.get(); |
- } |
- ShillServiceClient* shill_service_client() { |
- return shill_service_client_.get(); |
- } |
- ShillProfileClient* shill_profile_client() { |
- return shill_profile_client_.get(); |
- } |
- GsmSMSClient* gsm_sms_client() { |
- return gsm_sms_client_.get(); |
- } |
- ImageBurnerClient* image_burner_client() { |
- return image_burner_client_.get(); |
- } |
- IntrospectableClient* introspectable_client() { |
- return introspectable_client_.get(); |
- } |
- ModemMessagingClient* modem_messaging_client() { |
- return modem_messaging_client_.get(); |
- } |
- NfcManagerClient* nfc_manager_client() { |
- return nfc_manager_client_.get(); |
- } |
- NfcAdapterClient* nfc_adapter_client() { |
- return nfc_adapter_client_.get(); |
- } |
- NfcDeviceClient* nfc_device_client() { |
- return nfc_device_client_.get(); |
- } |
- NfcTagClient* nfc_tag_client() { |
- return nfc_tag_client_.get(); |
- } |
- NfcRecordClient* nfc_record_client() { |
- return nfc_record_client_.get(); |
- } |
- PermissionBrokerClient* permission_broker_client() { |
- return permission_broker_client_.get(); |
- } |
- SystemClockClient* system_clock_client() { |
- return system_clock_client_.get(); |
- } |
- PowerManagerClient* power_manager_client() { |
- return power_manager_client_.get(); |
- } |
- SessionManagerClient* session_manager_client() { |
- return session_manager_client_.get(); |
- } |
- SMSClient* sms_client() { |
- return sms_client_.get(); |
- } |
- UpdateEngineClient* update_engine_client() { |
- return update_engine_client_.get(); |
+namespace { |
+ |
+// Command line switch mapping for --dbus-unstub-clients. |
+struct { |
+ const char* param_name; |
+ DBusClientBundle::DBusClientType client_type; |
+} client_type_map[] = { |
+ { "bluetooth", DBusClientBundle::BLUETOOTH }, |
+ { "bluetoothlowenergy", DBusClientBundle::BLUETOOTH_LOW_ENERGY }, |
+ { "cras", DBusClientBundle::CRAS }, |
+ { "crosdisks", DBusClientBundle::CROS_DISKS }, |
+ { "cryptohome", DBusClientBundle::CRYPTOHOME }, |
+ { "debugdaemon", DBusClientBundle::DEBUG_DAEMON }, |
+ { "easyunlock", DBusClientBundle::EASY_UNLOCK }, |
+ { "lorgnettemanager", DBusClientBundle::LORGNETTE_MANAGER }, |
+ { "shill", DBusClientBundle::SHILL }, |
+ { "gsmsms", DBusClientBundle::GSM_SMS }, |
+ { "imageburner", DBusClientBundle::IMAGE_BURNER }, |
+ { "introspectable", DBusClientBundle::INTROSPECTABLE }, |
+ { "modemmessaging", DBusClientBundle::MODEM_MESSAGING }, |
+ { "nfc", DBusClientBundle::NFC }, |
+ { "permissionbroker", DBusClientBundle::PERMISSION_BROKER }, |
+ { "powermanager", DBusClientBundle::POWER_MANAGER }, |
+ { "powerpolicy", DBusClientBundle::POWER_POLICY }, |
+ { "sessionmanager", DBusClientBundle::SESSION_MANAGER }, |
+ { "sms", DBusClientBundle::SMS }, |
+ { "systemclock", DBusClientBundle::SYSTEM_CLOCK }, |
+ { "updateengine", DBusClientBundle::UPDATE_ENGINE }, |
+}; |
+ |
+// Parses single command line param value for dbus subsystem and returns its |
+// enum representation. DBusClientType::UNKWNOWN is returned if |client_type| |
+// does not match any known dbus client. |
+DBusClientBundle::DBusClientType GetDBusClientType( |
+ const std::string& client_type) { |
+ for (size_t i = 0; i < arraysize(client_type_map); i++) { |
+ if (LowerCaseEqualsASCII(client_type, client_type_map[i].param_name)) |
+ return client_type_map[i].client_type; |
} |
+ return DBusClientBundle::UNKNOWN; |
+} |
- private: |
- scoped_ptr<BluetoothAdapterClient> bluetooth_adapter_client_; |
- scoped_ptr<BluetoothAgentManagerClient> bluetooth_agent_manager_client_; |
- scoped_ptr<BluetoothDeviceClient> bluetooth_device_client_; |
- scoped_ptr<BluetoothGattCharacteristicClient> |
- bluetooth_gatt_characteristic_client_; |
- scoped_ptr<BluetoothGattDescriptorClient> bluetooth_gatt_descriptor_client_; |
- scoped_ptr<BluetoothGattManagerClient> bluetooth_gatt_manager_client_; |
- scoped_ptr<BluetoothGattServiceClient> bluetooth_gatt_service_client_; |
- scoped_ptr<BluetoothInputClient> bluetooth_input_client_; |
- scoped_ptr<BluetoothProfileManagerClient> bluetooth_profile_manager_client_; |
- scoped_ptr<CrasAudioClient> cras_audio_client_; |
- scoped_ptr<CrosDisksClient> cros_disks_client_; |
- scoped_ptr<CryptohomeClient> cryptohome_client_; |
- scoped_ptr<DebugDaemonClient> debug_daemon_client_; |
- scoped_ptr<EasyUnlockClient> easy_unlock_client_; |
- scoped_ptr<LorgnetteManagerClient> lorgnette_manager_client_; |
- scoped_ptr<ShillDeviceClient> shill_device_client_; |
- scoped_ptr<ShillIPConfigClient> shill_ipconfig_client_; |
- scoped_ptr<ShillManagerClient> shill_manager_client_; |
- scoped_ptr<ShillServiceClient> shill_service_client_; |
- scoped_ptr<ShillProfileClient> shill_profile_client_; |
- scoped_ptr<GsmSMSClient> gsm_sms_client_; |
- scoped_ptr<ImageBurnerClient> image_burner_client_; |
- scoped_ptr<IntrospectableClient> introspectable_client_; |
- scoped_ptr<ModemMessagingClient> modem_messaging_client_; |
- // The declaration order for NFC client objects is important. See |
- // DBusThreadManager::CreateDefaultClients for the dependencies. |
- scoped_ptr<NfcManagerClient> nfc_manager_client_; |
- scoped_ptr<NfcAdapterClient> nfc_adapter_client_; |
- scoped_ptr<NfcDeviceClient> nfc_device_client_; |
- scoped_ptr<NfcTagClient> nfc_tag_client_; |
- scoped_ptr<NfcRecordClient> nfc_record_client_; |
- scoped_ptr<PermissionBrokerClient> permission_broker_client_; |
- scoped_ptr<SystemClockClient> system_clock_client_; |
- scoped_ptr<PowerManagerClient> power_manager_client_; |
- scoped_ptr<SessionManagerClient> session_manager_client_; |
- scoped_ptr<SMSClient> sms_client_; |
- scoped_ptr<UpdateEngineClient> update_engine_client_; |
- |
- DISALLOW_COPY_AND_ASSIGN(DBusClientBundle); |
-}; |
+// Parses command line param values for dbus subsystem that should be |
+// un-stubbed. |
+int ParseUnstubList(const std::string& unstub_list) { |
+ int unstub_mask = 0; |
+ std::vector<std::string> unstub_components; |
+ base::SplitString(unstub_list, ',', &unstub_components); |
+ for (std::vector<std::string>::const_iterator iter = |
+ unstub_components.begin(); |
+ iter != unstub_components.end(); ++iter) { |
+ DBusClientBundle::DBusClientType client = GetDBusClientType(*iter); |
+ if (client != DBusClientBundle::UNKNOWN) { |
+ LOG(WARNING) << "Unstubbing dbus client for " << *iter; |
+ unstub_mask |= client; |
+ } |
+ } |
+ |
+ return unstub_mask; |
+} |
+ |
+} // namespace |
// The DBusThreadManager implementation used in production. |
class DBusThreadManagerImpl : public DBusThreadManager { |
public: |
- DBusThreadManagerImpl() { |
+ explicit DBusThreadManagerImpl(int client_mask) : client_mask_(client_mask) { |
// Create the D-Bus thread. |
base::Thread::Options thread_options; |
thread_options.message_loop_type = base::MessageLoop::TYPE_IO; |
@@ -462,8 +327,9 @@ class DBusThreadManagerImpl : public DBusThreadManager { |
// Constructs all clients and stores them in the respective *_client_ member |
// variable. |
void CreateDefaultClients() { |
- client_bundle_.reset(new DBusClientBundle); |
- power_policy_controller_.reset(new PowerPolicyController); |
+ client_bundle_.reset(new DBusClientBundle(client_mask_)); |
+ if (client_mask_ & DBusClientBundle::POWER_POLICY) |
+ power_policy_controller_.reset(new PowerPolicyController); |
} |
// Note: Keep this before other members so they can call AddObserver() in |
@@ -474,10 +340,12 @@ class DBusThreadManagerImpl : public DBusThreadManager { |
scoped_refptr<dbus::Bus> system_bus_; |
scoped_ptr<DBusClientBundle> client_bundle_; |
scoped_ptr<PowerPolicyController> power_policy_controller_; |
+ int client_mask_; |
DISALLOW_COPY_AND_ASSIGN(DBusThreadManagerImpl); |
}; |
+ |
// static |
void DBusThreadManager::Initialize() { |
// If we initialize DBusThreadManager twice we may also be shutting it down |
@@ -491,15 +359,20 @@ void DBusThreadManager::Initialize() { |
return; |
} |
- // Determine whether we use stub or real client implementations. |
- if (!base::SysInfo::IsRunningOnChromeOS() || |
+ bool use_dbus_stub = !base::SysInfo::IsRunningOnChromeOS() || |
CommandLine::ForCurrentProcess()->HasSwitch( |
- chromeos::switches::kDbusStub)) { |
- InitializeWithStub(); |
+ chromeos::switches::kDbusStub); |
+ bool force_unstub_clients = CommandLine::ForCurrentProcess()->HasSwitch( |
+ chromeos::switches::kDbusUnstubClients); |
+ // Determine whether we use stub or real client implementations. |
+ if (force_unstub_clients) { |
+ InitializeThreadManagerWithPartialStub( |
+ CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
+ chromeos::switches::kDbusUnstubClients)); |
+ } else if (use_dbus_stub) { |
+ InitializeThreadManagerWithStub(); |
} else { |
- g_dbus_thread_manager = new DBusThreadManagerImpl; |
- InitializeClients(); |
- VLOG(1) << "DBusThreadManager initialized for Chrome OS"; |
+ InitializeThreadManager(); |
} |
} |
@@ -519,7 +392,40 @@ void DBusThreadManager::InitializeForTesting( |
} |
// static |
-void DBusThreadManager::InitializeWithStub() { |
+void DBusThreadManager::InitializeThreadManagerWithPartialStub( |
+ const std::string& unstub_clients) { |
+ // If we initialize DBusThreadManager twice we may also be shutting it down |
+ // early; do not allow that. |
+ CHECK(g_dbus_thread_manager == NULL); |
+ |
+ int unstub_mask = ParseUnstubList(unstub_clients); |
+ // We should have something parsed correctly here. |
+ if (unstub_mask == 0) { |
+ LOG(FATAL) << "Switch values for --" |
+ << chromeos::switches::kDbusUnstubClients |
+ << " cannot be parsed: " |
+ << unstub_clients; |
+ } |
+ DBusThreadManager* real_thread_manager = |
+ new DBusThreadManagerImpl(unstub_mask); |
+ FakeDBusThreadManager* fake_dbus_thread_manager = new FakeDBusThreadManager; |
+ fake_dbus_thread_manager->SetFakeClients(); |
+ VLOG(1) << "DBusThreadManager initialized for mixed runtime environment"; |
+ g_dbus_thread_manager = new MixedDBusThreadManager(unstub_mask, |
+ real_thread_manager, |
+ fake_dbus_thread_manager); |
+ InitializeClients(); |
+} |
+ |
+// static |
+void DBusThreadManager::InitializeThreadManager() { |
+ g_dbus_thread_manager = new DBusThreadManagerImpl(DBusClientBundle::All); |
+ InitializeClients(); |
+ VLOG(1) << "DBusThreadManager initialized for Chrome OS"; |
+} |
+ |
+// static |
+void DBusThreadManager::InitializeThreadManagerWithStub() { |
// If we initialize DBusThreadManager twice we may also be shutting it down |
// early; do not allow that. |
CHECK(g_dbus_thread_manager == NULL); |