diff options
Diffstat (limited to 'device/bluetooth')
112 files changed, 15777 insertions, 898 deletions
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn index 25dfc44..5edb17c 100644 --- a/device/bluetooth/BUILD.gn +++ b/device/bluetooth/BUILD.gn @@ -161,6 +161,95 @@ component("bluetooth") { if (is_win) { libs = [ "setupapi.lib" ] } + + # This block will also build for Linux once we write the linux + # implementation of BluezDbusManager. + if (is_chromeos) { + defines += [ "DEVICE_BLUETOOTH_IMPLEMENTATION" ] + sources += [ + "dbus/bluetooth_adapter_client.cc", + "dbus/bluetooth_adapter_client.h", + "dbus/bluetooth_agent_manager_client.cc", + "dbus/bluetooth_agent_manager_client.h", + "dbus/bluetooth_agent_service_provider.cc", + "dbus/bluetooth_agent_service_provider.h", + "dbus/bluetooth_dbus_client_bundle.cc", + "dbus/bluetooth_dbus_client_bundle.h", + "dbus/bluetooth_device_client.cc", + "dbus/bluetooth_device_client.h", + "dbus/bluetooth_gatt_characteristic_client.cc", + "dbus/bluetooth_gatt_characteristic_client.h", + "dbus/bluetooth_gatt_characteristic_service_provider.cc", + "dbus/bluetooth_gatt_characteristic_service_provider.h", + "dbus/bluetooth_gatt_descriptor_client.cc", + "dbus/bluetooth_gatt_descriptor_client.h", + "dbus/bluetooth_gatt_descriptor_service_provider.cc", + "dbus/bluetooth_gatt_descriptor_service_provider.h", + "dbus/bluetooth_gatt_manager_client.cc", + "dbus/bluetooth_gatt_manager_client.h", + "dbus/bluetooth_gatt_service_client.cc", + "dbus/bluetooth_gatt_service_client.h", + "dbus/bluetooth_gatt_service_service_provider.cc", + "dbus/bluetooth_gatt_service_service_provider.h", + "dbus/bluetooth_input_client.cc", + "dbus/bluetooth_input_client.h", + "dbus/bluetooth_le_advertisement_service_provider.cc", + "dbus/bluetooth_le_advertisement_service_provider.h", + "dbus/bluetooth_le_advertising_manager_client.cc", + "dbus/bluetooth_le_advertising_manager_client.h", + "dbus/bluetooth_media_client.cc", + "dbus/bluetooth_media_client.h", + "dbus/bluetooth_media_endpoint_service_provider.cc", + "dbus/bluetooth_media_endpoint_service_provider.h", + "dbus/bluetooth_media_transport_client.cc", + "dbus/bluetooth_media_transport_client.h", + "dbus/bluetooth_profile_manager_client.cc", + "dbus/bluetooth_profile_manager_client.h", + "dbus/bluetooth_profile_service_provider.cc", + "dbus/bluetooth_profile_service_provider.h", + "dbus/bluez_dbus_client.h", + "dbus/bluez_dbus_manager.cc", + "dbus/bluez_dbus_manager.h", + "dbus/fake_bluetooth_adapter_client.cc", + "dbus/fake_bluetooth_adapter_client.h", + "dbus/fake_bluetooth_agent_manager_client.cc", + "dbus/fake_bluetooth_agent_manager_client.h", + "dbus/fake_bluetooth_agent_service_provider.cc", + "dbus/fake_bluetooth_agent_service_provider.h", + "dbus/fake_bluetooth_device_client.cc", + "dbus/fake_bluetooth_device_client.h", + "dbus/fake_bluetooth_gatt_characteristic_client.cc", + "dbus/fake_bluetooth_gatt_characteristic_client.h", + "dbus/fake_bluetooth_gatt_characteristic_service_provider.cc", + "dbus/fake_bluetooth_gatt_characteristic_service_provider.h", + "dbus/fake_bluetooth_gatt_descriptor_client.cc", + "dbus/fake_bluetooth_gatt_descriptor_client.h", + "dbus/fake_bluetooth_gatt_descriptor_service_provider.cc", + "dbus/fake_bluetooth_gatt_descriptor_service_provider.h", + "dbus/fake_bluetooth_gatt_manager_client.cc", + "dbus/fake_bluetooth_gatt_manager_client.h", + "dbus/fake_bluetooth_gatt_service_client.cc", + "dbus/fake_bluetooth_gatt_service_client.h", + "dbus/fake_bluetooth_gatt_service_service_provider.cc", + "dbus/fake_bluetooth_gatt_service_service_provider.h", + "dbus/fake_bluetooth_input_client.cc", + "dbus/fake_bluetooth_input_client.h", + "dbus/fake_bluetooth_le_advertisement_service_provider.cc", + "dbus/fake_bluetooth_le_advertisement_service_provider.h", + "dbus/fake_bluetooth_le_advertising_manager_client.cc", + "dbus/fake_bluetooth_le_advertising_manager_client.h", + "dbus/fake_bluetooth_media_client.cc", + "dbus/fake_bluetooth_media_client.h", + "dbus/fake_bluetooth_media_endpoint_service_provider.cc", + "dbus/fake_bluetooth_media_endpoint_service_provider.h", + "dbus/fake_bluetooth_media_transport_client.cc", + "dbus/fake_bluetooth_media_transport_client.h", + "dbus/fake_bluetooth_profile_manager_client.cc", + "dbus/fake_bluetooth_profile_manager_client.h", + "dbus/fake_bluetooth_profile_service_provider.cc", + "dbus/fake_bluetooth_profile_service_provider.h", + ] + } } static_library("mocks") { diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp index f862660..90306d1 100644 --- a/device/bluetooth/bluetooth.gyp +++ b/device/bluetooth/bluetooth.gyp @@ -133,6 +133,96 @@ 'bluetooth_uuid.h', ], 'conditions': [ + # This block will also build for Linux once we write the linux + # implementation of BluezDbusManager. + ['chromeos==1', { + 'defines': [ + 'DEVICE_BLUETOOTH_IMPLEMENTATION', + ], + 'sources': [ + 'dbus/bluetooth_adapter_client.cc', + 'dbus/bluetooth_adapter_client.h', + 'dbus/bluetooth_le_advertising_manager_client.cc', + 'dbus/bluetooth_le_advertising_manager_client.h', + 'dbus/bluetooth_le_advertisement_service_provider.cc', + 'dbus/bluetooth_le_advertisement_service_provider.h', + 'dbus/bluetooth_agent_manager_client.cc', + 'dbus/bluetooth_agent_manager_client.h', + 'dbus/bluetooth_agent_service_provider.cc', + 'dbus/bluetooth_agent_service_provider.h', + 'dbus/bluetooth_dbus_client_bundle.cc', + 'dbus/bluetooth_dbus_client_bundle.h', + 'dbus/bluetooth_device_client.cc', + 'dbus/bluetooth_device_client.h', + 'dbus/bluetooth_gatt_characteristic_client.cc', + 'dbus/bluetooth_gatt_characteristic_client.h', + 'dbus/bluetooth_gatt_characteristic_service_provider.cc', + 'dbus/bluetooth_gatt_characteristic_service_provider.h', + 'dbus/bluetooth_gatt_descriptor_client.cc', + 'dbus/bluetooth_gatt_descriptor_client.h', + 'dbus/bluetooth_gatt_descriptor_service_provider.cc', + 'dbus/bluetooth_gatt_descriptor_service_provider.h', + 'dbus/bluetooth_gatt_manager_client.cc', + 'dbus/bluetooth_gatt_manager_client.h', + 'dbus/bluetooth_gatt_service_client.cc', + 'dbus/bluetooth_gatt_service_client.h', + 'dbus/bluetooth_gatt_service_service_provider.cc', + 'dbus/bluetooth_gatt_service_service_provider.h', + 'dbus/bluetooth_input_client.cc', + 'dbus/bluetooth_input_client.h', + 'dbus/bluetooth_media_client.cc', + 'dbus/bluetooth_media_client.h', + 'dbus/bluetooth_media_endpoint_service_provider.cc', + 'dbus/bluetooth_media_endpoint_service_provider.h', + 'dbus/bluetooth_media_transport_client.cc', + 'dbus/bluetooth_media_transport_client.h', + 'dbus/bluetooth_profile_manager_client.cc', + 'dbus/bluetooth_profile_manager_client.h', + 'dbus/bluetooth_profile_service_provider.cc', + 'dbus/bluetooth_profile_service_provider.h', + 'dbus/bluez_dbus_client.h', + 'dbus/bluez_dbus_manager.cc', + 'dbus/bluez_dbus_manager.h', + 'dbus/fake_bluetooth_adapter_client.cc', + 'dbus/fake_bluetooth_adapter_client.h', + 'dbus/fake_bluetooth_le_advertising_manager_client.cc', + 'dbus/fake_bluetooth_le_advertising_manager_client.h', + 'dbus/fake_bluetooth_le_advertisement_service_provider.cc', + 'dbus/fake_bluetooth_le_advertisement_service_provider.h', + 'dbus/fake_bluetooth_agent_manager_client.cc', + 'dbus/fake_bluetooth_agent_manager_client.h', + 'dbus/fake_bluetooth_agent_service_provider.cc', + 'dbus/fake_bluetooth_agent_service_provider.h', + 'dbus/fake_bluetooth_device_client.cc', + 'dbus/fake_bluetooth_device_client.h', + 'dbus/fake_bluetooth_gatt_characteristic_client.cc', + 'dbus/fake_bluetooth_gatt_characteristic_client.h', + 'dbus/fake_bluetooth_gatt_characteristic_service_provider.cc', + 'dbus/fake_bluetooth_gatt_characteristic_service_provider.h', + 'dbus/fake_bluetooth_gatt_descriptor_client.cc', + 'dbus/fake_bluetooth_gatt_descriptor_client.h', + 'dbus/fake_bluetooth_gatt_descriptor_service_provider.cc', + 'dbus/fake_bluetooth_gatt_descriptor_service_provider.h', + 'dbus/fake_bluetooth_gatt_manager_client.cc', + 'dbus/fake_bluetooth_gatt_manager_client.h', + 'dbus/fake_bluetooth_gatt_service_client.cc', + 'dbus/fake_bluetooth_gatt_service_client.h', + 'dbus/fake_bluetooth_gatt_service_service_provider.cc', + 'dbus/fake_bluetooth_gatt_service_service_provider.h', + 'dbus/fake_bluetooth_input_client.cc', + 'dbus/fake_bluetooth_input_client.h', + 'dbus/fake_bluetooth_media_client.cc', + 'dbus/fake_bluetooth_media_client.h', + 'dbus/fake_bluetooth_media_endpoint_service_provider.cc', + 'dbus/fake_bluetooth_media_endpoint_service_provider.h', + 'dbus/fake_bluetooth_media_transport_client.cc', + 'dbus/fake_bluetooth_media_transport_client.h', + 'dbus/fake_bluetooth_profile_manager_client.cc', + 'dbus/fake_bluetooth_profile_manager_client.h', + 'dbus/fake_bluetooth_profile_service_provider.cc', + 'dbus/fake_bluetooth_profile_service_provider.h', + ], + }], ['chromeos==1', { 'dependencies': [ '../../build/linux/system.gyp:dbus', diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc index 70ec7fb..55d0bef 100644 --- a/device/bluetooth/bluetooth_adapter_chromeos.cc +++ b/device/bluetooth/bluetooth_adapter_chromeos.cc @@ -13,12 +13,6 @@ #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" -#include "chromeos/dbus/bluetooth_adapter_client.h" -#include "chromeos/dbus/bluetooth_agent_manager_client.h" -#include "chromeos/dbus/bluetooth_agent_service_provider.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_input_client.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/system/devicetype.h" #include "device/bluetooth/bluetooth_adapter_profile_chromeos.h" #include "device/bluetooth/bluetooth_advertisement_chromeos.h" @@ -33,6 +27,12 @@ #include "device/bluetooth/bluetooth_socket_chromeos.h" #include "device/bluetooth/bluetooth_socket_thread.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/bluetooth/dbus/bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h" +#include "device/bluetooth/dbus/bluetooth_device_client.h" +#include "device/bluetooth/dbus/bluetooth_input_client.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" #include "third_party/cros_system_api/dbus/service_constants.h" using device::BluetoothAdapter; @@ -61,9 +61,9 @@ void OnUnregisterAgentError(const std::string& error_name, UMABluetoothDiscoverySessionOutcome TranslateDiscoveryErrorToUMA( const std::string& error_name) { - if (error_name == chromeos::BluetoothAdapterClient::kUnknownAdapterError) { + if (error_name == bluez::BluetoothAdapterClient::kUnknownAdapterError) { return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_UNKNOWN_ADAPTER; - } else if (error_name == chromeos::BluetoothAdapterClient::kNoResponseError) { + } else if (error_name == bluez::BluetoothAdapterClient::kNoResponseError) { return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_NO_RESPONSE; } else if (error_name == bluetooth_device::kErrorInProgress) { return UMABluetoothDiscoverySessionOutcome::CHROMEOS_DBUS_IN_PROGRESS; @@ -100,9 +100,9 @@ base::WeakPtr<BluetoothAdapter> BluetoothAdapterChromeOS::CreateAdapter() { void BluetoothAdapterChromeOS::Shutdown() { if (dbus_is_shutdown_) return; - DCHECK(DBusThreadManager::IsInitialized()) + DCHECK(bluez::BluezDBusManager::IsInitialized()) << "Call BluetoothAdapterFactory::Shutdown() before " - "DBusThreadManager::Shutdown()."; + "BluezDBusManager::Shutdown()."; if (IsPresent()) RemoveAdapter(); // Also deletes devices_. @@ -115,14 +115,19 @@ void BluetoothAdapterChromeOS::Shutdown() { delete it.second; profile_queues_.clear(); - DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveObserver(this); - DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this); - DBusThreadManager::Get()->GetBluetoothInputClient()->RemoveObserver(this); + bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->RemoveObserver( + this); + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->RemoveObserver( + this); + bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->RemoveObserver( + this); VLOG(1) << "Unregistering pairing agent"; - DBusThreadManager::Get()->GetBluetoothAgentManagerClient()->UnregisterAgent( - dbus::ObjectPath(kAgentPath), base::Bind(&base::DoNothing), - base::Bind(&OnUnregisterAgentError)); + bluez::BluezDBusManager::Get() + ->GetBluetoothAgentManagerClient() + ->UnregisterAgent(dbus::ObjectPath(kAgentPath), + base::Bind(&base::DoNothing), + base::Bind(&OnUnregisterAgentError)); agent_.reset(); dbus_is_shutdown_ = true; @@ -136,18 +141,20 @@ BluetoothAdapterChromeOS::BluetoothAdapterChromeOS() ui_task_runner_ = base::ThreadTaskRunnerHandle::Get(); socket_thread_ = device::BluetoothSocketThread::Get(); - DBusThreadManager::Get()->GetBluetoothAdapterClient()->AddObserver(this); - DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this); - DBusThreadManager::Get()->GetBluetoothInputClient()->AddObserver(this); + bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->AddObserver( + this); + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->AddObserver(this); + bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->AddObserver(this); // Register the pairing agent. - dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); - agent_.reset(BluetoothAgentServiceProvider::Create( + dbus::Bus* system_bus = bluez::BluezDBusManager::Get()->GetSystemBus(); + agent_.reset(bluez::BluetoothAgentServiceProvider::Create( system_bus, dbus::ObjectPath(kAgentPath), this)); DCHECK(agent_.get()); - std::vector<dbus::ObjectPath> object_paths = - DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetAdapters(); + std::vector<dbus::ObjectPath> object_paths = bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->GetAdapters(); if (!object_paths.empty()) { VLOG(1) << object_paths.size() << " Bluetooth adapter(s) available."; @@ -163,9 +170,10 @@ std::string BluetoothAdapterChromeOS::GetAddress() const { if (!IsPresent()) return std::string(); - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties( - object_path_); + bluez::BluetoothAdapterClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->GetProperties(object_path_); DCHECK(properties); return BluetoothDevice::CanonicalizeAddress(properties->address.value()); @@ -175,9 +183,10 @@ std::string BluetoothAdapterChromeOS::GetName() const { if (!IsPresent()) return std::string(); - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties( - object_path_); + bluez::BluetoothAdapterClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->GetProperties(object_path_); DCHECK(properties); return properties->alias.value(); @@ -191,7 +200,7 @@ void BluetoothAdapterChromeOS::SetName(const std::string& name, return; } - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothAdapterClient() ->GetProperties(object_path_) ->alias.Set( @@ -212,9 +221,10 @@ bool BluetoothAdapterChromeOS::IsPowered() const { if (!IsPresent()) return false; - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties( - object_path_); + bluez::BluetoothAdapterClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->GetProperties(object_path_); return properties->powered.value(); } @@ -228,7 +238,7 @@ void BluetoothAdapterChromeOS::SetPowered( return; } - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothAdapterClient() ->GetProperties(object_path_) ->powered.Set( @@ -241,9 +251,10 @@ bool BluetoothAdapterChromeOS::IsDiscoverable() const { if (!IsPresent()) return false; - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties( - object_path_); + bluez::BluetoothAdapterClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->GetProperties(object_path_); return properties->discoverable.value(); } @@ -257,7 +268,7 @@ void BluetoothAdapterChromeOS::SetDiscoverable( return; } - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothAdapterClient() ->GetProperties(object_path_) ->discoverable.Set( @@ -270,9 +281,10 @@ bool BluetoothAdapterChromeOS::IsDiscovering() const { if (!IsPresent()) return false; - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties( - object_path_); + bluez::BluetoothAdapterClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->GetProperties(object_path_); return properties->discovering.value(); } @@ -377,9 +389,10 @@ void BluetoothAdapterChromeOS::AdapterPropertyChanged( return; DCHECK(IsPresent()); - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties( - object_path_); + bluez::BluetoothAdapterClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->GetProperties(object_path_); if (property_name == properties->powered.name()) { PoweredChanged(properties->powered.value()); @@ -392,9 +405,9 @@ void BluetoothAdapterChromeOS::AdapterPropertyChanged( void BluetoothAdapterChromeOS::DeviceAdded( const dbus::ObjectPath& object_path) { - DCHECK(DBusThreadManager::Get()); - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + DCHECK(bluez::BluezDBusManager::Get()); + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path); if (!properties || properties->adapter.value() != object_path_) return; @@ -438,8 +451,8 @@ void BluetoothAdapterChromeOS::DevicePropertyChanged( if (!device_chromeos) return; - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path); if (property_name == properties->address.name()) { @@ -513,8 +526,8 @@ void BluetoothAdapterChromeOS::InputPropertyChanged( if (!device_chromeos) return; - BluetoothInputClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothInputClient()->GetProperties( + bluez::BluetoothInputClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->GetProperties( object_path); // Properties structure can be removed, which triggers a change in the @@ -672,7 +685,7 @@ void BluetoothAdapterChromeOS::Cancel() { void BluetoothAdapterChromeOS::OnRegisterAgent() { VLOG(1) << "Pairing agent registered, requesting to be made default"; - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothAgentManagerClient() ->RequestDefaultAgent( dbus::ObjectPath(kAgentPath), @@ -765,19 +778,22 @@ void BluetoothAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) { VLOG(1) << object_path_.value() << ": using adapter."; VLOG(1) << "Registering pairing agent"; - DBusThreadManager::Get()->GetBluetoothAgentManagerClient()->RegisterAgent( - dbus::ObjectPath(kAgentPath), - bluetooth_agent_manager::kKeyboardDisplayCapability, - base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgent, - weak_ptr_factory_.GetWeakPtr()), - base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgentError, - weak_ptr_factory_.GetWeakPtr())); + bluez::BluezDBusManager::Get() + ->GetBluetoothAgentManagerClient() + ->RegisterAgent( + dbus::ObjectPath(kAgentPath), + bluetooth_agent_manager::kKeyboardDisplayCapability, + base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgent, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAdapterChromeOS::OnRegisterAgentError, + weak_ptr_factory_.GetWeakPtr())); SetDefaultAdapterName(); - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties( - object_path_); + bluez::BluetoothAdapterClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->GetProperties(object_path_); PresentChanged(true); @@ -789,7 +805,7 @@ void BluetoothAdapterChromeOS::SetAdapter(const dbus::ObjectPath& object_path) { DiscoveringChanged(true); std::vector<dbus::ObjectPath> device_paths = - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothDeviceClient() ->GetDevicesForAdapter(object_path_); @@ -828,9 +844,10 @@ void BluetoothAdapterChromeOS::RemoveAdapter() { DCHECK(IsPresent()); VLOG(1) << object_path_.value() << ": adapter removed."; - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()->GetProperties( - object_path_); + bluez::BluetoothAdapterClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->GetProperties(object_path_); object_path_ = dbus::ObjectPath(""); @@ -1025,8 +1042,8 @@ void BluetoothAdapterChromeOS::NotifyGattDescriptorValueChanged( void BluetoothAdapterChromeOS::UseProfile( const BluetoothUUID& uuid, const dbus::ObjectPath& device_path, - const BluetoothProfileManagerClient::Options& options, - BluetoothProfileServiceProvider::Delegate* delegate, + const bluez::BluetoothProfileManagerClient::Options& options, + bluez::BluetoothProfileServiceProvider::Delegate* delegate, const ProfileRegisteredCallback& success_callback, const ErrorCompletionCallback& error_callback) { DCHECK(delegate); @@ -1097,7 +1114,7 @@ void BluetoothAdapterChromeOS::OnRegisterProfile( void BluetoothAdapterChromeOS::SetProfileDelegate( const BluetoothUUID& uuid, const dbus::ObjectPath& device_path, - BluetoothProfileServiceProvider::Delegate* delegate, + bluez::BluetoothProfileServiceProvider::Delegate* delegate, const ProfileRegisteredCallback& success_callback, const ErrorCompletionCallback& error_callback) { if (profiles_.find(uuid) == profiles_.end()) { @@ -1140,7 +1157,7 @@ void BluetoothAdapterChromeOS::OnSetDiscoverable( // Set the discoverable_timeout property to zero so the adapter remains // discoverable forever. - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothAdapterClient() ->GetProperties(object_path_) ->discoverable_timeout.Set( @@ -1214,7 +1231,7 @@ void BluetoothAdapterChromeOS::AddDiscoverySession( // This is the first request to start device discovery. discovery_request_pending_ = true; - DBusThreadManager::Get()->GetBluetoothAdapterClient()->StartDiscovery( + bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StartDiscovery( object_path_, base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery, weak_ptr_factory_.GetWeakPtr(), callback, error_callback), @@ -1268,7 +1285,7 @@ void BluetoothAdapterChromeOS::RemoveDiscoverySession( // discovery. DCHECK_EQ(num_discovery_sessions_, 1); discovery_request_pending_ = true; - DBusThreadManager::Get()->GetBluetoothAdapterClient()->StopDiscovery( + bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StopDiscovery( object_path_, base::Bind(&BluetoothAdapterChromeOS::OnStopDiscovery, weak_ptr_factory_.GetWeakPtr(), callback), base::Bind(&BluetoothAdapterChromeOS::OnStopDiscoveryError, @@ -1301,7 +1318,7 @@ void BluetoothAdapterChromeOS::SetDiscoveryFilter( current_filter_.reset(discovery_filter.release()); - chromeos::BluetoothAdapterClient::DiscoveryFilter dbus_discovery_filter; + bluez::BluetoothAdapterClient::DiscoveryFilter dbus_discovery_filter; if (current_filter_.get()) { uint16_t pathloss; @@ -1336,12 +1353,14 @@ void BluetoothAdapterChromeOS::SetDiscoveryFilter( } } - DBusThreadManager::Get()->GetBluetoothAdapterClient()->SetDiscoveryFilter( - object_path_, dbus_discovery_filter, - base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilter, - weak_ptr_factory_.GetWeakPtr(), callback, error_callback), - base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilterError, - weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); + bluez::BluezDBusManager::Get() + ->GetBluetoothAdapterClient() + ->SetDiscoveryFilter( + object_path_, dbus_discovery_filter, + base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilter, + weak_ptr_factory_.GetWeakPtr(), callback, error_callback), + base::Bind(&BluetoothAdapterChromeOS::OnSetDiscoveryFilterError, + weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); } void BluetoothAdapterChromeOS::OnStartDiscovery( @@ -1431,7 +1450,7 @@ void BluetoothAdapterChromeOS::OnPreSetDiscoveryFilter( DCHECK(discovery_request_pending_); DCHECK_EQ(num_discovery_sessions_, 0); - DBusThreadManager::Get()->GetBluetoothAdapterClient()->StartDiscovery( + bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->StartDiscovery( object_path_, base::Bind(&BluetoothAdapterChromeOS::OnStartDiscovery, weak_ptr_factory_.GetWeakPtr(), callback, error_callback), diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h index 46c634f..53b271f 100644 --- a/device/bluetooth/bluetooth_adapter_chromeos.h +++ b/device/bluetooth/bluetooth_adapter_chromeos.h @@ -12,18 +12,18 @@ #include <vector> #include "base/memory/weak_ptr.h" -#include "chromeos/dbus/bluetooth_adapter_client.h" -#include "chromeos/dbus/bluetooth_agent_service_provider.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_input_client.h" -#include "chromeos/dbus/bluetooth_profile_manager_client.h" -#include "chromeos/dbus/bluetooth_profile_service_provider.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_audio_sink.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_discovery_session.h" #include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h" +#include "device/bluetooth/dbus/bluetooth_device_client.h" +#include "device/bluetooth/dbus/bluetooth_input_client.h" +#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" namespace base { class SequencedTaskRunner; @@ -60,10 +60,10 @@ class BluetoothRemoteGattServiceChromeOS; // BluetoothChromeOSTest, Shutdown. class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS : public device::BluetoothAdapter, - public chromeos::BluetoothAdapterClient::Observer, - public chromeos::BluetoothDeviceClient::Observer, - public chromeos::BluetoothInputClient::Observer, - public chromeos::BluetoothAgentServiceProvider::Delegate { + public bluez::BluetoothAdapterClient::Observer, + public bluez::BluetoothDeviceClient::Observer, + public bluez::BluetoothInputClient::Observer, + public bluez::BluetoothAgentServiceProvider::Delegate { public: typedef base::Callback<void(const std::string& error_message)> ErrorCompletionCallback; @@ -157,8 +157,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS // |error_callback| will be called. void UseProfile(const device::BluetoothUUID& uuid, const dbus::ObjectPath& device_path, - const BluetoothProfileManagerClient::Options& options, - BluetoothProfileServiceProvider::Delegate* delegate, + const bluez::BluetoothProfileManagerClient::Options& options, + bluez::BluetoothProfileServiceProvider::Delegate* delegate, const ProfileRegisteredCallback& success_callback, const ErrorCompletionCallback& error_callback); @@ -194,23 +194,23 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS BluetoothAdapterChromeOS(); ~BluetoothAdapterChromeOS() override; - // BluetoothAdapterClient::Observer override. + // bluez::BluetoothAdapterClient::Observer override. void AdapterAdded(const dbus::ObjectPath& object_path) override; void AdapterRemoved(const dbus::ObjectPath& object_path) override; void AdapterPropertyChanged(const dbus::ObjectPath& object_path, const std::string& property_name) override; - // BluetoothDeviceClient::Observer override. + // bluez::BluetoothDeviceClient::Observer override. void DeviceAdded(const dbus::ObjectPath& object_path) override; void DeviceRemoved(const dbus::ObjectPath& object_path) override; void DevicePropertyChanged(const dbus::ObjectPath& object_path, const std::string& property_name) override; - // BluetoothInputClient::Observer override. + // bluez::BluetoothInputClient::Observer override. void InputPropertyChanged(const dbus::ObjectPath& object_path, const std::string& property_name) override; - // BluetoothAgentServiceProvider::Delegate override. + // bluez::BluetoothAgentServiceProvider::Delegate override. void Released() override; void RequestPinCode(const dbus::ObjectPath& device_path, const PinCodeCallback& callback) override; @@ -333,11 +333,12 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS void OnRegisterProfile(const device::BluetoothUUID& uuid, scoped_ptr<BluetoothAdapterProfileChromeOS> profile); - void SetProfileDelegate(const device::BluetoothUUID& uuid, - const dbus::ObjectPath& device_path, - BluetoothProfileServiceProvider::Delegate* delegate, - const ProfileRegisteredCallback& success_callback, - const ErrorCompletionCallback& error_callback); + void SetProfileDelegate( + const device::BluetoothUUID& uuid, + const dbus::ObjectPath& device_path, + bluez::BluetoothProfileServiceProvider::Delegate* delegate, + const ProfileRegisteredCallback& success_callback, + const ErrorCompletionCallback& error_callback); void OnRegisterProfileError(const device::BluetoothUUID& uuid, const std::string& error_name, const std::string& error_message); @@ -377,7 +378,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS // Instance of the D-Bus agent object used for pairing, initialized with // our own class as its delegate. - scoped_ptr<BluetoothAgentServiceProvider> agent_; + scoped_ptr<bluez::BluetoothAgentServiceProvider> agent_; // UI thread task runner and socket thread object used to create sockets. scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos.cc b/device/bluetooth/bluetooth_adapter_profile_chromeos.cc index aeab2ae..27779f2 100644 --- a/device/bluetooth/bluetooth_adapter_profile_chromeos.cc +++ b/device/bluetooth/bluetooth_adapter_profile_chromeos.cc @@ -9,29 +9,31 @@ #include "base/bind.h" #include "base/logging.h" #include "base/strings/string_util.h" -#include "chromeos/dbus/bluetooth_profile_service_provider.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "dbus/bus.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" namespace chromeos { // static void BluetoothAdapterProfileChromeOS::Register( const device::BluetoothUUID& uuid, - const BluetoothProfileManagerClient::Options& options, + const bluez::BluetoothProfileManagerClient::Options& options, const ProfileRegisteredCallback& success_callback, - const BluetoothProfileManagerClient::ErrorCallback& error_callback) { + const bluez::BluetoothProfileManagerClient::ErrorCallback& error_callback) { scoped_ptr<BluetoothAdapterProfileChromeOS> profile( new BluetoothAdapterProfileChromeOS(uuid)); VLOG(1) << "Registering profile: " << profile->object_path().value(); const dbus::ObjectPath& object_path = profile->object_path(); - DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->RegisterProfile( - object_path, uuid.canonical_value(), options, - base::Bind(success_callback, base::Passed(&profile)), error_callback); + bluez::BluezDBusManager::Get() + ->GetBluetoothProfileManagerClient() + ->RegisterProfile(object_path, uuid.canonical_value(), options, + base::Bind(success_callback, base::Passed(&profile)), + error_callback); } BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS( @@ -42,9 +44,9 @@ BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS( object_path_ = dbus::ObjectPath("/org/chromium/bluetooth_profile/" + uuid_path); - dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); - profile_.reset( - BluetoothProfileServiceProvider::Create(system_bus, object_path_, this)); + dbus::Bus* system_bus = bluez::BluezDBusManager::Get()->GetSystemBus(); + profile_.reset(bluez::BluetoothProfileServiceProvider::Create( + system_bus, object_path_, this)); DCHECK(profile_.get()); } @@ -53,7 +55,7 @@ BluetoothAdapterProfileChromeOS::~BluetoothAdapterProfileChromeOS() { bool BluetoothAdapterProfileChromeOS::SetDelegate( const dbus::ObjectPath& device_path, - BluetoothProfileServiceProvider::Delegate* delegate) { + bluez::BluetoothProfileServiceProvider::Delegate* delegate) { DCHECK(delegate); VLOG(1) << "SetDelegate: " << object_path_.value() << " dev " << device_path.value(); @@ -83,7 +85,7 @@ void BluetoothAdapterProfileChromeOS::RemoveDelegate( VLOG(1) << device_path.value() << " No delegates left, unregistering."; // No users left, release the profile. - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothProfileManagerClient() ->UnregisterProfile( object_path_, unregistered_callback, @@ -102,7 +104,7 @@ void BluetoothAdapterProfileChromeOS::OnUnregisterProfileError( unregistered_callback.Run(); } -// BluetoothProfileServiceProvider::Delegate: +// bluez::BluetoothProfileServiceProvider::Delegate: void BluetoothAdapterProfileChromeOS::Released() { VLOG(1) << object_path_.value() << ": Release"; } @@ -110,7 +112,7 @@ void BluetoothAdapterProfileChromeOS::Released() { void BluetoothAdapterProfileChromeOS::NewConnection( const dbus::ObjectPath& device_path, scoped_ptr<dbus::FileDescriptor> fd, - const BluetoothProfileServiceProvider::Delegate::Options& options, + const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, const ConfirmationCallback& callback) { dbus::ObjectPath delegate_path = device_path; diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos.h b/device/bluetooth/bluetooth_adapter_profile_chromeos.h index 85e2ffe..35971e8 100644 --- a/device/bluetooth/bluetooth_adapter_profile_chromeos.h +++ b/device/bluetooth/bluetooth_adapter_profile_chromeos.h @@ -6,10 +6,10 @@ #define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_PROFILE_CHROMEOS_H_ #include "base/memory/weak_ptr.h" -#include "chromeos/dbus/bluetooth_profile_manager_client.h" -#include "chromeos/dbus/bluetooth_profile_service_provider.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" #include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" namespace device { class BluetoothUUID; @@ -28,7 +28,7 @@ namespace chromeos { // BluetoothAdapterProfileChromeOS objects are owned by the // BluetoothAdapterChromeOS and allocated through Register() class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS - : public chromeos::BluetoothProfileServiceProvider::Delegate { + : public bluez::BluetoothProfileServiceProvider::Delegate { public: typedef base::Callback<void(scoped_ptr<BluetoothAdapterProfileChromeOS> profile)> ProfileRegisteredCallback; @@ -39,9 +39,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS // will be called. static void Register( const device::BluetoothUUID& uuid, - const BluetoothProfileManagerClient::Options& options, + const bluez::BluetoothProfileManagerClient::Options& options, const ProfileRegisteredCallback& success_callback, - const BluetoothProfileManagerClient::ErrorCallback& error_callback); + const bluez::BluetoothProfileManagerClient::ErrorCallback& + error_callback); ~BluetoothAdapterProfileChromeOS() override; @@ -56,7 +57,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS // Returns true if the delegate was set, and false if the |device_path| // already had a delegate set. bool SetDelegate(const dbus::ObjectPath& device_path, - BluetoothProfileServiceProvider::Delegate* delegate); + bluez::BluetoothProfileServiceProvider::Delegate* delegate); // Remove the delegate for a device. |unregistered_callback| will be called // if this unregisters the profile. @@ -69,12 +70,12 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS private: BluetoothAdapterProfileChromeOS(const device::BluetoothUUID& uuid); - // BluetoothProfileServiceProvider::Delegate: + // bluez::BluetoothProfileServiceProvider::Delegate: void Released() override; void NewConnection( const dbus::ObjectPath& device_path, scoped_ptr<dbus::FileDescriptor> fd, - const BluetoothProfileServiceProvider::Delegate::Options& options, + const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, const ConfirmationCallback& callback) override; void RequestDisconnection(const dbus::ObjectPath& device_path, const ConfirmationCallback& callback) override; @@ -86,7 +87,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS const std::string& error_message); // List of delegates which this profile is multiplexing to. - std::map<std::string, BluetoothProfileServiceProvider::Delegate*> delegates_; + std::map<std::string, bluez::BluetoothProfileServiceProvider::Delegate*> + delegates_; // The UUID that this profile represents. const device::BluetoothUUID& uuid_; @@ -95,7 +97,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS dbus::ObjectPath object_path_; // Profile dbus object for receiving profile method calls from BlueZ - scoped_ptr<BluetoothProfileServiceProvider> profile_; + scoped_ptr<bluez::BluetoothProfileServiceProvider> profile_; // Note: This should remain the last member so it'll be destroyed and // invalidate its weak pointers before any other members are destroyed. diff --git a/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc b/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc index 1b9c0b3..be99901 100644 --- a/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc @@ -4,17 +4,17 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" -#include "chromeos/dbus/bluetooth_profile_service_provider.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/fake_bluetooth_adapter_client.h" -#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h" -#include "chromeos/dbus/fake_bluetooth_device_client.h" -#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_adapter_profile_chromeos.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_device_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h" #include "testing/gtest/include/gtest/gtest.h" using device::BluetoothAdapter; @@ -27,25 +27,29 @@ class BluetoothAdapterProfileChromeOSTest : public testing::Test { BluetoothAdapterProfileChromeOSTest() : success_callback_count_(0), error_callback_count_(0), - fake_delegate_paired_(FakeBluetoothDeviceClient::kPairedDevicePath), - fake_delegate_autopair_(FakeBluetoothDeviceClient::kLegacyAutopairPath), + fake_delegate_paired_( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath), + fake_delegate_autopair_( + bluez::FakeBluetoothDeviceClient::kLegacyAutopairPath), fake_delegate_listen_(""), profile_user_ptr_(nullptr) {} void SetUp() override { - scoped_ptr<DBusThreadManagerSetter> dbus_setter = - DBusThreadManager::GetSetterForTesting(); + scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter = + bluez::BluezDBusManager::GetSetterForTesting(); dbus_setter->SetBluetoothAdapterClient( - scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient)); + scoped_ptr<bluez::BluetoothAdapterClient>( + new bluez::FakeBluetoothAdapterClient)); dbus_setter->SetBluetoothAgentManagerClient( - scoped_ptr<BluetoothAgentManagerClient>( - new FakeBluetoothAgentManagerClient)); + scoped_ptr<bluez::BluetoothAgentManagerClient>( + new bluez::FakeBluetoothAgentManagerClient)); dbus_setter->SetBluetoothDeviceClient( - scoped_ptr<BluetoothDeviceClient>(new FakeBluetoothDeviceClient)); + scoped_ptr<bluez::BluetoothDeviceClient>( + new bluez::FakeBluetoothDeviceClient)); dbus_setter->SetBluetoothProfileManagerClient( - scoped_ptr<BluetoothProfileManagerClient>( - new FakeBluetoothProfileManagerClient)); + scoped_ptr<bluez::BluetoothProfileManagerClient>( + new bluez::FakeBluetoothProfileManagerClient)); // Grab a pointer to the adapter. device::BluetoothAdapterFactory::GetAdapter( @@ -64,21 +68,20 @@ class BluetoothAdapterProfileChromeOSTest : public testing::Test { void TearDown() override { profile_.reset(); adapter_ = nullptr; - DBusThreadManager::Shutdown(); + bluez::BluezDBusManager::Shutdown(); } void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) { adapter_ = adapter; } - class FakeDelegate - : public chromeos::BluetoothProfileServiceProvider::Delegate { + class FakeDelegate : public bluez::BluetoothProfileServiceProvider::Delegate { public: FakeDelegate(const std::string& device_path) : connections_(0) { device_path_ = dbus::ObjectPath(device_path); } - // BluetoothProfileServiceProvider::Delegate: + // bluez::BluetoothProfileServiceProvider::Delegate: void Released() override { // noop } @@ -86,7 +89,8 @@ class BluetoothAdapterProfileChromeOSTest : public testing::Test { void NewConnection( const dbus::ObjectPath& device_path, scoped_ptr<dbus::FileDescriptor> fd, - const BluetoothProfileServiceProvider::Delegate::Options& options, + const bluez::BluetoothProfileServiceProvider::Delegate::Options& + options, const ConfirmationCallback& callback) override { ++connections_; fd->CheckValidity(); @@ -157,8 +161,8 @@ class BluetoothAdapterProfileChromeOSTest : public testing::Test { }; TEST_F(BluetoothAdapterProfileChromeOSTest, DelegateCount) { - BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kRfcommUuid); - BluetoothProfileManagerClient::Options options; + BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid); + bluez::BluetoothProfileManagerClient::Options options; options.require_authentication.reset(new bool(false)); @@ -194,8 +198,8 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, DelegateCount) { } TEST_F(BluetoothAdapterProfileChromeOSTest, BlackHole) { - BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kRfcommUuid); - BluetoothProfileManagerClient::Options options; + BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid); + bluez::BluetoothProfileManagerClient::Options options; options.require_authentication.reset(new bool(false)); @@ -212,9 +216,9 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, BlackHole) { EXPECT_EQ(1U, success_callback_count_); EXPECT_EQ(0U, error_callback_count_); - DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath), - FakeBluetoothProfileManagerClient::kRfcommUuid, + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath), + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid, base::Bind( &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback, base::Unretained(this)), @@ -230,8 +234,8 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, BlackHole) { } TEST_F(BluetoothAdapterProfileChromeOSTest, Routing) { - BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kRfcommUuid); - BluetoothProfileManagerClient::Options options; + BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid); + bluez::BluetoothProfileManagerClient::Options options; options.require_authentication.reset(new bool(false)); @@ -255,9 +259,9 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, Routing) { profile_->SetDelegate(fake_delegate_listen_.device_path_, &fake_delegate_listen_); - DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath), - FakeBluetoothProfileManagerClient::kRfcommUuid, + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath), + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid, base::Bind( &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback, base::Unretained(this)), @@ -271,9 +275,9 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, Routing) { EXPECT_EQ(1U, fake_delegate_paired_.connections_); - DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLegacyAutopairPath), - FakeBluetoothProfileManagerClient::kRfcommUuid, + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLegacyAutopairPath), + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid, base::Bind( &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback, base::Unretained(this)), @@ -288,9 +292,9 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, Routing) { EXPECT_EQ(1U, fake_delegate_autopair_.connections_); // Incoming connections look the same from BlueZ. - DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( - dbus::ObjectPath(FakeBluetoothDeviceClient::kDisplayPinCodePath), - FakeBluetoothProfileManagerClient::kRfcommUuid, + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kDisplayPinCodePath), + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid, base::Bind( &BluetoothAdapterProfileChromeOSTest::DBusConnectSuccessCallback, base::Unretained(this)), @@ -306,8 +310,8 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, Routing) { } TEST_F(BluetoothAdapterProfileChromeOSTest, SimultaneousRegister) { - BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kRfcommUuid); - BluetoothProfileManagerClient::Options options; + BluetoothUUID uuid(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid); + bluez::BluetoothProfileManagerClient::Options options; BluetoothAdapterChromeOS* adapter = static_cast<BluetoothAdapterChromeOS*>(adapter_.get()); @@ -347,8 +351,9 @@ TEST_F(BluetoothAdapterProfileChromeOSTest, SimultaneousRegister) { } TEST_F(BluetoothAdapterProfileChromeOSTest, SimultaneousRegisterFail) { - BluetoothUUID uuid(FakeBluetoothProfileManagerClient::kUnregisterableUuid); - BluetoothProfileManagerClient::Options options; + BluetoothUUID uuid( + bluez::FakeBluetoothProfileManagerClient::kUnregisterableUuid); + bluez::BluetoothProfileManagerClient::Options options; BluetoothAdapterChromeOS* adapter = static_cast<BluetoothAdapterChromeOS*>(adapter_.get()); diff --git a/device/bluetooth/bluetooth_advertisement_chromeos.cc b/device/bluetooth/bluetooth_advertisement_chromeos.cc index 8cdfe90..671977d 100644 --- a/device/bluetooth/bluetooth_advertisement_chromeos.cc +++ b/device/bluetooth/bluetooth_advertisement_chromeos.cc @@ -12,11 +12,11 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string_util.h" -#include "chromeos/dbus/bluetooth_le_advertising_manager_client.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "dbus/bus.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" +#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" #include "third_party/cros_system_api/dbus/service_constants.h" namespace { @@ -82,10 +82,12 @@ BluetoothAdvertisementChromeOS::BluetoothAdvertisementChromeOS( dbus::ObjectPath advertisement_object_path = dbus::ObjectPath("/org/chromium/bluetooth_advertisement/" + GuidString); - DCHECK(DBusThreadManager::Get()); - provider_ = BluetoothLEAdvertisementServiceProvider::Create( - DBusThreadManager::Get()->GetSystemBus(), advertisement_object_path, this, - static_cast<BluetoothLEAdvertisementServiceProvider::AdvertisementType>( + DCHECK(bluez::BluezDBusManager::Get()); + provider_ = bluez::BluetoothLEAdvertisementServiceProvider::Create( + bluez::BluezDBusManager::Get()->GetSystemBus(), advertisement_object_path, + this, + static_cast< + bluez::BluetoothLEAdvertisementServiceProvider::AdvertisementType>( data->type()), data->service_uuids().Pass(), data->manufacturer_data().Pass(), data->solicit_uuids().Pass(), data->service_data().Pass()); @@ -95,8 +97,8 @@ void BluetoothAdvertisementChromeOS::Register( const base::Closure& success_callback, const device::BluetoothAdapter::CreateAdvertisementErrorCallback& error_callback) { - DCHECK(DBusThreadManager::Get()); - DBusThreadManager::Get() + DCHECK(bluez::BluezDBusManager::Get()); + bluez::BluezDBusManager::Get() ->GetBluetoothLEAdvertisingManagerClient() ->RegisterAdvertisement( adapter_->object_path(), provider_->object_path(), success_callback, @@ -118,8 +120,8 @@ void BluetoothAdvertisementChromeOS::Unregister( return; } - DCHECK(DBusThreadManager::Get()); - DBusThreadManager::Get() + DCHECK(bluez::BluezDBusManager::Get()); + bluez::BluezDBusManager::Get() ->GetBluetoothLEAdvertisingManagerClient() ->UnregisterAdvertisement( adapter_->object_path(), provider_->object_path(), success_callback, diff --git a/device/bluetooth/bluetooth_advertisement_chromeos.h b/device/bluetooth/bluetooth_advertisement_chromeos.h index aeb59b7..44abec2 100644 --- a/device/bluetooth/bluetooth_advertisement_chromeos.h +++ b/device/bluetooth/bluetooth_advertisement_chromeos.h @@ -6,21 +6,24 @@ #define DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_CHROMEOS_H_ #include "base/macros.h" -#include "chromeos/dbus/bluetooth_le_advertisement_service_provider.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_advertisement.h" #include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h" + +namespace bluez { +class BluetoothLEAdvertisementServiceProvider; +} namespace chromeos { -class BluetoothLEAdvertisementServiceProvider; class BluetoothAdapterChromeOS; // The BluetoothAdvertisementChromeOS class implements BluetoothAdvertisement // for the Chrome OS platform. class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisementChromeOS : public device::BluetoothAdvertisement, - public BluetoothLEAdvertisementServiceProvider::Delegate { + public bluez::BluetoothLEAdvertisementServiceProvider::Delegate { public: BluetoothAdvertisementChromeOS( scoped_ptr<device::BluetoothAdvertisement::Data> data, @@ -30,7 +33,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisementChromeOS void Unregister(const SuccessCallback& success_callback, const ErrorCallback& error_callback) override; - // BluetoothLEAdvertisementServiceProvider::Delegate overrides: + // bluez::BluetoothLEAdvertisementServiceProvider::Delegate overrides: void Released() override; void Register( @@ -40,7 +43,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisementChromeOS // Used from tests to be able to trigger events on the fake advertisement // provider. - BluetoothLEAdvertisementServiceProvider* provider() { + bluez::BluetoothLEAdvertisementServiceProvider* provider() { return provider_.get(); } @@ -49,7 +52,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisementChromeOS // Adapter this advertisement is advertising on. scoped_refptr<BluetoothAdapterChromeOS> adapter_; - scoped_ptr<BluetoothLEAdvertisementServiceProvider> provider_; + scoped_ptr<bluez::BluetoothLEAdvertisementServiceProvider> provider_; DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisementChromeOS); }; diff --git a/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc b/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc index 02fe1e4..165dc8d 100644 --- a/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc @@ -9,12 +9,12 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_advertisement.h" #include "device/bluetooth/bluetooth_advertisement_chromeos.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h" #include "testing/gtest/include/gtest/gtest.h" using device::BluetoothAdapter; @@ -52,7 +52,7 @@ class TestAdvertisementObserver : public BluetoothAdvertisement::Observer { class BluetoothAdvertisementChromeOSTest : public testing::Test { public: void SetUp() override { - DBusThreadManager::Initialize(); + bluez::BluezDBusManager::Initialize(NULL, true); callback_count_ = 0; error_callback_count_ = 0; @@ -70,7 +70,7 @@ class BluetoothAdvertisementChromeOSTest : public testing::Test { // The adapter should outlive the advertisement. advertisement_ = nullptr; adapter_ = nullptr; - DBusThreadManager::Shutdown(); + bluez::BluezDBusManager::Shutdown(); } // Gets the existing Bluetooth adapter. @@ -134,8 +134,8 @@ class BluetoothAdvertisementChromeOSTest : public testing::Test { void TriggerReleased(scoped_refptr<BluetoothAdvertisement> advertisement) { BluetoothAdvertisementChromeOS* adv = static_cast<BluetoothAdvertisementChromeOS*>(advertisement.get()); - FakeBluetoothLEAdvertisementServiceProvider* provider = - static_cast<FakeBluetoothLEAdvertisementServiceProvider*>( + bluez::FakeBluetoothLEAdvertisementServiceProvider* provider = + static_cast<bluez::FakeBluetoothLEAdvertisementServiceProvider*>( adv->provider()); provider->Release(); } diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.cc b/device/bluetooth/bluetooth_audio_sink_chromeos.cc index 18ab219..9bb4b60 100644 --- a/device/bluetooth/bluetooth_audio_sink_chromeos.cc +++ b/device/bluetooth/bluetooth_audio_sink_chromeos.cc @@ -14,9 +14,9 @@ #include "base/debug/stack_trace.h" #include "base/files/file_util.h" #include "base/logging.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "dbus/message.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" using dbus::ObjectPath; using device::BluetoothAudioSink; @@ -94,17 +94,17 @@ BluetoothAudioSinkChromeOS::BluetoothAudioSinkChromeOS( CHECK(adapter_.get()); CHECK(adapter_->IsPresent()); - CHECK(DBusThreadManager::IsInitialized()); + CHECK(bluez::BluezDBusManager::IsInitialized()); adapter_->AddObserver(this); - BluetoothMediaClient* media = - DBusThreadManager::Get()->GetBluetoothMediaClient(); + bluez::BluetoothMediaClient* media = + bluez::BluezDBusManager::Get()->GetBluetoothMediaClient(); CHECK(media); media->AddObserver(this); - BluetoothMediaTransportClient* transport = - DBusThreadManager::Get()->GetBluetoothMediaTransportClient(); + bluez::BluetoothMediaTransportClient* transport = + bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient(); CHECK(transport); transport->AddObserver(this); @@ -123,13 +123,13 @@ BluetoothAudioSinkChromeOS::~BluetoothAudioSinkChromeOS() { adapter_->RemoveObserver(this); - BluetoothMediaClient* media = - DBusThreadManager::Get()->GetBluetoothMediaClient(); + bluez::BluetoothMediaClient* media = + bluez::BluezDBusManager::Get()->GetBluetoothMediaClient(); CHECK(media); media->RemoveObserver(this); - BluetoothMediaTransportClient* transport = - DBusThreadManager::Get()->GetBluetoothMediaTransportClient(); + bluez::BluetoothMediaTransportClient* transport = + bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient(); CHECK(transport); transport->RemoveObserver(this); } @@ -139,11 +139,11 @@ void BluetoothAudioSinkChromeOS::Unregister( const device::BluetoothAudioSink::ErrorCallback& error_callback) { VLOG(1) << "Unregister"; - if (!DBusThreadManager::IsInitialized()) + if (!bluez::BluezDBusManager::IsInitialized()) error_callback.Run(BluetoothAudioSink::ERROR_NOT_UNREGISTERED); - BluetoothMediaClient* media = - DBusThreadManager::Get()->GetBluetoothMediaClient(); + bluez::BluetoothMediaClient* media = + bluez::BluezDBusManager::Get()->GetBluetoothMediaClient(); CHECK(media); media->UnregisterEndpoint( @@ -185,27 +185,28 @@ void BluetoothAudioSinkChromeOS::Register( DCHECK_EQ(state_, BluetoothAudioSink::STATE_DISCONNECTED); // Gets system bus. - dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); + dbus::Bus* system_bus = bluez::BluezDBusManager::Get()->GetSystemBus(); // Creates a Media Endpoint with newly-generated path. endpoint_path_ = GenerateEndpointPath(); - media_endpoint_.reset(BluetoothMediaEndpointServiceProvider::Create( + media_endpoint_.reset(bluez::BluetoothMediaEndpointServiceProvider::Create( system_bus, endpoint_path_, this)); DCHECK(media_endpoint_.get()); // Creates endpoint properties with |options|. options_ = options; - chromeos::BluetoothMediaClient::EndpointProperties endpoint_properties; - endpoint_properties.uuid = BluetoothMediaClient::kBluetoothAudioSinkUUID; + bluez::BluetoothMediaClient::EndpointProperties endpoint_properties; + endpoint_properties.uuid = + bluez::BluetoothMediaClient::kBluetoothAudioSinkUUID; endpoint_properties.codec = options_.codec; endpoint_properties.capabilities = options_.capabilities; media_path_ = static_cast<BluetoothAdapterChromeOS*>( adapter_.get())->object_path(); - BluetoothMediaClient* media = - DBusThreadManager::Get()->GetBluetoothMediaClient(); + bluez::BluetoothMediaClient* media = + bluez::BluezDBusManager::Get()->GetBluetoothMediaClient(); CHECK(media); media->RegisterEndpoint( media_path_, @@ -217,7 +218,7 @@ void BluetoothAudioSinkChromeOS::Register( weak_ptr_factory_.GetWeakPtr(), error_callback)); } -BluetoothMediaEndpointServiceProvider* +bluez::BluetoothMediaEndpointServiceProvider* BluetoothAudioSinkChromeOS::GetEndpointServiceProvider() { return media_endpoint_.get(); } @@ -279,21 +280,21 @@ void BluetoothAudioSinkChromeOS::MediaTransportPropertyChanged( VLOG(1) << "MediaTransportPropertyChanged: " << property_name; // Retrieves the property set of the transport object with |object_path|. - BluetoothMediaTransportClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothMediaTransportClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothMediaTransportClient() ->GetProperties(object_path); // Dispatches a property changed event to the corresponding handler. if (property_name == properties->state.name()) { if (properties->state.value() == - BluetoothMediaTransportClient::kStateIdle) { + bluez::BluetoothMediaTransportClient::kStateIdle) { StateChanged(BluetoothAudioSink::STATE_IDLE); } else if (properties->state.value() == - BluetoothMediaTransportClient::kStatePending) { + bluez::BluetoothMediaTransportClient::kStatePending) { StateChanged(BluetoothAudioSink::STATE_PENDING); } else if (properties->state.value() == - BluetoothMediaTransportClient::kStateActive) { + bluez::BluetoothMediaTransportClient::kStateActive) { StateChanged(BluetoothAudioSink::STATE_ACTIVE); } } else if (property_name == properties->volume.name()) { @@ -308,7 +309,7 @@ void BluetoothAudioSinkChromeOS::SetConfiguration( transport_path_ = transport_path; // The initial state for a connection should be "idle". - if (properties.state != BluetoothMediaTransportClient::kStateIdle) { + if (properties.state != bluez::BluetoothMediaTransportClient::kStateIdle) { VLOG(1) << "SetConfiugration - unexpected state :" << properties.state; return; } @@ -355,7 +356,7 @@ void BluetoothAudioSinkChromeOS::AcquireFD() { read_has_failed_ = false; - DBusThreadManager::Get()->GetBluetoothMediaTransportClient()->Acquire( + bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient()->Acquire( transport_path_, base::Bind(&BluetoothAudioSinkChromeOS::OnAcquireSucceeded, weak_ptr_factory_.GetWeakPtr()), diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos.h b/device/bluetooth/bluetooth_audio_sink_chromeos.h index 6261ace..750b31d 100644 --- a/device/bluetooth/bluetooth_audio_sink_chromeos.h +++ b/device/bluetooth/bluetooth_audio_sink_chromeos.h @@ -14,14 +14,14 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/observer_list.h" -#include "chromeos/dbus/bluetooth_media_client.h" -#include "chromeos/dbus/bluetooth_media_endpoint_service_provider.h" -#include "chromeos/dbus/bluetooth_media_transport_client.h" #include "dbus/file_descriptor.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_audio_sink.h" #include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_media_client.h" +#include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h" +#include "device/bluetooth/dbus/bluetooth_media_transport_client.h" namespace chromeos { @@ -30,9 +30,9 @@ class BluetoothAudioSinkChromeOSTest; class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkChromeOS : public device::BluetoothAudioSink, public device::BluetoothAdapter::Observer, - public BluetoothMediaClient::Observer, - public BluetoothMediaTransportClient::Observer, - public BluetoothMediaEndpointServiceProvider::Delegate, + public bluez::BluetoothMediaClient::Observer, + public bluez::BluetoothMediaTransportClient::Observer, + public bluez::BluetoothMediaEndpointServiceProvider::Delegate, public base::MessageLoopForIO::Watcher { public: explicit BluetoothAudioSinkChromeOS( @@ -61,7 +61,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkChromeOS // Returns a pointer to the media endpoint object. This function should be // used for testing purpose only. - BluetoothMediaEndpointServiceProvider* GetEndpointServiceProvider(); + bluez::BluetoothMediaEndpointServiceProvider* GetEndpointServiceProvider(); private: ~BluetoothAudioSinkChromeOS() override; @@ -72,15 +72,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkChromeOS void AdapterPoweredChanged(device::BluetoothAdapter* adapter, bool powered) override; - // BluetoothMediaClient::Observer overrides. + // bluez::BluetoothMediaClient::Observer overrides. void MediaRemoved(const dbus::ObjectPath& object_path) override; - // BluetoothMediaTransportClient::Observer overrides. + // bluez::BluetoothMediaTransportClient::Observer overrides. void MediaTransportRemoved(const dbus::ObjectPath& object_path) override; void MediaTransportPropertyChanged(const dbus::ObjectPath& object_path, const std::string& property_name) override; - // BluetoothMediaEndpointServiceProvider::Delegate overrides. + // bluez::BluetoothMediaEndpointServiceProvider::Delegate overrides. void SetConfiguration(const dbus::ObjectPath& transport_path, const TransportProperties& properties) override; void SelectConfiguration( @@ -204,7 +204,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAudioSinkChromeOS device::BluetoothAudioSink::Options options_; // Media Endpoint object owned by the audio sink object. - scoped_ptr<BluetoothMediaEndpointServiceProvider> media_endpoint_; + scoped_ptr<bluez::BluetoothMediaEndpointServiceProvider> media_endpoint_; // List of observers interested in event notifications from us. Objects in // |observers_| are expected to outlive a BluetoothAudioSinkChromeOS object. diff --git a/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc b/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc index a585f3d..5f51cb8 100644 --- a/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_audio_sink_chromeos_unittest.cc @@ -8,20 +8,21 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" -#include "chromeos/dbus/bluetooth_media_client.h" -#include "chromeos/dbus/bluetooth_media_endpoint_service_provider.h" -#include "chromeos/dbus/bluetooth_media_transport_client.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/fake_bluetooth_media_client.h" -#include "chromeos/dbus/fake_bluetooth_media_endpoint_service_provider.h" -#include "chromeos/dbus/fake_bluetooth_media_transport_client.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_audio_sink.h" #include "device/bluetooth/bluetooth_audio_sink_chromeos.h" +#include "device/bluetooth/dbus/bluetooth_media_client.h" +#include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h" +#include "device/bluetooth/dbus/bluetooth_media_transport_client.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h" #include "testing/gtest/include/gtest/gtest.h" +using bluez::FakeBluetoothMediaTransportClient; using dbus::ObjectPath; using device::BluetoothAdapter; using device::BluetoothAdapterFactory; @@ -81,26 +82,26 @@ class TestAudioSinkObserver : public BluetoothAudioSink::Observer { class BluetoothAudioSinkChromeOSTest : public testing::Test { public: void SetUp() override { - DBusThreadManager::Initialize(); + bluez::BluezDBusManager::Initialize(NULL, true); callback_count_ = 0; error_callback_count_ = 0; - fake_media_ = static_cast<FakeBluetoothMediaClient*>( - DBusThreadManager::Get()->GetBluetoothMediaClient()); + fake_media_ = static_cast<bluez::FakeBluetoothMediaClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothMediaClient()); fake_transport_ = static_cast<FakeBluetoothMediaTransportClient*>( - DBusThreadManager::Get()->GetBluetoothMediaTransportClient()); + bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient()); // Initiates Delegate::TransportProperties with default values. properties_.device = ObjectPath(FakeBluetoothMediaTransportClient::kTransportDevicePath); - properties_.uuid = BluetoothMediaClient::kBluetoothAudioSinkUUID; + properties_.uuid = bluez::BluetoothMediaClient::kBluetoothAudioSinkUUID; properties_.codec = FakeBluetoothMediaTransportClient::kTransportCodec; properties_.configuration = std::vector<uint8_t>( FakeBluetoothMediaTransportClient::kTransportConfiguration, FakeBluetoothMediaTransportClient::kTransportConfiguration + FakeBluetoothMediaTransportClient::kTransportConfigurationLength); - properties_.state = BluetoothMediaTransportClient::kStateIdle; + properties_.state = bluez::BluetoothMediaTransportClient::kStateIdle; properties_.delay.reset( new uint16_t(FakeBluetoothMediaTransportClient::kTransportDelay)); properties_.volume.reset( @@ -119,7 +120,7 @@ class BluetoothAudioSinkChromeOSTest : public testing::Test { // The adapter should outlive audio sink. audio_sink_ = nullptr; adapter_ = nullptr; - DBusThreadManager::Shutdown(); + bluez::BluezDBusManager::Shutdown(); } // Gets the existing Bluetooth adapter. @@ -180,8 +181,9 @@ class BluetoothAudioSinkChromeOSTest : public testing::Test { static_cast<BluetoothAudioSinkChromeOS*>(audio_sink_.get()); ASSERT_NE(audio_sink_chromeos, nullptr); - media_endpoint_ = static_cast<FakeBluetoothMediaEndpointServiceProvider*>( - audio_sink_chromeos->GetEndpointServiceProvider()); + media_endpoint_ = + static_cast<bluez::FakeBluetoothMediaEndpointServiceProvider*>( + audio_sink_chromeos->GetEndpointServiceProvider()); } // Called whenever RegisterAudioSink is completed successfully. @@ -233,16 +235,16 @@ class BluetoothAudioSinkChromeOSTest : public testing::Test { base::MessageLoopForIO message_loop_; - FakeBluetoothMediaClient* fake_media_; + bluez::FakeBluetoothMediaClient* fake_media_; FakeBluetoothMediaTransportClient* fake_transport_; - FakeBluetoothMediaEndpointServiceProvider* media_endpoint_; + bluez::FakeBluetoothMediaEndpointServiceProvider* media_endpoint_; scoped_ptr<TestAudioSinkObserver> observer_; scoped_refptr<BluetoothAdapter> adapter_; scoped_refptr<BluetoothAudioSink> audio_sink_; // The default property set used while calling SetConfiguration on a media // endpoint object. - BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties + bluez::BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties properties_; }; diff --git a/device/bluetooth/bluetooth_chromeos_unittest.cc b/device/bluetooth/bluetooth_chromeos_unittest.cc index 49b5b59..cea92d9 100644 --- a/device/bluetooth/bluetooth_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_chromeos_unittest.cc @@ -6,12 +6,6 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/fake_bluetooth_adapter_client.h" -#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h" -#include "chromeos/dbus/fake_bluetooth_device_client.h" -#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h" -#include "chromeos/dbus/fake_bluetooth_input_client.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" @@ -20,6 +14,12 @@ #include "device/bluetooth/bluetooth_device_chromeos.h" #include "device/bluetooth/bluetooth_discovery_session.h" #include "device/bluetooth/bluetooth_pairing_chromeos.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_device_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_input_client.h" #include "device/bluetooth/test/test_bluetooth_adapter_observer.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/cros_system_api/dbus/service_constants.h" @@ -57,17 +57,18 @@ int GetDeviceIndexByAddress(BluetoothAdapter::DeviceList& devices, } class FakeBluetoothProfileServiceProviderDelegate - : public chromeos::BluetoothProfileServiceProvider::Delegate { + : public bluez::BluetoothProfileServiceProvider::Delegate { public: FakeBluetoothProfileServiceProviderDelegate() {} - // BluetoothProfileServiceProvider::Delegate: + // bluez::BluetoothProfileServiceProvider::Delegate: void Released() override {} - void NewConnection(const dbus::ObjectPath&, - scoped_ptr<dbus::FileDescriptor>, - const BluetoothProfileServiceProvider::Delegate::Options&, - const ConfirmationCallback&) override {} + void NewConnection( + const dbus::ObjectPath&, + scoped_ptr<dbus::FileDescriptor>, + const bluez::BluetoothProfileServiceProvider::Delegate::Options&, + const ConfirmationCallback&) override {} void RequestDisconnection(const dbus::ObjectPath&, const ConfirmationCallback&) override {} @@ -165,25 +166,28 @@ class TestPairingDelegate : public BluetoothDevice::PairingDelegate { class BluetoothChromeOSTest : public testing::Test { public: void SetUp() override { - scoped_ptr<DBusThreadManagerSetter> dbus_setter = - chromeos::DBusThreadManager::GetSetterForTesting(); - // We need to initialize DBusThreadManager early to prevent + scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter = + bluez::BluezDBusManager::GetSetterForTesting(); + // We need to initialize BluezDBusManager early to prevent // Bluetooth*::Create() methods from picking the real instead of fake // implementations. - fake_bluetooth_adapter_client_ = new FakeBluetoothAdapterClient; + fake_bluetooth_adapter_client_ = new bluez::FakeBluetoothAdapterClient; dbus_setter->SetBluetoothAdapterClient( - scoped_ptr<BluetoothAdapterClient>(fake_bluetooth_adapter_client_)); - fake_bluetooth_device_client_ = new FakeBluetoothDeviceClient; + scoped_ptr<bluez::BluetoothAdapterClient>( + fake_bluetooth_adapter_client_)); + fake_bluetooth_device_client_ = new bluez::FakeBluetoothDeviceClient; dbus_setter->SetBluetoothDeviceClient( - scoped_ptr<BluetoothDeviceClient>(fake_bluetooth_device_client_)); + scoped_ptr<bluez::BluetoothDeviceClient>( + fake_bluetooth_device_client_)); dbus_setter->SetBluetoothInputClient( - scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient)); + scoped_ptr<bluez::BluetoothInputClient>( + new bluez::FakeBluetoothInputClient)); dbus_setter->SetBluetoothAgentManagerClient( - scoped_ptr<BluetoothAgentManagerClient>( - new FakeBluetoothAgentManagerClient)); + scoped_ptr<bluez::BluetoothAgentManagerClient>( + new bluez::FakeBluetoothAgentManagerClient)); dbus_setter->SetBluetoothGattServiceClient( - scoped_ptr<BluetoothGattServiceClient>( - new FakeBluetoothGattServiceClient)); + scoped_ptr<bluez::BluetoothGattServiceClient>( + new bluez::FakeBluetoothGattServiceClient)); fake_bluetooth_adapter_client_->SetSimulationIntervalMs(10); @@ -208,7 +212,7 @@ class BluetoothChromeOSTest : public testing::Test { } discovery_sessions_.clear(); adapter_ = nullptr; - DBusThreadManager::Shutdown(); + bluez::BluezDBusManager::Shutdown(); } // Generic callbacks @@ -337,8 +341,8 @@ class BluetoothChromeOSTest : public testing::Test { protected: base::MessageLoop message_loop_; - FakeBluetoothAdapterClient* fake_bluetooth_adapter_client_; - FakeBluetoothDeviceClient* fake_bluetooth_device_client_; + bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client_; + bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client_; scoped_refptr<BluetoothAdapter> adapter_; int callback_count_; @@ -366,7 +370,7 @@ TEST_F(BluetoothChromeOSTest, AlreadyPresent) { // and initializes with an existing adapter if there is one. EXPECT_TRUE(adapter_->IsPresent()); EXPECT_FALSE(adapter_->IsPowered()); - EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress, + EXPECT_EQ(bluez::FakeBluetoothAdapterClient::kAdapterAddress, adapter_->GetAddress()); EXPECT_FALSE(adapter_->IsDiscovering()); @@ -375,12 +379,14 @@ TEST_F(BluetoothChromeOSTest, AlreadyPresent) { EXPECT_EQ(2U, devices.size()); // |devices| are not ordered, verify it contains the 2 device addresses. - EXPECT_NE(-1, GetDeviceIndexByAddress( - devices, FakeBluetoothDeviceClient::kPairedDeviceAddress)); - EXPECT_NE(-1, - GetDeviceIndexByAddress( - devices, - FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress)); + EXPECT_NE( + -1, GetDeviceIndexByAddress( + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress)); + EXPECT_NE( + -1, + GetDeviceIndexByAddress( + devices, + bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress)); } TEST_F(BluetoothChromeOSTest, BecomePresent) { @@ -401,7 +407,7 @@ TEST_F(BluetoothChromeOSTest, BecomePresent) { // We should have had a device announced. EXPECT_EQ(2, observer.device_added_count()); - EXPECT_EQ(FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress, + EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress, observer.last_device_address()); // Other callbacks shouldn't be called if the values are false. @@ -430,10 +436,10 @@ TEST_F(BluetoothChromeOSTest, BecomeNotPresent) { EXPECT_EQ(2, observer.device_removed_count()); // 2 possibilities for the last device here. std::string address = observer.last_device_address(); - EXPECT_TRUE( - address.compare( - FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress) == 0 || - address.compare(FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0); + EXPECT_TRUE(address.compare(bluez::FakeBluetoothDeviceClient:: + kPairedUnconnectableDeviceAddress) == 0 || + address.compare( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0); // Other callbacks shouldn't be called since the values are false. EXPECT_EQ(0, observer.powered_changed_count()); @@ -455,7 +461,7 @@ TEST_F(BluetoothChromeOSTest, SecondAdapter) { EXPECT_EQ(0, observer.present_changed_count()); EXPECT_TRUE(adapter_->IsPresent()); - EXPECT_EQ(FakeBluetoothAdapterClient::kAdapterAddress, + EXPECT_EQ(bluez::FakeBluetoothAdapterClient::kAdapterAddress, adapter_->GetAddress()); // Try removing the first adapter, we should now act as if the adapter @@ -472,10 +478,10 @@ TEST_F(BluetoothChromeOSTest, SecondAdapter) { // As BluetoothAdapter devices removal does not keep the order of adding them, // 2 possibilities for the last device here. std::string address = observer.last_device_address(); - EXPECT_TRUE( - address.compare( - FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress) == 0 || - address.compare(FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0); + EXPECT_TRUE(address.compare(bluez::FakeBluetoothDeviceClient:: + kPairedUnconnectableDeviceAddress) == 0 || + address.compare( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress) == 0); // Other callbacks shouldn't be called since the values are false. EXPECT_EQ(0, observer.powered_changed_count()); @@ -745,7 +751,7 @@ TEST_F(BluetoothChromeOSTest, Discovery) { message_loop_.Run(); EXPECT_EQ(2, observer.device_added_count()); - EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress, + EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress, observer.last_device_address()); // Next we should get another two devices... @@ -757,7 +763,7 @@ TEST_F(BluetoothChromeOSTest, Discovery) { message_loop_.Run(); EXPECT_EQ(1, observer.device_removed_count()); - EXPECT_EQ(FakeBluetoothDeviceClient::kVanishingDeviceAddress, + EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kVanishingDeviceAddress, observer.last_device_address()); } @@ -777,7 +783,7 @@ TEST_F(BluetoothChromeOSTest, PoweredAndDiscovering) { // Stop the timers that the simulation uses fake_bluetooth_device_client_->EndDiscoverySimulation( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath)); ASSERT_TRUE(adapter_->IsPowered()); ASSERT_TRUE(adapter_->IsDiscovering()); @@ -971,21 +977,23 @@ TEST_F(BluetoothChromeOSTest, // Stop the timers that the simulation uses fake_bluetooth_device_client_->EndDiscoverySimulation( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath)); ASSERT_TRUE(adapter_->IsPowered()); ASSERT_TRUE(adapter_->IsDiscovering()); // Stop device discovery behind the adapter. The adapter and the observer // should be notified of the change and the reference count should be reset. - // Even though FakeBluetoothAdapterClient does its own reference counting and + // Even though bluez::FakeBluetoothAdapterClient does its own reference + // counting and // we called 3 BluetoothAdapter::StartDiscoverySession 3 times, the - // FakeBluetoothAdapterClient's count should be only 1 and a single call to - // FakeBluetoothAdapterClient::StopDiscovery should work. + // bluez::FakeBluetoothAdapterClient's count should be only 1 and a single + // call to + // bluez::FakeBluetoothAdapterClient::StopDiscovery should work. fake_bluetooth_adapter_client_->StopDiscovery( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), GetCallback(), - base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); message_loop_.Run(); EXPECT_EQ(2, observer.discovering_changed_count()); EXPECT_EQ(4, callback_count_); @@ -1018,7 +1026,7 @@ TEST_F(BluetoothChromeOSTest, EXPECT_TRUE(discovery_sessions_[i]->IsActive()); fake_bluetooth_device_client_->EndDiscoverySimulation( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath)); // Make the adapter disappear and appear. This will make it come back as // discovering. When this happens, the reference count should become and @@ -1043,7 +1051,8 @@ TEST_F(BluetoothChromeOSTest, EXPECT_TRUE(observer.last_discovering()); EXPECT_TRUE(adapter_->IsDiscovering()); - // Start and stop discovery. At this point, FakeBluetoothAdapterClient has + // Start and stop discovery. At this point, bluez::FakeBluetoothAdapterClient + // has // a reference count that is equal to 1. Pretend that this was done by an // application other than us. Starting and stopping discovery will succeed // but it won't cause the discovery state to change. @@ -1088,9 +1097,9 @@ TEST_F(BluetoothChromeOSTest, // the discovery state won't change since our BluetoothAdapter also just // requested it via D-Bus. fake_bluetooth_adapter_client_->StopDiscovery( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), GetCallback(), - base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); message_loop_.Run(); EXPECT_EQ(5, observer.discovering_changed_count()); EXPECT_EQ(10, callback_count_); @@ -1149,7 +1158,7 @@ TEST_F(BluetoothChromeOSTest, InvalidatedDiscoverySessions) { // Stop the timers that the simulation uses fake_bluetooth_device_client_->EndDiscoverySimulation( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath)); ASSERT_TRUE(adapter_->IsPowered()); ASSERT_TRUE(adapter_->IsDiscovering()); @@ -1166,9 +1175,9 @@ TEST_F(BluetoothChromeOSTest, InvalidatedDiscoverySessions) { // memory errors as the sessions that we explicitly deleted should get // cleaned up. fake_bluetooth_adapter_client_->StopDiscovery( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), GetCallback(), - base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); message_loop_.Run(); EXPECT_EQ(2, observer.discovering_changed_count()); EXPECT_EQ(4, callback_count_); @@ -1201,7 +1210,7 @@ TEST_F(BluetoothChromeOSTest, QueuedDiscoveryRequests) { EXPECT_EQ(0, callback_count_); fake_bluetooth_device_client_->EndDiscoverySimulation( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath)); // The underlying adapter has started discovery, but our call hasn't returned // yet. @@ -2119,14 +2128,15 @@ TEST_F(BluetoothChromeOSTest, DeviceProperties) { ASSERT_EQ(2U, devices.size()); int idx = GetDeviceIndexByAddress( - devices, FakeBluetoothDeviceClient::kPairedDeviceAddress); + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_NE(-1, idx); - ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, + ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress, devices[idx]->GetAddress()); // Verify the other device properties. - EXPECT_EQ(base::UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName), - devices[idx]->GetName()); + EXPECT_EQ( + base::UTF8ToUTF16(bluez::FakeBluetoothDeviceClient::kPairedDeviceName), + devices[idx]->GetName()); EXPECT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[idx]->GetDeviceType()); EXPECT_TRUE(devices[idx]->IsPaired()); EXPECT_FALSE(devices[idx]->IsConnected()); @@ -2155,7 +2165,7 @@ TEST_F(BluetoothChromeOSTest, DeviceClassChanged) { ASSERT_EQ(2U, devices.size()); int idx = GetDeviceIndexByAddress( - devices, FakeBluetoothDeviceClient::kPairedDeviceAddress); + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_NE(-1, idx); ASSERT_EQ(BluetoothDevice::DEVICE_COMPUTER, devices[idx]->GetDeviceType()); @@ -2163,9 +2173,9 @@ TEST_F(BluetoothChromeOSTest, DeviceClassChanged) { // we change the class of the device. TestBluetoothAdapterObserver observer(adapter_); - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); properties->bluetooth_class.ReplaceValue(0x002580); @@ -2183,20 +2193,21 @@ TEST_F(BluetoothChromeOSTest, DeviceNameChanged) { ASSERT_EQ(2U, devices.size()); int idx = GetDeviceIndexByAddress( - devices, FakeBluetoothDeviceClient::kPairedDeviceAddress); + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_NE(-1, idx); - ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, + ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress, devices[idx]->GetAddress()); - ASSERT_EQ(base::UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName), - devices[idx]->GetName()); + ASSERT_EQ( + base::UTF8ToUTF16(bluez::FakeBluetoothDeviceClient::kPairedDeviceName), + devices[idx]->GetName()); // Install an observer; expect the DeviceChanged method to be called when // we change the alias of the device. TestBluetoothAdapterObserver observer(adapter_); - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); static const std::string new_name("New Device Name"); properties->alias.ReplaceValue(new_name); @@ -2215,20 +2226,21 @@ TEST_F(BluetoothChromeOSTest, DeviceAddressChanged) { ASSERT_EQ(2U, devices.size()); int idx = GetDeviceIndexByAddress( - devices, FakeBluetoothDeviceClient::kPairedDeviceAddress); + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_NE(-1, idx); - ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, + ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress, devices[idx]->GetAddress()); - ASSERT_EQ(base::UTF8ToUTF16(FakeBluetoothDeviceClient::kPairedDeviceName), - devices[idx]->GetName()); + ASSERT_EQ( + base::UTF8ToUTF16(bluez::FakeBluetoothDeviceClient::kPairedDeviceName), + devices[idx]->GetName()); // Install an observer; expect the DeviceAddressChanged method to be called // when we change the alias of the device. TestBluetoothAdapterObserver observer(adapter_); - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); static const char* kNewAddress = "D9:1F:FC:11:22:33"; properties->address.ReplaceValue(kNewAddress); @@ -2248,9 +2260,9 @@ TEST_F(BluetoothChromeOSTest, DeviceUuidsChanged) { ASSERT_EQ(2U, devices.size()); int idx = GetDeviceIndexByAddress( - devices, FakeBluetoothDeviceClient::kPairedDeviceAddress); + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_NE(-1, idx); - ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, + ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress, devices[idx]->GetAddress()); BluetoothDevice::UUIDList uuids = devices[idx]->GetUUIDs(); @@ -2262,9 +2274,9 @@ TEST_F(BluetoothChromeOSTest, DeviceUuidsChanged) { // we change the class of the device. TestBluetoothAdapterObserver observer(adapter_); - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); std::vector<std::string> new_uuids; new_uuids.push_back(uuids[0].canonical_value()); @@ -2297,12 +2309,12 @@ TEST_F(BluetoothChromeOSTest, DeviceInquiryRSSIInvalidated) { ASSERT_EQ(2U, devices.size()); int idx = GetDeviceIndexByAddress( - devices, FakeBluetoothDeviceClient::kPairedDeviceAddress); + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_NE(-1, idx); - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); // During discovery, rssi is a valid value (-75) properties->rssi.ReplaceValue(-75); @@ -2334,12 +2346,12 @@ TEST_F(BluetoothChromeOSTest, DeviceInquiryTxPowerInvalidated) { ASSERT_EQ(2U, devices.size()); int idx = GetDeviceIndexByAddress( - devices, FakeBluetoothDeviceClient::kPairedDeviceAddress); + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_NE(-1, idx); - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); // During discovery, tx_power is a valid value (0) properties->tx_power.ReplaceValue(0); @@ -2369,9 +2381,9 @@ TEST_F(BluetoothChromeOSTest, ForgetDevice) { ASSERT_EQ(2U, devices.size()); int idx = GetDeviceIndexByAddress( - devices, FakeBluetoothDeviceClient::kPairedDeviceAddress); + devices, bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_NE(-1, idx); - ASSERT_EQ(FakeBluetoothDeviceClient::kPairedDeviceAddress, + ASSERT_EQ(bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress, devices[idx]->GetAddress()); std::string address = devices[idx]->GetAddress(); @@ -2395,8 +2407,8 @@ TEST_F(BluetoothChromeOSTest, ForgetUnpairedDevice) { GetAdapter(); DiscoverDevices(); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kConnectUnpairableAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -2413,9 +2425,9 @@ TEST_F(BluetoothChromeOSTest, ForgetUnpairedDevice) { ASSERT_FALSE(device->IsConnecting()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kConnectUnpairablePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kConnectUnpairablePath)); ASSERT_TRUE(properties->trusted.value()); // Install an observer; expect the DeviceRemoved method to be called @@ -2426,20 +2438,20 @@ TEST_F(BluetoothChromeOSTest, ForgetUnpairedDevice) { EXPECT_EQ(0, error_callback_count_); EXPECT_EQ(1, observer.device_removed_count()); - EXPECT_EQ(FakeBluetoothDeviceClient::kConnectUnpairableAddress, + EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress, observer.last_device_address()); // GetDevices shouldn't return the device either. - device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kConnectUnpairableAddress); + device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress); EXPECT_FALSE(device != nullptr); } TEST_F(BluetoothChromeOSTest, ConnectPairedDevice) { GetAdapter(); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_TRUE(device != nullptr); ASSERT_TRUE(device->IsPaired()); @@ -2467,8 +2479,8 @@ TEST_F(BluetoothChromeOSTest, ConnectUnpairableDevice) { GetAdapter(); DiscoverDevices(); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kConnectUnpairableAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kConnectUnpairableAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -2492,9 +2504,9 @@ TEST_F(BluetoothChromeOSTest, ConnectUnpairableDevice) { EXPECT_FALSE(device->IsConnecting()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kConnectUnpairablePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kConnectUnpairablePath)); EXPECT_TRUE(properties->trusted.value()); // Verify is a HID device and is not connectable. @@ -2507,8 +2519,8 @@ TEST_F(BluetoothChromeOSTest, ConnectUnpairableDevice) { TEST_F(BluetoothChromeOSTest, ConnectConnectedDevice) { GetAdapter(); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_TRUE(device != nullptr); ASSERT_TRUE(device->IsPaired()); @@ -2545,8 +2557,8 @@ TEST_F(BluetoothChromeOSTest, ConnectDeviceFails) { GetAdapter(); DiscoverDevices(); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLegacyAutopairAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kLegacyAutopairAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -2571,8 +2583,8 @@ TEST_F(BluetoothChromeOSTest, ConnectDeviceFails) { TEST_F(BluetoothChromeOSTest, DisconnectDevice) { GetAdapter(); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_TRUE(device != nullptr); ASSERT_TRUE(device->IsPaired()); @@ -2605,8 +2617,8 @@ TEST_F(BluetoothChromeOSTest, DisconnectDevice) { TEST_F(BluetoothChromeOSTest, DisconnectUnconnectedDevice) { GetAdapter(); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_TRUE(device != nullptr); ASSERT_TRUE(device->IsPaired()); ASSERT_FALSE(device->IsConnected()); @@ -2630,18 +2642,20 @@ TEST_F(BluetoothChromeOSTest, PairTrustedDevice) { GetAdapter(); fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath( - FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath)); - BluetoothDevice* device = adapter_->GetDevice( - FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDeviceAddress); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient:: + kConnectedTrustedNotPairedDevicePath)); + BluetoothDevice* device = + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient:: + kConnectedTrustedNotPairedDeviceAddress); ASSERT_TRUE(device != nullptr); // On the DBus level the device is trusted but not paired. But the current // implementation of |BluetoothDevice::IsPaired()| returns true in this case. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( - FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties( + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient:: + kConnectedTrustedNotPairedDevicePath)); EXPECT_FALSE(properties->paired.value()); EXPECT_TRUE(properties->trusted.value()); ASSERT_TRUE(device->IsPaired()); @@ -2667,7 +2681,7 @@ TEST_F(BluetoothChromeOSTest, PairTrustedDevice) { // Make sure the paired property has been set to true. properties = fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( - FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath)); + bluez::FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath)); EXPECT_TRUE(properties->paired.value()); } @@ -2675,16 +2689,16 @@ TEST_F(BluetoothChromeOSTest, PairAlreadyPairedDevice) { GetAdapter(); fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_TRUE(device != nullptr); // On the DBus level a device can be trusted but not paired. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); EXPECT_TRUE(properties->paired.value()); EXPECT_TRUE(properties->trusted.value()); ASSERT_TRUE(device->IsPaired()); @@ -2712,8 +2726,8 @@ TEST_F(BluetoothChromeOSTest, PairLegacyAutopair) { // The Legacy Autopair device requires no PIN or Passkey to pair because // the daemon provides 0000 to the device for us. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLegacyAutopairAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kLegacyAutopairAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -2750,9 +2764,9 @@ TEST_F(BluetoothChromeOSTest, PairLegacyAutopair) { EXPECT_TRUE(device->IsConnectable()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLegacyAutopairPath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kLegacyAutopairPath)); EXPECT_TRUE(properties->trusted.value()); } @@ -2763,8 +2777,8 @@ TEST_F(BluetoothChromeOSTest, PairDisplayPinCode) { DiscoverDevices(); // Requires that we display a randomly generated PIN on the screen. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kDisplayPinCodeAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kDisplayPinCodeAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -2803,9 +2817,9 @@ TEST_F(BluetoothChromeOSTest, PairDisplayPinCode) { EXPECT_TRUE(device->IsConnectable()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kDisplayPinCodePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kDisplayPinCodePath)); EXPECT_TRUE(properties->trusted.value()); } @@ -2817,8 +2831,8 @@ TEST_F(BluetoothChromeOSTest, PairDisplayPasskey) { // Requires that we display a randomly generated Passkey on the screen, // and notifies us as it's typed in. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kDisplayPasskeyAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kDisplayPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -2878,9 +2892,9 @@ TEST_F(BluetoothChromeOSTest, PairDisplayPasskey) { EXPECT_FALSE(device->IsConnectable()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kDisplayPasskeyPath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kDisplayPasskeyPath)); EXPECT_TRUE(properties->trusted.value()); } @@ -2891,8 +2905,8 @@ TEST_F(BluetoothChromeOSTest, PairRequestPinCode) { DiscoverDevices(); // Requires that the user enters a PIN for them. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -2932,9 +2946,9 @@ TEST_F(BluetoothChromeOSTest, PairRequestPinCode) { EXPECT_TRUE(device->IsConnectable()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kRequestPinCodePath)); EXPECT_TRUE(properties->trusted.value()); } @@ -2945,8 +2959,8 @@ TEST_F(BluetoothChromeOSTest, PairConfirmPasskey) { DiscoverDevices(); // Requests that we confirm a displayed passkey. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -2983,9 +2997,9 @@ TEST_F(BluetoothChromeOSTest, PairConfirmPasskey) { EXPECT_TRUE(device->IsConnectable()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath)); EXPECT_TRUE(properties->trusted.value()); } @@ -2997,8 +3011,8 @@ TEST_F(BluetoothChromeOSTest, PairRequestPasskey) { // Requires that the user enters a Passkey, this would be some kind of // device that has a display, but doesn't use "just works" - maybe a car? - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3034,9 +3048,9 @@ TEST_F(BluetoothChromeOSTest, PairRequestPasskey) { EXPECT_TRUE(device->IsConnectable()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath)); EXPECT_TRUE(properties->trusted.value()); } @@ -3049,7 +3063,7 @@ TEST_F(BluetoothChromeOSTest, PairJustWorks) { // Uses just-works pairing, since this is an outgoing pairing, no delegate // interaction is required. BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kJustWorksAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kJustWorksAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3081,9 +3095,9 @@ TEST_F(BluetoothChromeOSTest, PairJustWorks) { EXPECT_TRUE(device->IsConnectable()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = + bluez::FakeBluetoothDeviceClient::Properties* properties = fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath)); EXPECT_TRUE(properties->trusted.value()); } @@ -3091,10 +3105,10 @@ TEST_F(BluetoothChromeOSTest, PairUnpairableDeviceFails) { fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); - DiscoverDevice(FakeBluetoothDeviceClient::kUnconnectableDeviceAddress); + DiscoverDevice(bluez::FakeBluetoothDeviceClient::kUnconnectableDeviceAddress); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kUnpairableDeviceAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kUnpairableDeviceAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3125,11 +3139,11 @@ TEST_F(BluetoothChromeOSTest, PairingFails) { fake_bluetooth_device_client_->SetSimulationIntervalMs(10); GetAdapter(); - DiscoverDevice(FakeBluetoothDeviceClient::kVanishingDeviceAddress); + DiscoverDevice(bluez::FakeBluetoothDeviceClient::kVanishingDeviceAddress); // The vanishing device times out during pairing - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kVanishingDeviceAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kVanishingDeviceAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3165,7 +3179,7 @@ TEST_F(BluetoothChromeOSTest, PairingFailsAtConnection) { // Everything seems to go according to plan with the unconnectable device; // it pairs, but then you can't make connections to it after. BluetoothDevice* device = adapter_->GetDevice( - FakeBluetoothDeviceClient::kUnconnectableDeviceAddress); + bluez::FakeBluetoothDeviceClient::kUnconnectableDeviceAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3197,9 +3211,9 @@ TEST_F(BluetoothChromeOSTest, PairingFailsAtConnection) { // Make sure the trusted property has been set to true still (since pairing // worked). - FakeBluetoothDeviceClient::Properties* properties = + bluez::FakeBluetoothDeviceClient::Properties* properties = fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( - FakeBluetoothDeviceClient::kUnconnectableDevicePath)); + bluez::FakeBluetoothDeviceClient::kUnconnectableDevicePath)); EXPECT_TRUE(properties->trusted.value()); } @@ -3210,8 +3224,8 @@ TEST_F(BluetoothChromeOSTest, PairingRejectedAtPinCode) { DiscoverDevices(); // Reject the pairing after we receive a request for the PIN code. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3248,8 +3262,8 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledAtPinCode) { DiscoverDevices(); // Cancel the pairing after we receive a request for the PIN code. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3286,8 +3300,8 @@ TEST_F(BluetoothChromeOSTest, PairingRejectedAtPasskey) { DiscoverDevices(); // Reject the pairing after we receive a request for the passkey. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3324,8 +3338,8 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledAtPasskey) { DiscoverDevices(); // Cancel the pairing after we receive a request for the passkey. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3362,8 +3376,8 @@ TEST_F(BluetoothChromeOSTest, PairingRejectedAtConfirmation) { DiscoverDevices(); // Reject the pairing after we receive a request for passkey confirmation. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3400,8 +3414,8 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledAtConfirmation) { DiscoverDevices(); // Cancel the pairing after we receive a request for the passkey. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3438,8 +3452,8 @@ TEST_F(BluetoothChromeOSTest, PairingCancelledInFlight) { DiscoverDevices(); // Cancel the pairing while we're waiting for the remote host. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLegacyAutopairAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kLegacyAutopairAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); @@ -3480,19 +3494,19 @@ TEST_F(BluetoothChromeOSTest, IncomingPairRequestPinCode) { // Requires that we provide a PIN code. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath)); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath)); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); TestBluetoothAdapterObserver observer(adapter_); fake_bluetooth_device_client_->SimulatePairing( - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath), true, - GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath), + true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); EXPECT_EQ(1, pairing_delegate.call_count_); EXPECT_EQ(1, pairing_delegate.request_pincode_count_); @@ -3511,9 +3525,9 @@ TEST_F(BluetoothChromeOSTest, IncomingPairRequestPinCode) { EXPECT_TRUE(device->IsPaired()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kRequestPinCodePath)); ASSERT_TRUE(properties->trusted.value()); // No pairing context should remain on the device. @@ -3534,19 +3548,19 @@ TEST_F(BluetoothChromeOSTest, IncomingPairConfirmPasskey) { // Requests that we confirm a displayed passkey. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath)); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath)); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); TestBluetoothAdapterObserver observer(adapter_); fake_bluetooth_device_client_->SimulatePairing( - dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath), true, - GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath), + true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); EXPECT_EQ(1, pairing_delegate.call_count_); EXPECT_EQ(1, pairing_delegate.confirm_passkey_count_); @@ -3566,9 +3580,9 @@ TEST_F(BluetoothChromeOSTest, IncomingPairConfirmPasskey) { EXPECT_TRUE(device->IsPaired()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath)); ASSERT_TRUE(properties->trusted.value()); // No pairing context should remain on the device. @@ -3589,19 +3603,19 @@ TEST_F(BluetoothChromeOSTest, IncomingPairRequestPasskey) { // Requests that we provide a Passkey. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath)); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath)); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); TestBluetoothAdapterObserver observer(adapter_); fake_bluetooth_device_client_->SimulatePairing( - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath), true, - GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath), + true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); EXPECT_EQ(1, pairing_delegate.call_count_); EXPECT_EQ(1, pairing_delegate.request_passkey_count_); @@ -3620,9 +3634,9 @@ TEST_F(BluetoothChromeOSTest, IncomingPairRequestPasskey) { EXPECT_TRUE(device->IsPaired()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath)); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath)); ASSERT_TRUE(properties->trusted.value()); // No pairing context should remain on the device. @@ -3644,17 +3658,17 @@ TEST_F(BluetoothChromeOSTest, IncomingPairJustWorks) { // Uses just-works pairing so, sinec this an incoming pairing, require // authorization from the user. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kJustWorksAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kJustWorksAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); TestBluetoothAdapterObserver observer(adapter_); fake_bluetooth_device_client_->SimulatePairing( - dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath), true, + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath), true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, base::Unretained(this))); @@ -3675,9 +3689,9 @@ TEST_F(BluetoothChromeOSTest, IncomingPairJustWorks) { EXPECT_TRUE(device->IsPaired()); // Make sure the trusted property has been set to true. - FakeBluetoothDeviceClient::Properties* properties = + bluez::FakeBluetoothDeviceClient::Properties* properties = fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath)); ASSERT_TRUE(properties->trusted.value()); // No pairing context should remain on the device. @@ -3694,19 +3708,19 @@ TEST_F(BluetoothChromeOSTest, IncomingPairRequestPinCodeWithoutDelegate) { // Requires that we provide a PIN Code, without a pairing delegate, // that will be rejected. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath)); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPinCodeAddress); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath)); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPinCodeAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); TestBluetoothAdapterObserver observer(adapter_); fake_bluetooth_device_client_->SimulatePairing( - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath), true, - GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPinCodePath), + true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); message_loop_.Run(); @@ -3733,19 +3747,19 @@ TEST_F(BluetoothChromeOSTest, IncomingPairConfirmPasskeyWithoutDelegate) { // Requests that we confirm a displayed passkey, without a pairing delegate, // that will be rejected. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath)); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kConfirmPasskeyAddress); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath)); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kConfirmPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); TestBluetoothAdapterObserver observer(adapter_); fake_bluetooth_device_client_->SimulatePairing( - dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath), true, - GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kConfirmPasskeyPath), + true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); message_loop_.Run(); @@ -3772,19 +3786,19 @@ TEST_F(BluetoothChromeOSTest, IncomingPairRequestPasskeyWithoutDelegate) { // Requests that we provide a displayed passkey, without a pairing delegate, // that will be rejected. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath)); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath)); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); TestBluetoothAdapterObserver observer(adapter_); fake_bluetooth_device_client_->SimulatePairing( - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath), true, - GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath), + true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); message_loop_.Run(); @@ -3811,17 +3825,17 @@ TEST_F(BluetoothChromeOSTest, IncomingPairJustWorksWithoutDelegate) { // Uses just-works pairing and thus requires authorization for incoming // pairings, without a pairing delegate, that will be rejected. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kJustWorksAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kJustWorksAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); TestBluetoothAdapterObserver observer(adapter_); fake_bluetooth_device_client_->SimulatePairing( - dbus::ObjectPath(FakeBluetoothDeviceClient::kJustWorksPath), true, + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kJustWorksPath), true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, base::Unretained(this))); @@ -3854,19 +3868,19 @@ TEST_F(BluetoothChromeOSTest, RemovePairingDelegateDuringPairing) { // Requests that we provide a Passkey. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath)); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kRequestPasskeyAddress); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath)); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kRequestPasskeyAddress); ASSERT_TRUE(device != nullptr); ASSERT_FALSE(device->IsPaired()); TestBluetoothAdapterObserver observer(adapter_); fake_bluetooth_device_client_->SimulatePairing( - dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPasskeyPath), true, - GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, - base::Unretained(this))); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kRequestPasskeyPath), + true, GetCallback(), base::Bind(&BluetoothChromeOSTest::DBusErrorCallback, + base::Unretained(this))); EXPECT_EQ(1, pairing_delegate.call_count_); EXPECT_EQ(1, pairing_delegate.request_passkey_count_); @@ -3897,11 +3911,11 @@ TEST_F(BluetoothChromeOSTest, DeviceId) { // Use the built-in paired device for this test, grab its Properties // structure so we can adjust the underlying modalias property. - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); - FakeBluetoothDeviceClient::Properties* properties = - fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kPairedDevicePath)); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); + bluez::FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties(dbus::ObjectPath( + bluez::FakeBluetoothDeviceClient::kPairedDevicePath)); ASSERT_TRUE(device != nullptr); ASSERT_TRUE(properties != nullptr); @@ -3949,8 +3963,8 @@ TEST_F(BluetoothChromeOSTest, DeviceId) { TEST_F(BluetoothChromeOSTest, GetConnectionInfoForDisconnectedDevice) { GetAdapter(); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); // Calling GetConnectionInfo for an unconnected device should return a result // in which all fields are filled with BluetoothDevice::kUnknownPower. @@ -3965,8 +3979,8 @@ TEST_F(BluetoothChromeOSTest, GetConnectionInfoForDisconnectedDevice) { TEST_F(BluetoothChromeOSTest, GetConnectionInfoForConnectedDevice) { GetAdapter(); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); device->Connect(nullptr, GetCallback(), base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback, @@ -4011,8 +4025,9 @@ TEST_F(BluetoothChromeOSTest, Shutdown) { EXPECT_TRUE(adapter_->IsDiscoverable()); EXPECT_TRUE(adapter_->IsDiscovering()); EXPECT_EQ(2U, adapter_->GetDevices().size()); - EXPECT_NE(nullptr, adapter_->GetDevice( - FakeBluetoothDeviceClient::kPairedDeviceAddress)); + EXPECT_NE(nullptr, + adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress)); EXPECT_NE(dbus::ObjectPath(""), static_cast<BluetoothAdapterChromeOS*>( adapter_.get())->object_path()); @@ -4089,7 +4104,7 @@ TEST_F(BluetoothChromeOSTest, Shutdown) { FakeBluetoothProfileServiceProviderDelegate profile_delegate; adapter_chrome_os->UseProfile( BluetoothUUID(), dbus::ObjectPath(""), - BluetoothProfileManagerClient::Options(), &profile_delegate, + bluez::BluetoothProfileManagerClient::Options(), &profile_delegate, base::Bind(&BluetoothChromeOSTest::ProfileRegisteredCallback, base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback, @@ -4109,7 +4124,8 @@ TEST_F(BluetoothChromeOSTest, Shutdown) { adapter_chrome_os->DeviceRemoved(dbus::ObjectPath("")); adapter_chrome_os->DevicePropertyChanged(dbus::ObjectPath(""), ""); adapter_chrome_os->InputPropertyChanged(dbus::ObjectPath(""), ""); - // BluetoothAgentServiceProvider::Delegate omitted, dbus will be shutdown, + // bluez::BluetoothAgentServiceProvider::Delegate omitted, dbus will be + // shutdown, // with the exception of Released. adapter_chrome_os->Released(); @@ -4166,7 +4182,7 @@ TEST_F(BluetoothChromeOSTest, Shutdown) { // UseProfile to be set first, do so again here just before calling them. adapter_chrome_os->UseProfile( BluetoothUUID(), dbus::ObjectPath(""), - BluetoothProfileManagerClient::Options(), &profile_delegate, + bluez::BluetoothProfileManagerClient::Options(), &profile_delegate, base::Bind(&BluetoothChromeOSTest::ProfileRegisteredCallback, base::Unretained(this)), base::Bind(&BluetoothChromeOSTest::ErrorCompletionCallback, @@ -4201,8 +4217,9 @@ TEST_F(BluetoothChromeOSTest, Shutdown) { EXPECT_EQ(1, error_callback_count_--) << "StartDiscoverySession error"; EXPECT_EQ(0U, adapter_->GetDevices().size()); - EXPECT_EQ(nullptr, adapter_->GetDevice( - FakeBluetoothDeviceClient::kPairedDeviceAddress)); + EXPECT_EQ(nullptr, + adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress)); TestPairingDelegate pairing_delegate2; adapter_->AddPairingDelegate( &pairing_delegate2, BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH); diff --git a/device/bluetooth/bluetooth_device_chromeos.cc b/device/bluetooth/bluetooth_device_chromeos.cc index 898fd51..ea4a168 100644 --- a/device/bluetooth/bluetooth_device_chromeos.cc +++ b/device/bluetooth/bluetooth_device_chromeos.cc @@ -11,11 +11,6 @@ #include "base/metrics/histogram.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" -#include "chromeos/dbus/bluetooth_adapter_client.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_gatt_service_client.h" -#include "chromeos/dbus/bluetooth_input_client.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "dbus/bus.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" #include "device/bluetooth/bluetooth_gatt_connection_chromeos.h" @@ -25,6 +20,11 @@ #include "device/bluetooth/bluetooth_socket_chromeos.h" #include "device/bluetooth/bluetooth_socket_thread.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/bluetooth/dbus/bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/bluetooth_device_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h" +#include "device/bluetooth/dbus/bluetooth_input_client.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" #include "third_party/cros_system_api/dbus/service_constants.h" using device::BluetoothDevice; @@ -55,10 +55,9 @@ void ParseModalias(const dbus::ObjectPath& object_path, uint16* vendor_id, uint16* product_id, uint16* device_id) { - chromeos::BluetoothDeviceClient::Properties* properties = - chromeos::DBusThreadManager::Get() - ->GetBluetoothDeviceClient() - ->GetProperties(object_path); + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( + object_path); DCHECK(properties); std::string modalias = properties->modalias.value(); @@ -153,11 +152,14 @@ BluetoothDeviceChromeOS::BluetoothDeviceChromeOS( ui_task_runner_(ui_task_runner), socket_thread_(socket_thread), weak_ptr_factory_(this) { - DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this); + bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient()->AddObserver( + this); // Add all known GATT services. const std::vector<dbus::ObjectPath> gatt_services = - DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetServices(); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattServiceClient() + ->GetServices(); for (std::vector<dbus::ObjectPath>::const_iterator it = gatt_services.begin(); it != gatt_services.end(); ++it) { GattServiceAdded(*it); @@ -165,8 +167,9 @@ BluetoothDeviceChromeOS::BluetoothDeviceChromeOS( } BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() { - DBusThreadManager::Get()->GetBluetoothGattServiceClient()->RemoveObserver( - this); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattServiceClient() + ->RemoveObserver(this); // Copy the GATT services list here and clear the original so that when we // send GattServiceRemoved(), GetGattServices() returns no services. @@ -180,8 +183,8 @@ BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() { } uint32 BluetoothDeviceChromeOS::GetBluetoothClass() const { - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); DCHECK(properties); @@ -189,8 +192,8 @@ uint32 BluetoothDeviceChromeOS::GetBluetoothClass() const { } std::string BluetoothDeviceChromeOS::GetDeviceName() const { - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); DCHECK(properties); @@ -210,8 +213,8 @@ void BluetoothDeviceChromeOS::DisconnectGatt() { } std::string BluetoothDeviceChromeOS::GetAddress() const { - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); DCHECK(properties); @@ -244,8 +247,8 @@ uint16 BluetoothDeviceChromeOS::GetDeviceID() const { } bool BluetoothDeviceChromeOS::IsPaired() const { - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); DCHECK(properties); @@ -256,8 +259,8 @@ bool BluetoothDeviceChromeOS::IsPaired() const { } bool BluetoothDeviceChromeOS::IsConnected() const { - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); DCHECK(properties); @@ -270,8 +273,8 @@ bool BluetoothDeviceChromeOS::IsGattConnected() const { } bool BluetoothDeviceChromeOS::IsConnectable() const { - BluetoothInputClient::Properties* input_properties = - DBusThreadManager::Get()->GetBluetoothInputClient()->GetProperties( + bluez::BluetoothInputClient::Properties* input_properties = + bluez::BluezDBusManager::Get()->GetBluetoothInputClient()->GetProperties( object_path_); // GetProperties returns NULL when the device does not implement the given // interface. Non HID devices are normally connectable. @@ -286,8 +289,8 @@ bool BluetoothDeviceChromeOS::IsConnecting() const { } BluetoothDeviceChromeOS::UUIDList BluetoothDeviceChromeOS::GetUUIDs() const { - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); DCHECK(properties); @@ -303,8 +306,8 @@ BluetoothDeviceChromeOS::UUIDList BluetoothDeviceChromeOS::GetUUIDs() const { } int16 BluetoothDeviceChromeOS::GetInquiryRSSI() const { - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); DCHECK(properties); @@ -315,8 +318,8 @@ int16 BluetoothDeviceChromeOS::GetInquiryRSSI() const { } int16 BluetoothDeviceChromeOS::GetInquiryTxPower() const { - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); DCHECK(properties); @@ -342,7 +345,7 @@ void BluetoothDeviceChromeOS::GetConnectionInfo( const ConnectionInfoCallback& callback) { // DBus method call should gracefully return an error if the device is not // currently connected. - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetConnInfo( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetConnInfo( object_path_, base::Bind(&BluetoothDeviceChromeOS::OnGetConnInfo, weak_ptr_factory_.GetWeakPtr(), callback), base::Bind(&BluetoothDeviceChromeOS::OnGetConnInfoError, @@ -366,7 +369,7 @@ void BluetoothDeviceChromeOS::Connect( // Initiate high-security connection with pairing. BeginPairing(pairing_delegate); - DBusThreadManager::Get()->GetBluetoothDeviceClient()->Pair( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Pair( object_path_, base::Bind(&BluetoothDeviceChromeOS::OnPairDuringConnect, weak_ptr_factory_.GetWeakPtr(), callback, error_callback), @@ -382,7 +385,7 @@ void BluetoothDeviceChromeOS::Pair( DCHECK(pairing_delegate); BeginPairing(pairing_delegate); - DBusThreadManager::Get()->GetBluetoothDeviceClient()->Pair( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Pair( object_path_, base::Bind(&BluetoothDeviceChromeOS::OnPair, weak_ptr_factory_.GetWeakPtr(), callback), base::Bind(&BluetoothDeviceChromeOS::OnPairError, @@ -429,7 +432,7 @@ void BluetoothDeviceChromeOS::CancelPairing() { if (!canceled) { VLOG(1) << object_path_.value() << ": No pairing context or callback. " << "Sending explicit cancel"; - DBusThreadManager::Get()->GetBluetoothDeviceClient()->CancelPairing( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->CancelPairing( object_path_, base::Bind(&base::DoNothing), base::Bind(&BluetoothDeviceChromeOS::OnCancelPairingError, weak_ptr_factory_.GetWeakPtr())); @@ -445,7 +448,7 @@ void BluetoothDeviceChromeOS::CancelPairing() { void BluetoothDeviceChromeOS::Disconnect(const base::Closure& callback, const ErrorCallback& error_callback) { VLOG(1) << object_path_.value() << ": Disconnecting"; - DBusThreadManager::Get()->GetBluetoothDeviceClient()->Disconnect( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Disconnect( object_path_, base::Bind(&BluetoothDeviceChromeOS::OnDisconnect, weak_ptr_factory_.GetWeakPtr(), callback), base::Bind(&BluetoothDeviceChromeOS::OnDisconnectError, @@ -454,7 +457,7 @@ void BluetoothDeviceChromeOS::Disconnect(const base::Closure& callback, void BluetoothDeviceChromeOS::Forget(const ErrorCallback& error_callback) { VLOG(1) << object_path_.value() << ": Removing device"; - DBusThreadManager::Get()->GetBluetoothAdapterClient()->RemoveDevice( + bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()->RemoveDevice( adapter()->object_path(), object_path_, base::Bind(&base::DoNothing), base::Bind(&BluetoothDeviceChromeOS::OnForgetError, weak_ptr_factory_.GetWeakPtr(), error_callback)); @@ -533,9 +536,10 @@ void BluetoothDeviceChromeOS::GattServiceAdded( return; } - BluetoothGattServiceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetProperties( - object_path); + bluez::BluetoothGattServiceClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothGattServiceClient() + ->GetProperties(object_path); DCHECK(properties); if (properties->device.value() != object_path_) { VLOG(2) << "Remote GATT service does not belong to this device."; @@ -603,7 +607,7 @@ void BluetoothDeviceChromeOS::ConnectInternal( const base::Closure& callback, const ConnectErrorCallback& error_callback) { VLOG(1) << object_path_.value() << ": Connecting"; - DBusThreadManager::Get()->GetBluetoothDeviceClient()->Connect( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->Connect( object_path_, base::Bind(&BluetoothDeviceChromeOS::OnConnect, weak_ptr_factory_.GetWeakPtr(), after_pairing, callback), @@ -731,7 +735,7 @@ void BluetoothDeviceChromeOS::SetTrusted() { // first; there's no harm in doing this and it solves any race conditions // with the property becoming true or false and this call happening before // we get the D-Bus signal about the earlier change. - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothDeviceClient() ->GetProperties(object_path_) ->trusted.Set(true, base::Bind(&BluetoothDeviceChromeOS::OnSetTrusted, diff --git a/device/bluetooth/bluetooth_device_chromeos.h b/device/bluetooth/bluetooth_device_chromeos.h index 7f66a43..544fdaf 100644 --- a/device/bluetooth/bluetooth_device_chromeos.h +++ b/device/bluetooth/bluetooth_device_chromeos.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H -#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H +#ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ #include <string> @@ -11,11 +11,11 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_gatt_service_client.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_device_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h" namespace device { class BluetoothSocketThread; @@ -35,7 +35,7 @@ class BluetoothPairingChromeOS; // thread. class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceChromeOS : public device::BluetoothDevice, - public BluetoothGattServiceClient::Observer { + public bluez::BluetoothGattServiceClient::Observer { public: // BluetoothDevice override uint32 GetBluetoothClass() const override; @@ -118,7 +118,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceChromeOS scoped_refptr<device::BluetoothSocketThread> socket_thread); ~BluetoothDeviceChromeOS() override; - // BluetoothGattServiceClient::Observer overrides. + // bluez::BluetoothGattServiceClient::Observer overrides. void GattServiceAdded(const dbus::ObjectPath& object_path) override; void GattServiceRemoved(const dbus::ObjectPath& object_path) override; @@ -215,4 +215,4 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceChromeOS } // namespace chromeos -#endif // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H +#endif // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ diff --git a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc index 5cf067c..cf9e441 100644 --- a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc @@ -5,14 +5,6 @@ #include "base/memory/scoped_vector.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/fake_bluetooth_adapter_client.h" -#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h" -#include "chromeos/dbus/fake_bluetooth_device_client.h" -#include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h" -#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h" -#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h" -#include "chromeos/dbus/fake_bluetooth_input_client.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter_factory.h" @@ -23,6 +15,14 @@ #include "device/bluetooth/bluetooth_gatt_notify_session.h" #include "device/bluetooth/bluetooth_gatt_service.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_device_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_input_client.h" #include "device/bluetooth/test/test_bluetooth_adapter_observer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -41,11 +41,11 @@ namespace chromeos { namespace { const BluetoothUUID kHeartRateMeasurementUUID( - FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID); + bluez::FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID); const BluetoothUUID kBodySensorLocationUUID( - FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID); + bluez::FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID); const BluetoothUUID kHeartRateControlPointUUID( - FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID); + bluez::FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID); // Compares GATT characteristic/descriptor values. Returns true, if the values // are equal. @@ -70,32 +70,36 @@ class BluetoothGattChromeOSTest : public testing::Test { } void SetUp() override { - scoped_ptr<DBusThreadManagerSetter> dbus_setter = - chromeos::DBusThreadManager::GetSetterForTesting(); - fake_bluetooth_device_client_ = new FakeBluetoothDeviceClient; - fake_bluetooth_gatt_service_client_ = new FakeBluetoothGattServiceClient; + scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter = + bluez::BluezDBusManager::GetSetterForTesting(); + fake_bluetooth_device_client_ = new bluez::FakeBluetoothDeviceClient; + fake_bluetooth_gatt_service_client_ = + new bluez::FakeBluetoothGattServiceClient; fake_bluetooth_gatt_characteristic_client_ = - new FakeBluetoothGattCharacteristicClient; + new bluez::FakeBluetoothGattCharacteristicClient; fake_bluetooth_gatt_descriptor_client_ = - new FakeBluetoothGattDescriptorClient; + new bluez::FakeBluetoothGattDescriptorClient; dbus_setter->SetBluetoothDeviceClient( - scoped_ptr<BluetoothDeviceClient>(fake_bluetooth_device_client_)); + scoped_ptr<bluez::BluetoothDeviceClient>( + fake_bluetooth_device_client_)); dbus_setter->SetBluetoothGattServiceClient( - scoped_ptr<BluetoothGattServiceClient>( + scoped_ptr<bluez::BluetoothGattServiceClient>( fake_bluetooth_gatt_service_client_)); dbus_setter->SetBluetoothGattCharacteristicClient( - scoped_ptr<BluetoothGattCharacteristicClient>( + scoped_ptr<bluez::BluetoothGattCharacteristicClient>( fake_bluetooth_gatt_characteristic_client_)); dbus_setter->SetBluetoothGattDescriptorClient( - scoped_ptr<BluetoothGattDescriptorClient>( + scoped_ptr<bluez::BluetoothGattDescriptorClient>( fake_bluetooth_gatt_descriptor_client_)); dbus_setter->SetBluetoothAdapterClient( - scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient)); + scoped_ptr<bluez::BluetoothAdapterClient>( + new bluez::FakeBluetoothAdapterClient)); dbus_setter->SetBluetoothInputClient( - scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient)); + scoped_ptr<bluez::BluetoothInputClient>( + new bluez::FakeBluetoothInputClient)); dbus_setter->SetBluetoothAgentManagerClient( - scoped_ptr<BluetoothAgentManagerClient>( - new FakeBluetoothAgentManagerClient)); + scoped_ptr<bluez::BluetoothAgentManagerClient>( + new bluez::FakeBluetoothAgentManagerClient)); GetAdapter(); @@ -110,7 +114,7 @@ class BluetoothGattChromeOSTest : public testing::Test { adapter_ = NULL; update_sessions_.clear(); gatt_conn_.reset(); - DBusThreadManager::Shutdown(); + bluez::BluezDBusManager::Shutdown(); } void GetAdapter() { @@ -173,11 +177,12 @@ class BluetoothGattChromeOSTest : public testing::Test { base::MessageLoop message_loop_; - FakeBluetoothDeviceClient* fake_bluetooth_device_client_; - FakeBluetoothGattServiceClient* fake_bluetooth_gatt_service_client_; - FakeBluetoothGattCharacteristicClient* + bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client_; + bluez::FakeBluetoothGattServiceClient* fake_bluetooth_gatt_service_client_; + bluez::FakeBluetoothGattCharacteristicClient* fake_bluetooth_gatt_characteristic_client_; - FakeBluetoothGattDescriptorClient* fake_bluetooth_gatt_descriptor_client_; + bluez::FakeBluetoothGattDescriptorClient* + fake_bluetooth_gatt_descriptor_client_; scoped_ptr<device::BluetoothGattConnection> gatt_conn_; ScopedVector<BluetoothGattNotifySession> update_sessions_; scoped_refptr<BluetoothAdapter> adapter_; @@ -190,10 +195,10 @@ class BluetoothGattChromeOSTest : public testing::Test { TEST_F(BluetoothGattChromeOSTest, GattConnection) { fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); ASSERT_FALSE(device->IsConnected()); ASSERT_FALSE(gatt_conn_.get()); @@ -211,7 +216,7 @@ TEST_F(BluetoothGattChromeOSTest, GattConnection) { EXPECT_TRUE(device->IsConnected()); ASSERT_TRUE(gatt_conn_.get()); EXPECT_TRUE(gatt_conn_->IsConnected()); - EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress, + EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress, gatt_conn_->GetDeviceAddress()); gatt_conn_->Disconnect(); @@ -253,8 +258,8 @@ TEST_F(BluetoothGattChromeOSTest, GattConnection) { EXPECT_TRUE(gatt_conn_->IsConnected()); fake_bluetooth_device_client_->RemoveDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); ASSERT_TRUE(gatt_conn_.get()); EXPECT_FALSE(gatt_conn_->IsConnected()); } @@ -263,10 +268,10 @@ TEST_F(BluetoothGattChromeOSTest, GattServiceAddedAndRemoved) { // Create a fake LE device. We store the device pointer here because this is a // test. It's unsafe to do this in production as the device might get deleted. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); TestBluetoothAdapterObserver observer(adapter_); @@ -279,14 +284,14 @@ TEST_F(BluetoothGattChromeOSTest, GattServiceAddedAndRemoved) { // Expose the fake Heart Rate Service. fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); EXPECT_EQ(1, observer.gatt_service_added_count()); EXPECT_EQ(0, observer.gatt_service_removed_count()); EXPECT_FALSE(observer.last_gatt_service_id().empty()); EXPECT_EQ(1U, device->GetGattServices().size()); - EXPECT_EQ( - BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), - observer.last_gatt_service_uuid()); + EXPECT_EQ(BluetoothUUID( + bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID), + observer.last_gatt_service_uuid()); BluetoothGattService* service = device->GetGattService(observer.last_gatt_service_id()); @@ -306,9 +311,9 @@ TEST_F(BluetoothGattChromeOSTest, GattServiceAddedAndRemoved) { EXPECT_EQ(1, observer.gatt_service_removed_count()); EXPECT_FALSE(observer.last_gatt_service_id().empty()); EXPECT_TRUE(device->GetGattServices().empty()); - EXPECT_EQ( - BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), - observer.last_gatt_service_uuid()); + EXPECT_EQ(BluetoothUUID( + bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID), + observer.last_gatt_service_uuid()); EXPECT_EQ(NULL, device->GetGattService(observer.last_gatt_service_id())); @@ -316,14 +321,14 @@ TEST_F(BluetoothGattChromeOSTest, GattServiceAddedAndRemoved) { observer.last_gatt_service_uuid() = BluetoothUUID(); observer.last_gatt_service_id().clear(); fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); EXPECT_EQ(2, observer.gatt_service_added_count()); EXPECT_EQ(1, observer.gatt_service_removed_count()); EXPECT_FALSE(observer.last_gatt_service_id().empty()); EXPECT_EQ(1U, device->GetGattServices().size()); - EXPECT_EQ( - BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), - observer.last_gatt_service_uuid()); + EXPECT_EQ(BluetoothUUID( + bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID), + observer.last_gatt_service_uuid()); // The object |service| points to should have been deallocated. |device| // should contain a brand new instance. @@ -339,30 +344,30 @@ TEST_F(BluetoothGattChromeOSTest, GattServiceAddedAndRemoved) { observer.last_gatt_service_uuid() = BluetoothUUID(); observer.last_gatt_service_id().clear(); fake_bluetooth_device_client_->RemoveDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); EXPECT_EQ(2, observer.gatt_service_added_count()); EXPECT_EQ(2, observer.gatt_service_removed_count()); EXPECT_FALSE(observer.last_gatt_service_id().empty()); - EXPECT_EQ( - BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), - observer.last_gatt_service_uuid()); - EXPECT_EQ(NULL, - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress)); + EXPECT_EQ(BluetoothUUID( + bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID), + observer.last_gatt_service_uuid()); + EXPECT_EQ(NULL, adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kLowEnergyAddress)); } TEST_F(BluetoothGattChromeOSTest, ServicesDiscovered) { // Create a fake LE device. We store the device pointer here because this is a // test. It's unsafe to do this in production as the device might get deleted. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); - FakeBluetoothDeviceClient::Properties* properties = + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); + bluez::FakeBluetoothDeviceClient::Properties* properties = fake_bluetooth_device_client_->GetProperties( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); ASSERT_TRUE(device); @@ -372,23 +377,23 @@ TEST_F(BluetoothGattChromeOSTest, ServicesDiscovered) { // Expose the fake Heart Rate Service. fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); // Notify that all services have been discovered. properties->gatt_services.ReplaceValue( fake_bluetooth_gatt_service_client_->GetServices()); EXPECT_EQ(1, observer.gatt_services_discovered_count()); EXPECT_EQ(device, observer.last_device()); - EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress, + EXPECT_EQ(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress, observer.last_device_address()); } TEST_F(BluetoothGattChromeOSTest, GattCharacteristicAddedAndRemoved) { fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); TestBluetoothAdapterObserver observer(adapter_); @@ -396,7 +401,7 @@ TEST_F(BluetoothGattChromeOSTest, GattCharacteristicAddedAndRemoved) { // Expose the fake Heart Rate service. This will asynchronously expose // characteristics. fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); ASSERT_EQ(1, observer.gatt_service_added_count()); BluetoothGattService* service = @@ -453,10 +458,10 @@ TEST_F(BluetoothGattChromeOSTest, GattCharacteristicAddedAndRemoved) { TEST_F(BluetoothGattChromeOSTest, GattDescriptorAddedAndRemoved) { fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); TestBluetoothAdapterObserver observer(adapter_); @@ -464,7 +469,7 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorAddedAndRemoved) { // Expose the fake Heart Rate service. This will asynchronously expose // characteristics. fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); ASSERT_EQ(1, observer.gatt_service_added_count()); BluetoothGattService* service = @@ -525,7 +530,7 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorAddedAndRemoved) { observer.last_gatt_descriptor_uuid() = BluetoothUUID(); fake_bluetooth_gatt_descriptor_client_->ExposeDescriptor( dbus::ObjectPath(characteristic->GetIdentifier()), - FakeBluetoothGattDescriptorClient:: + bluez::FakeBluetoothGattDescriptorClient:: kClientCharacteristicConfigurationUUID); EXPECT_EQ(0, observer.gatt_service_changed_count()); EXPECT_EQ(1U, characteristic->GetDescriptors().size()); @@ -549,10 +554,10 @@ TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) { // Create the fake D-Bus objects. fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); while (!fake_bluetooth_gatt_characteristic_client_->IsHeartRateVisible()) base::RunLoop().RunUntilIdle(); ASSERT_TRUE(fake_bluetooth_gatt_service_client_->IsHeartRateVisible()); @@ -561,7 +566,7 @@ TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) { // Create the adapter. This should create all the GATT objects. GetAdapter(); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); EXPECT_EQ(1U, device->GetGattServices().size()); @@ -569,9 +574,9 @@ TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) { ASSERT_TRUE(service); EXPECT_FALSE(service->IsLocal()); EXPECT_TRUE(service->IsPrimary()); - EXPECT_EQ( - BluetoothUUID(FakeBluetoothGattServiceClient::kHeartRateServiceUUID), - service->GetUUID()); + EXPECT_EQ(BluetoothUUID( + bluez::FakeBluetoothGattServiceClient::kHeartRateServiceUUID), + service->GetUUID()); EXPECT_EQ(service, device->GetGattServices()[0]); EXPECT_EQ(service, device->GetGattService(service->GetIdentifier())); EXPECT_FALSE(service->IsLocal()); @@ -581,8 +586,8 @@ TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) { fake_bluetooth_gatt_characteristic_client_-> GetBodySensorLocationPath().value()); ASSERT_TRUE(characteristic); - EXPECT_EQ(BluetoothUUID( - FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID), + EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient:: + kBodySensorLocationUUID), characteristic->GetUUID()); EXPECT_FALSE(characteristic->IsLocal()); EXPECT_TRUE(characteristic->GetDescriptors().empty()); @@ -591,10 +596,9 @@ TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) { fake_bluetooth_gatt_characteristic_client_-> GetHeartRateControlPointPath().value()); ASSERT_TRUE(characteristic); - EXPECT_EQ( - BluetoothUUID( - FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID), - characteristic->GetUUID()); + EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient:: + kHeartRateControlPointUUID), + characteristic->GetUUID()); EXPECT_FALSE(characteristic->IsLocal()); EXPECT_TRUE(characteristic->GetDescriptors().empty()); @@ -602,10 +606,9 @@ TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) { fake_bluetooth_gatt_characteristic_client_-> GetHeartRateMeasurementPath().value()); ASSERT_TRUE(characteristic); - EXPECT_EQ( - BluetoothUUID( - FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID), - characteristic->GetUUID()); + EXPECT_EQ(BluetoothUUID(bluez::FakeBluetoothGattCharacteristicClient:: + kHeartRateMeasurementUUID), + characteristic->GetUUID()); EXPECT_FALSE(characteristic->IsLocal()); EXPECT_EQ(1U, characteristic->GetDescriptors().size()); @@ -618,10 +621,10 @@ TEST_F(BluetoothGattChromeOSTest, AdapterAddedAfterGattService) { TEST_F(BluetoothGattChromeOSTest, GattCharacteristicValue) { fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); TestBluetoothAdapterObserver observer(adapter_); @@ -629,7 +632,7 @@ TEST_F(BluetoothGattChromeOSTest, GattCharacteristicValue) { // Expose the fake Heart Rate service. This will asynchronously expose // characteristics. fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); ASSERT_EQ(1, observer.gatt_service_added_count()); BluetoothGattService* service = @@ -833,10 +836,10 @@ TEST_F(BluetoothGattChromeOSTest, GattCharacteristicValue) { TEST_F(BluetoothGattChromeOSTest, GattCharacteristicProperties) { fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); TestBluetoothAdapterObserver observer(adapter_); @@ -844,7 +847,7 @@ TEST_F(BluetoothGattChromeOSTest, GattCharacteristicProperties) { // Expose the fake Heart Rate service. This will asynchronously expose // characteristics. fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothGattService* service = device->GetGattService(observer.last_gatt_service_id()); @@ -875,10 +878,10 @@ TEST_F(BluetoothGattChromeOSTest, GattCharacteristicProperties) { TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) { fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); TestBluetoothAdapterObserver observer(adapter_); @@ -886,7 +889,7 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) { // Expose the fake Heart Rate service. This will asynchronously expose // characteristics. fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); ASSERT_EQ(1, observer.gatt_service_added_count()); BluetoothGattService* service = @@ -998,10 +1001,10 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) { TEST_F(BluetoothGattChromeOSTest, NotifySessions) { fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); TestBluetoothAdapterObserver observer(adapter_); @@ -1009,7 +1012,7 @@ TEST_F(BluetoothGattChromeOSTest, NotifySessions) { // Expose the fake Heart Rate service. This will asynchronously expose // characteristics. fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); ASSERT_EQ(1, observer.gatt_service_added_count()); BluetoothGattService* service = @@ -1147,10 +1150,10 @@ TEST_F(BluetoothGattChromeOSTest, NotifySessions) { TEST_F(BluetoothGattChromeOSTest, NotifySessionsMadeInactive) { fake_bluetooth_device_client_->CreateDevice( - dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + adapter_->GetDevice(bluez::FakeBluetoothDeviceClient::kLowEnergyAddress); ASSERT_TRUE(device); TestBluetoothAdapterObserver observer(adapter_); @@ -1158,7 +1161,7 @@ TEST_F(BluetoothGattChromeOSTest, NotifySessionsMadeInactive) { // Expose the fake Heart Rate service. This will asynchronously expose // characteristics. fake_bluetooth_gatt_service_client_->ExposeHeartRateService( - dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + dbus::ObjectPath(bluez::FakeBluetoothDeviceClient::kLowEnergyPath)); ASSERT_EQ(1, observer.gatt_service_added_count()); BluetoothGattService* service = diff --git a/device/bluetooth/bluetooth_gatt_connection_chromeos.cc b/device/bluetooth/bluetooth_gatt_connection_chromeos.cc index 6c16db8..57aaa4d 100644 --- a/device/bluetooth/bluetooth_gatt_connection_chromeos.cc +++ b/device/bluetooth/bluetooth_gatt_connection_chromeos.cc @@ -6,9 +6,9 @@ #include "base/bind.h" #include "base/logging.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" namespace chromeos { @@ -23,11 +23,12 @@ BluetoothGattConnectionChromeOS::BluetoothGattConnectionChromeOS( DCHECK(!device_address_.empty()); DCHECK(object_path_.IsValid()); - DBusThreadManager::Get()->GetBluetoothDeviceClient()->AddObserver(this); + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->AddObserver(this); } BluetoothGattConnectionChromeOS::~BluetoothGattConnectionChromeOS() { - DBusThreadManager::Get()->GetBluetoothDeviceClient()->RemoveObserver(this); + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->RemoveObserver( + this); Disconnect(); } @@ -40,8 +41,8 @@ bool BluetoothGattConnectionChromeOS::IsConnected() { if (!connected_) return false; - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); if (!properties || !properties->connected.value()) connected_ = false; @@ -82,8 +83,8 @@ void BluetoothGattConnectionChromeOS::DevicePropertyChanged( if (!connected_) return; - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties( + bluez::BluetoothDeviceClient::Properties* properties = + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->GetProperties( object_path_); if (!properties) { diff --git a/device/bluetooth/bluetooth_gatt_connection_chromeos.h b/device/bluetooth/bluetooth_gatt_connection_chromeos.h index 66c1a1a..6e40283 100644 --- a/device/bluetooth/bluetooth_gatt_connection_chromeos.h +++ b/device/bluetooth/bluetooth_gatt_connection_chromeos.h @@ -9,9 +9,9 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" -#include "chromeos/dbus/bluetooth_device_client.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_gatt_connection.h" +#include "device/bluetooth/dbus/bluetooth_device_client.h" namespace device { @@ -23,8 +23,9 @@ namespace chromeos { // BluetoothGattConnectionChromeOS implements BluetoothGattConnection for the // Chrome OS platform. -class BluetoothGattConnectionChromeOS : public device::BluetoothGattConnection, - public BluetoothDeviceClient::Observer { +class BluetoothGattConnectionChromeOS + : public device::BluetoothGattConnection, + public bluez::BluetoothDeviceClient::Observer { public: explicit BluetoothGattConnectionChromeOS( scoped_refptr<device::BluetoothAdapter> adapter, @@ -37,7 +38,7 @@ class BluetoothGattConnectionChromeOS : public device::BluetoothGattConnection, void Disconnect() override; private: - // chromeos::BluetoothDeviceClient::Observer overrides. + // bluez::Bluetooth$1Client::Observer overrides. void DeviceRemoved(const dbus::ObjectPath& object_path) override; void DevicePropertyChanged(const dbus::ObjectPath& object_path, const std::string& property_name) override; diff --git a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc b/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc index ba7b843..02f7ed8 100644 --- a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc +++ b/device/bluetooth/bluetooth_gatt_notify_session_chromeos.cc @@ -6,11 +6,11 @@ #include "base/bind.h" #include "base/logging.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_gatt_service.h" #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" namespace chromeos { @@ -32,12 +32,13 @@ BluetoothGattNotifySessionChromeOS::BluetoothGattNotifySessionChromeOS( DCHECK(!characteristic_id_.empty()); DCHECK(object_path_.IsValid()); - DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->AddObserver( - this); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattCharacteristicClient() + ->AddObserver(this); } BluetoothGattNotifySessionChromeOS::~BluetoothGattNotifySessionChromeOS() { - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->RemoveObserver(this); Stop(base::Bind(&base::DoNothing)); @@ -58,11 +59,12 @@ bool BluetoothGattNotifySessionChromeOS::IsActive() { // actually active, since the characteristic might have stopped sending // notifications yet this method was called before we processed the // observer event (e.g. because somebody else called this method in their - // BluetoothGattCharacteristicClient::Observer implementation, which was + // bluez::BluetoothGattCharacteristicClient::Observer implementation, which + // was // called before ours). Check the client to see if notifications are still // being sent. - BluetoothGattCharacteristicClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattCharacteristicClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->GetProperties(object_path_); if (!properties || !properties->notifying.value()) @@ -115,8 +117,8 @@ void BluetoothGattNotifySessionChromeOS::GattCharacteristicPropertyChanged( if (!active_) return; - BluetoothGattCharacteristicClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattCharacteristicClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->GetProperties(object_path_); if (!properties) { diff --git a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h b/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h index 245a72f..ef6e8da 100644 --- a/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h +++ b/device/bluetooth/bluetooth_gatt_notify_session_chromeos.h @@ -8,8 +8,8 @@ #include <string> #include "base/callback.h" -#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h" #include "device/bluetooth/bluetooth_gatt_notify_session.h" +#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" namespace device { @@ -25,7 +25,7 @@ class BluetoothRemoteGattCharacteristicChromeOS; // BluetoothGattNotifySession for the Chrome OS platform. class BluetoothGattNotifySessionChromeOS : public device::BluetoothGattNotifySession, - public BluetoothGattCharacteristicClient::Observer { + public bluez::BluetoothGattCharacteristicClient::Observer { public: ~BluetoothGattNotifySessionChromeOS() override; @@ -44,7 +44,7 @@ class BluetoothGattNotifySessionChromeOS const std::string& characteristic_identifier, const dbus::ObjectPath& characteristic_path); - // BluetoothGattCharacteristicClient::Observer overrides. + // bluez::BluetoothGattCharacteristicClient::Observer overrides. void GattCharacteristicRemoved(const dbus::ObjectPath& object_path) override; void GattCharacteristicPropertyChanged( const dbus::ObjectPath& object_path, diff --git a/device/bluetooth/bluetooth_pairing_chromeos.cc b/device/bluetooth/bluetooth_pairing_chromeos.cc index 2bc67cb..4541fb3 100644 --- a/device/bluetooth/bluetooth_pairing_chromeos.cc +++ b/device/bluetooth/bluetooth_pairing_chromeos.cc @@ -55,25 +55,26 @@ BluetoothPairingChromeOS::~BluetoothPairingChromeOS() { } if (!pincode_callback_.is_null()) { - pincode_callback_.Run(BluetoothAgentServiceProvider::Delegate::CANCELLED, - ""); + pincode_callback_.Run( + bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED, ""); } if (!passkey_callback_.is_null()) { - passkey_callback_.Run(BluetoothAgentServiceProvider::Delegate::CANCELLED, - 0); + passkey_callback_.Run( + bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED, 0); } if (!confirmation_callback_.is_null()) { confirmation_callback_.Run( - BluetoothAgentServiceProvider::Delegate::CANCELLED); + bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED); } pairing_delegate_ = NULL; } void BluetoothPairingChromeOS::RequestPinCode( - const BluetoothAgentServiceProvider::Delegate::PinCodeCallback& callback) { + const bluez::BluetoothAgentServiceProvider::Delegate::PinCodeCallback& + callback) { UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", UMA_PAIRING_METHOD_REQUEST_PINCODE, UMA_PAIRING_METHOD_COUNT); @@ -92,7 +93,7 @@ void BluetoothPairingChromeOS::SetPinCode(const std::string& pincode) { if (pincode_callback_.is_null()) return; - pincode_callback_.Run(BluetoothAgentServiceProvider::Delegate::SUCCESS, + pincode_callback_.Run(bluez::BluetoothAgentServiceProvider::Delegate::SUCCESS, pincode); pincode_callback_.Reset(); @@ -120,7 +121,8 @@ void BluetoothPairingChromeOS::DisplayPinCode(const std::string& pincode) { } void BluetoothPairingChromeOS::RequestPasskey( - const BluetoothAgentServiceProvider::Delegate::PasskeyCallback& callback) { + const bluez::BluetoothAgentServiceProvider::Delegate::PasskeyCallback& + callback) { UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", UMA_PAIRING_METHOD_REQUEST_PASSKEY, UMA_PAIRING_METHOD_COUNT); @@ -139,7 +141,7 @@ void BluetoothPairingChromeOS::SetPasskey(uint32 passkey) { if (passkey_callback_.is_null()) return; - passkey_callback_.Run(BluetoothAgentServiceProvider::Delegate::SUCCESS, + passkey_callback_.Run(bluez::BluetoothAgentServiceProvider::Delegate::SUCCESS, passkey); passkey_callback_.Reset(); @@ -158,7 +160,6 @@ void BluetoothPairingChromeOS::DisplayPasskey(uint32 passkey) { ResetCallbacks(); pairing_delegate_used_ = true; pairing_delegate_->DisplayPasskey(device_, passkey); - } void BluetoothPairingChromeOS::KeysEntered(uint16 entered) { @@ -174,7 +175,7 @@ void BluetoothPairingChromeOS::KeysEntered(uint16 entered) { void BluetoothPairingChromeOS::RequestConfirmation( uint32 passkey, - const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback& + const bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback& callback) { UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", UMA_PAIRING_METHOD_CONFIRM_PASSKEY, @@ -187,7 +188,7 @@ void BluetoothPairingChromeOS::RequestConfirmation( } void BluetoothPairingChromeOS::RequestAuthorization( - const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback& + const bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback& callback) { UMA_HISTOGRAM_ENUMERATION("Bluetooth.PairingMethod", UMA_PAIRING_METHOD_NONE, @@ -207,7 +208,8 @@ void BluetoothPairingChromeOS::ConfirmPairing() { if (confirmation_callback_.is_null()) return; - confirmation_callback_.Run(BluetoothAgentServiceProvider::Delegate::SUCCESS); + confirmation_callback_.Run( + bluez::BluetoothAgentServiceProvider::Delegate::SUCCESS); confirmation_callback_.Reset(); // If this is not an outgoing connection to the device, clean up the pairing @@ -218,12 +220,13 @@ void BluetoothPairingChromeOS::ConfirmPairing() { } bool BluetoothPairingChromeOS::RejectPairing() { - return RunPairingCallbacks(BluetoothAgentServiceProvider::Delegate::REJECTED); + return RunPairingCallbacks( + bluez::BluetoothAgentServiceProvider::Delegate::REJECTED); } bool BluetoothPairingChromeOS::CancelPairing() { return RunPairingCallbacks( - BluetoothAgentServiceProvider::Delegate::CANCELLED); + bluez::BluetoothAgentServiceProvider::Delegate::CANCELLED); } BluetoothDevice::PairingDelegate* @@ -238,7 +241,7 @@ void BluetoothPairingChromeOS::ResetCallbacks() { } bool BluetoothPairingChromeOS::RunPairingCallbacks( - BluetoothAgentServiceProvider::Delegate::Status status) { + bluez::BluetoothAgentServiceProvider::Delegate::Status status) { pairing_delegate_used_ = true; bool callback_run = false; diff --git a/device/bluetooth/bluetooth_pairing_chromeos.h b/device/bluetooth/bluetooth_pairing_chromeos.h index b50a328..0a4ddb6 100644 --- a/device/bluetooth/bluetooth_pairing_chromeos.h +++ b/device/bluetooth/bluetooth_pairing_chromeos.h @@ -5,8 +5,8 @@ #ifndef DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_CHROMEOS_H_ #define DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_CHROMEOS_H_ -#include "chromeos/dbus/bluetooth_agent_service_provider.h" #include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h" namespace chromeos { @@ -36,7 +36,8 @@ class BluetoothPairingChromeOS { // calls on this object are translated into the appropriate response to // |callback|. void RequestPinCode( - const BluetoothAgentServiceProvider::Delegate::PinCodeCallback& callback); + const bluez::BluetoothAgentServiceProvider::Delegate::PinCodeCallback& + callback); // Indicates whether the device is currently pairing and expecting a // PIN Code to be returned. @@ -57,7 +58,8 @@ class BluetoothPairingChromeOS { // calls on this object are translated into the appropriate response to // |callback|. void RequestPasskey( - const BluetoothAgentServiceProvider::Delegate::PasskeyCallback& callback); + const bluez::BluetoothAgentServiceProvider::Delegate::PasskeyCallback& + callback); // Sends the Passkey |passkey| to the remote device during pairing. // @@ -79,18 +81,16 @@ class BluetoothPairingChromeOS { // from the current pairing delegate. The ConfirmPairing(), RejectPairing() // and CancelPairing() method calls on this object are translated into the // appropriate response to |callback|. - void RequestConfirmation( - uint32 passkey, - const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback& - callback); + void RequestConfirmation(uint32 passkey, + const bluez::BluetoothAgentServiceProvider:: + Delegate::ConfirmationCallback& callback); // Requests authorization that the current device be allowed to pair with // this device from the current pairing delegate. The ConfirmPairing(), // RejectPairing() and CancelPairing() method calls on this object are // translated into the appropriate response to |callback|. - void RequestAuthorization( - const BluetoothAgentServiceProvider::Delegate::ConfirmationCallback& - callback); + void RequestAuthorization(const bluez::BluetoothAgentServiceProvider:: + Delegate::ConfirmationCallback& callback); // Confirms to the remote device during pairing that a passkey provided by // the ConfirmPasskey() delegate call is displayed on both devices. @@ -115,7 +115,7 @@ class BluetoothPairingChromeOS { // Internal method to respond to the relevant callback for a RejectPairing // or CancelPairing call. bool RunPairingCallbacks( - BluetoothAgentServiceProvider::Delegate::Status status); + bluez::BluetoothAgentServiceProvider::Delegate::Status status); // The underlying BluetoothDeviceChromeOS that owns this pairing context. BluetoothDeviceChromeOS* device_; @@ -131,11 +131,13 @@ class BluetoothPairingChromeOS { // During pairing these callbacks are set to those provided by method calls // made on the BluetoothAdapterChromeOS instance by its respective - // BluetoothAgentServiceProvider instance, and are called by our own + // bluez::BluetoothAgentServiceProvider instance, and are called by our own // method calls such as SetPinCode() and SetPasskey(). - BluetoothAgentServiceProvider::Delegate::PinCodeCallback pincode_callback_; - BluetoothAgentServiceProvider::Delegate::PasskeyCallback passkey_callback_; - BluetoothAgentServiceProvider::Delegate::ConfirmationCallback + bluez::BluetoothAgentServiceProvider::Delegate::PinCodeCallback + pincode_callback_; + bluez::BluetoothAgentServiceProvider::Delegate::PasskeyCallback + passkey_callback_; + bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback confirmation_callback_; DISALLOW_COPY_AND_ASSIGN(BluetoothPairingChromeOS); diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc index 7a0f5e3..7374f16 100644 --- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc +++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.cc @@ -8,13 +8,13 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_gatt_notify_session_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" #include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos { @@ -44,12 +44,13 @@ BluetoothRemoteGattCharacteristicChromeOS:: weak_ptr_factory_(this) { VLOG(1) << "Creating remote GATT characteristic with identifier: " << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); - DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->AddObserver( - this); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattDescriptorClient() + ->AddObserver(this); // Add all known GATT characteristic descriptors. const std::vector<dbus::ObjectPath>& gatt_descs = - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothGattDescriptorClient() ->GetDescriptors(); for (std::vector<dbus::ObjectPath>::const_iterator iter = gatt_descs.begin(); @@ -59,8 +60,9 @@ BluetoothRemoteGattCharacteristicChromeOS:: BluetoothRemoteGattCharacteristicChromeOS:: ~BluetoothRemoteGattCharacteristicChromeOS() { - DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->RemoveObserver( - this); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattDescriptorClient() + ->RemoveObserver(this); // Clean up all the descriptors. There isn't much point in notifying service // observers for each descriptor that gets removed, so just delete them. @@ -82,8 +84,8 @@ std::string BluetoothRemoteGattCharacteristicChromeOS::GetIdentifier() const { device::BluetoothUUID BluetoothRemoteGattCharacteristicChromeOS::GetUUID() const { - BluetoothGattCharacteristicClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattCharacteristicClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->GetProperties(object_path_); DCHECK(properties); @@ -96,8 +98,8 @@ bool BluetoothRemoteGattCharacteristicChromeOS::IsLocal() const { const std::vector<uint8>& BluetoothRemoteGattCharacteristicChromeOS::GetValue() const { - BluetoothGattCharacteristicClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattCharacteristicClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->GetProperties(object_path_); @@ -113,8 +115,8 @@ BluetoothRemoteGattCharacteristicChromeOS::GetService() const { device::BluetoothGattCharacteristic::Properties BluetoothRemoteGattCharacteristicChromeOS::GetProperties() const { - BluetoothGattCharacteristicClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattCharacteristicClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->GetProperties(object_path_); DCHECK(properties); @@ -157,8 +159,8 @@ BluetoothRemoteGattCharacteristicChromeOS::GetPermissions() const { } bool BluetoothRemoteGattCharacteristicChromeOS::IsNotifying() const { - BluetoothGattCharacteristicClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattCharacteristicClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->GetProperties(object_path_); DCHECK(properties); @@ -204,10 +206,12 @@ void BluetoothRemoteGattCharacteristicChromeOS::ReadRemoteCharacteristic( << GetIdentifier() << ", UUID: " << GetUUID().canonical_value() << "."; - DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->ReadValue( - object_path_, callback, - base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError, - weak_ptr_factory_.GetWeakPtr(), error_callback)); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattCharacteristicClient() + ->ReadValue( + object_path_, callback, + base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); } void BluetoothRemoteGattCharacteristicChromeOS::WriteRemoteCharacteristic( @@ -218,10 +222,12 @@ void BluetoothRemoteGattCharacteristicChromeOS::WriteRemoteCharacteristic( << GetIdentifier() << ", UUID: " << GetUUID().canonical_value() << ", with value: " << new_value << "."; - DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->WriteValue( - object_path_, new_value, callback, - base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError, - weak_ptr_factory_.GetWeakPtr(), error_callback)); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattCharacteristicClient() + ->WriteValue( + object_path_, new_value, callback, + base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); } void BluetoothRemoteGattCharacteristicChromeOS::StartNotifySession( @@ -267,13 +273,16 @@ void BluetoothRemoteGattCharacteristicChromeOS::StartNotifySession( } notify_call_pending_ = true; - DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->StartNotify( - object_path_, - base::Bind( - &BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifySuccess, - weak_ptr_factory_.GetWeakPtr(), callback), - base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifyError, - weak_ptr_factory_.GetWeakPtr(), error_callback)); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattCharacteristicClient() + ->StartNotify( + object_path_, + base::Bind( + &BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifySuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind( + &BluetoothRemoteGattCharacteristicChromeOS::OnStartNotifyError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); } void BluetoothRemoteGattCharacteristicChromeOS::RemoveNotifySession( @@ -302,13 +311,16 @@ void BluetoothRemoteGattCharacteristicChromeOS::RemoveNotifySession( DCHECK(num_notify_sessions_ == 1); notify_call_pending_ = true; - DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->StopNotify( - object_path_, - base::Bind( - &BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifySuccess, - weak_ptr_factory_.GetWeakPtr(), callback), - base::Bind(&BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifyError, - weak_ptr_factory_.GetWeakPtr(), callback)); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattCharacteristicClient() + ->StopNotify( + object_path_, + base::Bind( + &BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifySuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind( + &BluetoothRemoteGattCharacteristicChromeOS::OnStopNotifyError, + weak_ptr_factory_.GetWeakPtr(), callback)); } void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorAdded( @@ -319,8 +331,8 @@ void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorAdded( return; } - BluetoothGattDescriptorClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattDescriptorClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattDescriptorClient() ->GetProperties(object_path); DCHECK(properties); @@ -372,8 +384,8 @@ void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorPropertyChanged( return; } - BluetoothGattDescriptorClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattDescriptorClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattDescriptorClient() ->GetProperties(object_path); diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h index a23a1178..361b319 100644 --- a/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h +++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h @@ -12,10 +12,10 @@ #include <vector> #include "base/memory/weak_ptr.h" -#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_gatt_characteristic.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h" namespace device { @@ -34,7 +34,7 @@ class BluetoothRemoteGattServiceChromeOS; // platform. class BluetoothRemoteGattCharacteristicChromeOS : public device::BluetoothGattCharacteristic, - public BluetoothGattDescriptorClient::Observer { + public bluez::BluetoothGattDescriptorClient::Observer { public: // device::BluetoothGattCharacteristic overrides. std::string GetIdentifier() const override; @@ -78,7 +78,7 @@ class BluetoothRemoteGattCharacteristicChromeOS const dbus::ObjectPath& object_path); ~BluetoothRemoteGattCharacteristicChromeOS() override; - // BluetoothGattDescriptorClient::Observer overrides. + // bluez::BluetoothGattDescriptorClient::Observer overrides. void GattDescriptorAdded(const dbus::ObjectPath& object_path) override; void GattDescriptorRemoved(const dbus::ObjectPath& object_path) override; void GattDescriptorPropertyChanged(const dbus::ObjectPath& object_path, diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc index ab1074f8..f864c3b 100644 --- a/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc +++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.cc @@ -7,10 +7,10 @@ #include "base/bind.h" #include "base/logging.h" #include "base/strings/stringprintf.h" -#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h" +#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" namespace chromeos { @@ -47,8 +47,8 @@ std::string BluetoothRemoteGattDescriptorChromeOS::GetIdentifier() const { } device::BluetoothUUID BluetoothRemoteGattDescriptorChromeOS::GetUUID() const { - BluetoothGattDescriptorClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattDescriptorClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattDescriptorClient() ->GetProperties(object_path_); DCHECK(properties); @@ -61,8 +61,8 @@ bool BluetoothRemoteGattDescriptorChromeOS::IsLocal() const { const std::vector<uint8>& BluetoothRemoteGattDescriptorChromeOS::GetValue() const { - BluetoothGattDescriptorClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattDescriptorClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattDescriptorClient() ->GetProperties(object_path_); @@ -90,7 +90,7 @@ void BluetoothRemoteGattDescriptorChromeOS::ReadRemoteDescriptor( << "descriptor: " << GetIdentifier() << ", UUID: " << GetUUID().canonical_value(); - DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->ReadValue( + bluez::BluezDBusManager::Get()->GetBluetoothGattDescriptorClient()->ReadValue( object_path_, callback, base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError, weak_ptr_factory_.GetWeakPtr(), error_callback)); @@ -105,10 +105,11 @@ void BluetoothRemoteGattDescriptorChromeOS::WriteRemoteDescriptor( << GetUUID().canonical_value() << ", with value: " << new_value << "."; - DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->WriteValue( - object_path_, new_value, callback, - base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError, - weak_ptr_factory_.GetWeakPtr(), error_callback)); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattDescriptorClient() + ->WriteValue(object_path_, new_value, callback, + base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); } void BluetoothRemoteGattDescriptorChromeOS::OnError( diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc index e8176bd..8a57fa2 100644 --- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc +++ b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.cc @@ -6,12 +6,12 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" -#include "chromeos/dbus/bluetooth_gatt_service_client.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" #include "device/bluetooth/bluetooth_device_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_descriptor_chromeos.h" +#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" namespace chromeos { @@ -41,13 +41,15 @@ BluetoothRemoteGattServiceChromeOS::BluetoothRemoteGattServiceChromeOS( << object_path.value() << ", UUID: " << GetUUID().canonical_value(); DCHECK(adapter_); - DBusThreadManager::Get()->GetBluetoothGattServiceClient()->AddObserver(this); - DBusThreadManager::Get()->GetBluetoothGattCharacteristicClient()->AddObserver( + bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient()->AddObserver( this); + bluez::BluezDBusManager::Get() + ->GetBluetoothGattCharacteristicClient() + ->AddObserver(this); // Add all known GATT characteristics. const std::vector<dbus::ObjectPath>& gatt_chars = - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->GetCharacteristics(); for (std::vector<dbus::ObjectPath>::const_iterator iter = gatt_chars.begin(); @@ -56,9 +58,10 @@ BluetoothRemoteGattServiceChromeOS::BluetoothRemoteGattServiceChromeOS( } BluetoothRemoteGattServiceChromeOS::~BluetoothRemoteGattServiceChromeOS() { - DBusThreadManager::Get()->GetBluetoothGattServiceClient()->RemoveObserver( - this); - DBusThreadManager::Get() + bluez::BluezDBusManager::Get() + ->GetBluetoothGattServiceClient() + ->RemoveObserver(this); + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->RemoveObserver(this); @@ -81,9 +84,10 @@ std::string BluetoothRemoteGattServiceChromeOS::GetIdentifier() const { } device::BluetoothUUID BluetoothRemoteGattServiceChromeOS::GetUUID() const { - BluetoothGattServiceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetProperties( - object_path_); + bluez::BluetoothGattServiceClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothGattServiceClient() + ->GetProperties(object_path_); DCHECK(properties); return device::BluetoothUUID(properties->uuid.value()); } @@ -93,9 +97,10 @@ bool BluetoothRemoteGattServiceChromeOS::IsLocal() const { } bool BluetoothRemoteGattServiceChromeOS::IsPrimary() const { - BluetoothGattServiceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetProperties( - object_path_); + bluez::BluetoothGattServiceClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothGattServiceClient() + ->GetProperties(object_path_); DCHECK(properties); return properties->primary.value(); } @@ -229,9 +234,10 @@ void BluetoothRemoteGattServiceChromeOS::GattServicePropertyChanged( VLOG(1) << "Service property changed: \"" << property_name << "\", " << object_path.value(); - BluetoothGattServiceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothGattServiceClient()->GetProperties( - object_path); + bluez::BluetoothGattServiceClient::Properties* properties = + bluez::BluezDBusManager::Get() + ->GetBluetoothGattServiceClient() + ->GetProperties(object_path); DCHECK(properties); if (property_name != properties->characteristics.name()) { @@ -257,8 +263,8 @@ void BluetoothRemoteGattServiceChromeOS::GattCharacteristicAdded( return; } - BluetoothGattCharacteristicClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattCharacteristicClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->GetProperties(object_path); DCHECK(properties); @@ -315,8 +321,8 @@ void BluetoothRemoteGattServiceChromeOS::GattCharacteristicPropertyChanged( // "Characteristic Extended Properties" descriptor. In this case, kick off // a service changed observer event to let observers refresh the // characteristics. - BluetoothGattCharacteristicClient::Properties* properties = - DBusThreadManager::Get() + bluez::BluetoothGattCharacteristicClient::Properties* properties = + bluez::BluezDBusManager::Get() ->GetBluetoothGattCharacteristicClient() ->GetProperties(object_path); diff --git a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h index 9aa8fdd..bc35cb7 100644 --- a/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h +++ b/device/bluetooth/bluetooth_remote_gatt_service_chromeos.h @@ -12,11 +12,11 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" -#include "chromeos/dbus/bluetooth_gatt_characteristic_client.h" -#include "chromeos/dbus/bluetooth_gatt_service_client.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_gatt_service.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h" namespace device { @@ -36,8 +36,8 @@ class BluetoothRemoteGattDescriptorChromeOS; // for remote GATT services on the Chrome OS platform. class BluetoothRemoteGattServiceChromeOS : public device::BluetoothGattService, - public BluetoothGattServiceClient::Observer, - public BluetoothGattCharacteristicClient::Observer { + public bluez::BluetoothGattServiceClient::Observer, + public bluez::BluetoothGattCharacteristicClient::Observer { public: // device::BluetoothGattService overrides. std::string GetIdentifier() const override; @@ -104,11 +104,11 @@ class BluetoothRemoteGattServiceChromeOS const dbus::ObjectPath& object_path); ~BluetoothRemoteGattServiceChromeOS() override; - // BluetoothGattServiceClient::Observer override. + // bluez::BluetoothGattServiceClient::Observer override. void GattServicePropertyChanged(const dbus::ObjectPath& object_path, const std::string& property_name) override; - // BluetoothGattCharacteristicClient::Observer override. + // bluez::BluetoothGattCharacteristicClient::Observer override. void GattCharacteristicAdded(const dbus::ObjectPath& object_path) override; void GattCharacteristicRemoved(const dbus::ObjectPath& object_path) override; void GattCharacteristicPropertyChanged( diff --git a/device/bluetooth/bluetooth_socket_chromeos.cc b/device/bluetooth/bluetooth_socket_chromeos.cc index da15484..b3e357d 100644 --- a/device/bluetooth/bluetooth_socket_chromeos.cc +++ b/device/bluetooth/bluetooth_socket_chromeos.cc @@ -20,10 +20,6 @@ #include "base/task_runner_util.h" #include "base/threading/thread_restrictions.h" #include "base/threading/worker_pool.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_profile_manager_client.h" -#include "chromeos/dbus/bluetooth_profile_service_provider.h" -#include "chromeos/dbus/dbus_thread_manager.h" #include "dbus/bus.h" #include "dbus/file_descriptor.h" #include "dbus/object_path.h" @@ -35,6 +31,10 @@ #include "device/bluetooth/bluetooth_socket.h" #include "device/bluetooth/bluetooth_socket_net.h" #include "device/bluetooth/bluetooth_socket_thread.h" +#include "device/bluetooth/dbus/bluetooth_device_client.h" +#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" #include "net/base/ip_endpoint.h" #include "net/base/net_errors.h" #include "third_party/cros_system_api/dbus/service_constants.h" @@ -107,7 +107,7 @@ void BluetoothSocketChromeOS::Connect( device_address_ = device->GetAddress(); device_path_ = device->object_path(); uuid_ = uuid; - options_.reset(new BluetoothProfileManagerClient::Options()); + options_.reset(new bluez::BluetoothProfileManagerClient::Options()); if (security_level == SECURITY_LEVEL_LOW) options_->require_authentication.reset(new bool(false)); @@ -135,7 +135,7 @@ void BluetoothSocketChromeOS::Listen( adapter_->AddObserver(this); uuid_ = uuid; - options_.reset(new BluetoothProfileManagerClient::Options()); + options_.reset(new bluez::BluetoothProfileManagerClient::Options()); if (service_options.name) options_->name.reset(new std::string(*service_options.name)); @@ -165,7 +165,7 @@ void BluetoothSocketChromeOS::Close() { // In the case below, where an asynchronous task gets posted on the socket // thread in BluetoothSocketNet::Close, a reference will be held to this // socket by the callback. This may cause the BluetoothAdapter to outlive - // DBusThreadManager during shutdown if that callback executes too late. + // BluezDBusManager during shutdown if that callback executes too late. if (adapter_.get()) { adapter_->RemoveObserver(this); adapter_ = nullptr; @@ -264,7 +264,7 @@ void BluetoothSocketChromeOS::OnRegisterProfile( VLOG(1) << uuid_.canonical_value() << ": Got profile, connecting to " << device_path_.value(); - DBusThreadManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()->ConnectProfile( device_path_, uuid_.canonical_value(), base::Bind(&BluetoothSocketChromeOS::OnConnectProfile, this, success_callback), @@ -355,7 +355,7 @@ void BluetoothSocketChromeOS::Released() { void BluetoothSocketChromeOS::NewConnection( const dbus::ObjectPath& device_path, scoped_ptr<dbus::FileDescriptor> fd, - const BluetoothProfileServiceProvider::Delegate::Options& options, + const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, const ConfirmationCallback& callback) { DCHECK(ui_task_runner()->RunsTasksOnCurrentThread()); @@ -460,7 +460,7 @@ void BluetoothSocketChromeOS::AcceptConnectionRequest() { void BluetoothSocketChromeOS::DoNewConnection( const dbus::ObjectPath& device_path, scoped_ptr<dbus::FileDescriptor> fd, - const BluetoothProfileServiceProvider::Delegate::Options& options, + const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, const ConfirmationCallback& callback) { DCHECK(socket_thread()->task_runner()->RunsTasksOnCurrentThread()); base::ThreadRestrictions::AssertIOAllowed(); diff --git a/device/bluetooth/bluetooth_socket_chromeos.h b/device/bluetooth/bluetooth_socket_chromeos.h index 98d4d02..a1c76ee2 100644 --- a/device/bluetooth/bluetooth_socket_chromeos.h +++ b/device/bluetooth/bluetooth_socket_chromeos.h @@ -10,14 +10,14 @@ #include "base/memory/linked_ptr.h" #include "base/memory/scoped_ptr.h" -#include "chromeos/chromeos_export.h" -#include "chromeos/dbus/bluetooth_profile_manager_client.h" -#include "chromeos/dbus/bluetooth_profile_service_provider.h" #include "dbus/object_path.h" #include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_export.h" #include "device/bluetooth/bluetooth_socket.h" #include "device/bluetooth/bluetooth_socket_net.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" namespace dbus { class FileDescriptor; @@ -33,10 +33,10 @@ class BluetoothAdapterProfileChromeOS; // Chrome OS platform. // // This class is not thread-safe, but is only called from the UI thread. -class CHROMEOS_EXPORT BluetoothSocketChromeOS +class DEVICE_BLUETOOTH_EXPORT BluetoothSocketChromeOS : public device::BluetoothSocketNet, public device::BluetoothAdapter::Observer, - public BluetoothProfileServiceProvider::Delegate { + public bluez::BluetoothProfileServiceProvider::Delegate { public: enum SecurityLevel { SECURITY_LEVEL_LOW, @@ -112,12 +112,12 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS void OnInternalRegisterProfile(BluetoothAdapterProfileChromeOS* profile); void OnInternalRegisterProfileError(const std::string& error_message); - // BluetoothProfileServiceProvider::Delegate: + // bluez::BluetoothProfileServiceProvider::Delegate: void Released() override; void NewConnection( const dbus::ObjectPath& device_path, scoped_ptr<dbus::FileDescriptor> fd, - const BluetoothProfileServiceProvider::Delegate::Options& options, + const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, const ConfirmationCallback& callback) override; void RequestDisconnection(const dbus::ObjectPath& device_path, const ConfirmationCallback& callback) override; @@ -131,7 +131,7 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS void DoNewConnection( const dbus::ObjectPath& device_path, scoped_ptr<dbus::FileDescriptor> fd, - const BluetoothProfileServiceProvider::Delegate::Options& options, + const bluez::BluetoothProfileServiceProvider::Delegate::Options& options, const ConfirmationCallback& callback); // Method run on the UI thread after a new connection has been accepted and @@ -166,7 +166,7 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS device::BluetoothUUID uuid_; // Copy of the profile options used for registering the profile. - scoped_ptr<BluetoothProfileManagerClient::Options> options_; + scoped_ptr<bluez::BluetoothProfileManagerClient::Options> options_; // The profile registered with the adapter for this socket. BluetoothAdapterProfileChromeOS* profile_; @@ -188,7 +188,7 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS dbus::ObjectPath device_path; scoped_ptr<dbus::FileDescriptor> fd; - BluetoothProfileServiceProvider::Delegate::Options options; + bluez::BluetoothProfileServiceProvider::Delegate::Options options; ConfirmationCallback callback; bool accepting; bool cancelled; diff --git a/device/bluetooth/bluetooth_socket_chromeos_unittest.cc b/device/bluetooth/bluetooth_socket_chromeos_unittest.cc index 477f3a7..b306008 100644 --- a/device/bluetooth/bluetooth_socket_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_socket_chromeos_unittest.cc @@ -5,14 +5,6 @@ #include "base/bind.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/fake_bluetooth_adapter_client.h" -#include "chromeos/dbus/fake_bluetooth_agent_manager_client.h" -#include "chromeos/dbus/fake_bluetooth_device_client.h" -#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h" -#include "chromeos/dbus/fake_bluetooth_input_client.h" -#include "chromeos/dbus/fake_bluetooth_profile_manager_client.h" -#include "chromeos/dbus/fake_bluetooth_profile_service_provider.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h" #include "device/bluetooth/bluetooth_adapter_factory.h" @@ -22,6 +14,14 @@ #include "device/bluetooth/bluetooth_socket_chromeos.h" #include "device/bluetooth/bluetooth_socket_thread.h" #include "device/bluetooth/bluetooth_uuid.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_device_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_input_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "testing/gtest/include/gtest/gtest.h" @@ -51,24 +51,27 @@ class BluetoothSocketChromeOSTest : public testing::Test { last_reason_(BluetoothSocket::kSystemError) {} void SetUp() override { - scoped_ptr<DBusThreadManagerSetter> dbus_setter = - DBusThreadManager::GetSetterForTesting(); + scoped_ptr<bluez::BluezDBusManagerSetter> dbus_setter = + bluez::BluezDBusManager::GetSetterForTesting(); dbus_setter->SetBluetoothAdapterClient( - scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient)); + scoped_ptr<bluez::BluetoothAdapterClient>( + new bluez::FakeBluetoothAdapterClient)); dbus_setter->SetBluetoothAgentManagerClient( - scoped_ptr<BluetoothAgentManagerClient>( - new FakeBluetoothAgentManagerClient)); + scoped_ptr<bluez::BluetoothAgentManagerClient>( + new bluez::FakeBluetoothAgentManagerClient)); dbus_setter->SetBluetoothDeviceClient( - scoped_ptr<BluetoothDeviceClient>(new FakeBluetoothDeviceClient)); + scoped_ptr<bluez::BluetoothDeviceClient>( + new bluez::FakeBluetoothDeviceClient)); dbus_setter->SetBluetoothGattServiceClient( - scoped_ptr<BluetoothGattServiceClient>( - new FakeBluetoothGattServiceClient)); + scoped_ptr<bluez::BluetoothGattServiceClient>( + new bluez::FakeBluetoothGattServiceClient)); dbus_setter->SetBluetoothInputClient( - scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient)); + scoped_ptr<bluez::BluetoothInputClient>( + new bluez::FakeBluetoothInputClient)); dbus_setter->SetBluetoothProfileManagerClient( - scoped_ptr<BluetoothProfileManagerClient>( - new FakeBluetoothProfileManagerClient)); + scoped_ptr<bluez::BluetoothProfileManagerClient>( + new bluez::FakeBluetoothProfileManagerClient)); BluetoothSocketThread::Get(); @@ -91,7 +94,7 @@ class BluetoothSocketChromeOSTest : public testing::Test { void TearDown() override { adapter_ = nullptr; BluetoothSocketThread::CleanupForTesting(); - DBusThreadManager::Shutdown(); + bluez::BluezDBusManager::Shutdown(); } void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) { @@ -182,12 +185,12 @@ class BluetoothSocketChromeOSTest : public testing::Test { }; TEST_F(BluetoothSocketChromeOSTest, Connect) { - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_TRUE(device != nullptr); device->ConnectToService( - BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid), + BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid), base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback, base::Unretained(this)), base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback, @@ -294,7 +297,7 @@ TEST_F(BluetoothSocketChromeOSTest, Connect) { TEST_F(BluetoothSocketChromeOSTest, Listen) { adapter_->CreateRfcommService( - BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid), + BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid), BluetoothAdapter::ServiceOptions(), base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback, base::Unretained(this)), @@ -319,15 +322,15 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) { // // This is done before the Accept() call to simulate a pending call at the // point that Accept() is called. - FakeBluetoothDeviceClient* fake_bluetooth_device_client = - static_cast<FakeBluetoothDeviceClient*>( - DBusThreadManager::Get()->GetBluetoothDeviceClient()); - BluetoothDevice* device = - adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress); + bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client = + static_cast<bluez::FakeBluetoothDeviceClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()); + BluetoothDevice* device = adapter_->GetDevice( + bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress); ASSERT_TRUE(device != nullptr); fake_bluetooth_device_client->ConnectProfile( static_cast<BluetoothDeviceChromeOS*>(device)->object_path(), - FakeBluetoothProfileManagerClient::kRfcommUuid, + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid, base::Bind(&base::DoNothing), base::Bind(&DoNothingDBusErrorCallback)); message_loop_.RunUntilIdle(); @@ -374,7 +377,7 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) { fake_bluetooth_device_client->ConnectProfile( static_cast<BluetoothDeviceChromeOS*>(device)->object_path(), - FakeBluetoothProfileManagerClient::kRfcommUuid, + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid, base::Bind(&base::DoNothing), base::Bind(&DoNothingDBusErrorCallback)); message_loop_.Run(); @@ -414,13 +417,13 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) { TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) { // Start off with an invisible adapter, register the profile, then make // the adapter visible. - FakeBluetoothAdapterClient* fake_bluetooth_adapter_client = - static_cast<FakeBluetoothAdapterClient*>( - DBusThreadManager::Get()->GetBluetoothAdapterClient()); + bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client = + static_cast<bluez::FakeBluetoothAdapterClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()); fake_bluetooth_adapter_client->SetVisible(false); adapter_->CreateRfcommService( - BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid), + BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid), BluetoothAdapter::ServiceOptions(), base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback, base::Unretained(this)), @@ -439,12 +442,14 @@ TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) { error_callback_count_ = 0; // But there shouldn't be a profile registered yet. - FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client = - static_cast<FakeBluetoothProfileManagerClient*>( - DBusThreadManager::Get()->GetBluetoothProfileManagerClient()); - FakeBluetoothProfileServiceProvider* profile_service_provider = + bluez::FakeBluetoothProfileManagerClient* + fake_bluetooth_profile_manager_client = + static_cast<bluez::FakeBluetoothProfileManagerClient*>( + bluez::BluezDBusManager::Get() + ->GetBluetoothProfileManagerClient()); + bluez::FakeBluetoothProfileServiceProvider* profile_service_provider = fake_bluetooth_profile_manager_client->GetProfileServiceProvider( - FakeBluetoothProfileManagerClient::kRfcommUuid); + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid); EXPECT_TRUE(profile_service_provider == nullptr); // Make the adapter visible. This should register a profile. @@ -454,7 +459,7 @@ TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) { profile_service_provider = fake_bluetooth_profile_manager_client->GetProfileServiceProvider( - FakeBluetoothProfileManagerClient::kRfcommUuid); + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid); EXPECT_TRUE(profile_service_provider != nullptr); // Cleanup the socket. @@ -469,12 +474,12 @@ TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) { TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) { // The fake adapter starts off visible by default. - FakeBluetoothAdapterClient* fake_bluetooth_adapter_client = - static_cast<FakeBluetoothAdapterClient*>( - DBusThreadManager::Get()->GetBluetoothAdapterClient()); + bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client = + static_cast<bluez::FakeBluetoothAdapterClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient()); adapter_->CreateRfcommService( - BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid), + BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid), BluetoothAdapter::ServiceOptions(), base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback, base::Unretained(this)), @@ -493,12 +498,14 @@ TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) { error_callback_count_ = 0; // Make sure the profile was registered with the daemon. - FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client = - static_cast<FakeBluetoothProfileManagerClient*>( - DBusThreadManager::Get()->GetBluetoothProfileManagerClient()); - FakeBluetoothProfileServiceProvider* profile_service_provider = + bluez::FakeBluetoothProfileManagerClient* + fake_bluetooth_profile_manager_client = + static_cast<bluez::FakeBluetoothProfileManagerClient*>( + bluez::BluezDBusManager::Get() + ->GetBluetoothProfileManagerClient()); + bluez::FakeBluetoothProfileServiceProvider* profile_service_provider = fake_bluetooth_profile_manager_client->GetProfileServiceProvider( - FakeBluetoothProfileManagerClient::kRfcommUuid); + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid); EXPECT_TRUE(profile_service_provider != nullptr); // Make the adapter invisible, and fiddle with the profile fake to unregister @@ -514,7 +521,7 @@ TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) { profile_service_provider = fake_bluetooth_profile_manager_client->GetProfileServiceProvider( - FakeBluetoothProfileManagerClient::kRfcommUuid); + bluez::FakeBluetoothProfileManagerClient::kRfcommUuid); EXPECT_TRUE(profile_service_provider != nullptr); // Cleanup the socket. @@ -529,11 +536,11 @@ TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) { TEST_F(BluetoothSocketChromeOSTest, PairedConnectFails) { BluetoothDevice* device = adapter_->GetDevice( - FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress); + bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress); ASSERT_TRUE(device != nullptr); device->ConnectToService( - BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid), + BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid), base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback, base::Unretained(this)), base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback, @@ -545,7 +552,7 @@ TEST_F(BluetoothSocketChromeOSTest, PairedConnectFails) { EXPECT_TRUE(last_socket_.get() == nullptr); device->ConnectToService( - BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid), + BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid), base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback, base::Unretained(this)), base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback, @@ -559,7 +566,7 @@ TEST_F(BluetoothSocketChromeOSTest, PairedConnectFails) { TEST_F(BluetoothSocketChromeOSTest, SocketListenTwice) { adapter_->CreateRfcommService( - BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid), + BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid), BluetoothAdapter::ServiceOptions(), base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback, base::Unretained(this)), @@ -592,7 +599,7 @@ TEST_F(BluetoothSocketChromeOSTest, SocketListenTwice) { EXPECT_EQ(1U, error_callback_count_); adapter_->CreateRfcommService( - BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid), + BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid), BluetoothAdapter::ServiceOptions(), base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback, base::Unretained(this)), diff --git a/device/bluetooth/dbus/bluetooth_adapter_client.cc b/device/bluetooth/dbus/bluetooth_adapter_client.cc new file mode 100644 index 0000000..26081ea --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_adapter_client.cc @@ -0,0 +1,350 @@ +// Copyright 2013 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 "device/bluetooth/dbus/bluetooth_adapter_client.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_manager.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +BluetoothAdapterClient::DiscoveryFilter::DiscoveryFilter() {} + +BluetoothAdapterClient::DiscoveryFilter::~DiscoveryFilter() {} + +void BluetoothAdapterClient::DiscoveryFilter::CopyFrom( + const DiscoveryFilter& filter) { + if (filter.rssi.get()) + rssi.reset(new int16_t(*filter.rssi)); + else + rssi.reset(); + + if (filter.pathloss.get()) + pathloss.reset(new uint16_t(*filter.pathloss)); + else + pathloss.reset(); + + if (filter.transport.get()) + transport.reset(new std::string(*filter.transport)); + else + transport.reset(); + + if (filter.uuids.get()) + uuids.reset(new std::vector<std::string>(*filter.uuids)); + else + uuids.reset(); +} + +const char BluetoothAdapterClient::kNoResponseError[] = + "org.chromium.Error.NoResponse"; +const char BluetoothAdapterClient::kUnknownAdapterError[] = + "org.chromium.Error.UnknownAdapter"; + +BluetoothAdapterClient::Properties::Properties( + dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback) + : dbus::PropertySet(object_proxy, interface_name, callback) { + RegisterProperty(bluetooth_adapter::kAddressProperty, &address); + RegisterProperty(bluetooth_adapter::kNameProperty, &name); + RegisterProperty(bluetooth_adapter::kAliasProperty, &alias); + RegisterProperty(bluetooth_adapter::kClassProperty, &bluetooth_class); + RegisterProperty(bluetooth_adapter::kPoweredProperty, &powered); + RegisterProperty(bluetooth_adapter::kDiscoverableProperty, &discoverable); + RegisterProperty(bluetooth_adapter::kPairableProperty, &pairable); + RegisterProperty(bluetooth_adapter::kPairableTimeoutProperty, + &pairable_timeout); + RegisterProperty(bluetooth_adapter::kDiscoverableTimeoutProperty, + &discoverable_timeout); + RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering); + RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids); + RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias); +} + +BluetoothAdapterClient::Properties::~Properties() {} + +// The BluetoothAdapterClient implementation used in production. +class BluetoothAdapterClientImpl : public BluetoothAdapterClient, + public dbus::ObjectManager::Interface { + public: + BluetoothAdapterClientImpl() + : object_manager_(NULL), weak_ptr_factory_(this) {} + + ~BluetoothAdapterClientImpl() override { + object_manager_->UnregisterInterface( + bluetooth_adapter::kBluetoothAdapterInterface); + } + + // BluetoothAdapterClient override. + void AddObserver(BluetoothAdapterClient::Observer* observer) override { + DCHECK(observer); + observers_.AddObserver(observer); + } + + // BluetoothAdapterClient override. + void RemoveObserver(BluetoothAdapterClient::Observer* observer) override { + DCHECK(observer); + observers_.RemoveObserver(observer); + } + + // Returns the list of adapter object paths known to the system. + std::vector<dbus::ObjectPath> GetAdapters() override { + return object_manager_->GetObjectsWithInterface( + bluetooth_adapter::kBluetoothAdapterInterface); + } + + // dbus::ObjectManager::Interface override. + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + Properties* properties = new Properties( + object_proxy, interface_name, + base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), object_path)); + return static_cast<dbus::PropertySet*>(properties); + } + + // BluetoothAdapterClient override. + Properties* GetProperties(const dbus::ObjectPath& object_path) override { + return static_cast<Properties*>(object_manager_->GetProperties( + object_path, bluetooth_adapter::kBluetoothAdapterInterface)); + } + + // BluetoothAdapterClient override. + void StartDiscovery(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_adapter::kBluetoothAdapterInterface, + bluetooth_adapter::kStartDiscovery); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownAdapterError, ""); + return; + } + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAdapterClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAdapterClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothAdapterClient override. + void StopDiscovery(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_adapter::kBluetoothAdapterInterface, + bluetooth_adapter::kStopDiscovery); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownAdapterError, ""); + return; + } + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAdapterClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAdapterClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothAdapterClient override. + void RemoveDevice(const dbus::ObjectPath& object_path, + const dbus::ObjectPath& device_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_adapter::kBluetoothAdapterInterface, + bluetooth_adapter::kRemoveDevice); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(device_path); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownAdapterError, ""); + return; + } + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAdapterClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAdapterClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothAdapterClient override. + void SetDiscoveryFilter(const dbus::ObjectPath& object_path, + const DiscoveryFilter& discovery_filter, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_adapter::kBluetoothAdapterInterface, + bluetooth_adapter::kSetDiscoveryFilter); + + dbus::MessageWriter writer(&method_call); + dbus::MessageWriter dict_writer(nullptr); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownAdapterError, ""); + return; + } + + writer.OpenArray("{sv}", &dict_writer); + + if (discovery_filter.uuids.get()) { + std::vector<std::string>* uuids = discovery_filter.uuids.get(); + dbus::MessageWriter uuids_entry_writer(nullptr); + dict_writer.OpenDictEntry(&uuids_entry_writer); + uuids_entry_writer.AppendString( + bluetooth_adapter::kDiscoveryFilterParameterUUIDs); + + dbus::MessageWriter uuids_array_variant(nullptr); + uuids_entry_writer.OpenVariant("as", &uuids_array_variant); + dbus::MessageWriter uuids_array(nullptr); + uuids_array_variant.OpenArray("s", &uuids_array); + + for (auto& it : *uuids) + uuids_array.AppendString(it); + + uuids_array_variant.CloseContainer(&uuids_array); + uuids_entry_writer.CloseContainer(&uuids_array_variant); + dict_writer.CloseContainer(&uuids_entry_writer); + } + + if (discovery_filter.rssi.get()) { + dbus::MessageWriter rssi_entry_writer(nullptr); + dict_writer.OpenDictEntry(&rssi_entry_writer); + rssi_entry_writer.AppendString( + bluetooth_adapter::kDiscoveryFilterParameterRSSI); + rssi_entry_writer.AppendVariantOfInt16(*discovery_filter.rssi.get()); + dict_writer.CloseContainer(&rssi_entry_writer); + } + + if (discovery_filter.pathloss.get()) { + dbus::MessageWriter pathloss_entry_writer(nullptr); + dict_writer.OpenDictEntry(&pathloss_entry_writer); + pathloss_entry_writer.AppendString( + bluetooth_adapter::kDiscoveryFilterParameterPathloss); + pathloss_entry_writer.AppendVariantOfUint16( + *discovery_filter.pathloss.get()); + dict_writer.CloseContainer(&pathloss_entry_writer); + } + + if (discovery_filter.transport.get()) { + dbus::MessageWriter transport_entry_writer(nullptr); + dict_writer.OpenDictEntry(&transport_entry_writer); + transport_entry_writer.AppendString( + bluetooth_adapter::kDiscoveryFilterParameterTransport); + transport_entry_writer.AppendVariantOfString( + *discovery_filter.transport.get()); + dict_writer.CloseContainer(&transport_entry_writer); + } + + writer.CloseContainer(&dict_writer); + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAdapterClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAdapterClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + protected: + void Init(dbus::Bus* bus) override { + object_manager_ = bus->GetObjectManager( + bluetooth_object_manager::kBluetoothObjectManagerServiceName, + dbus::ObjectPath( + bluetooth_object_manager::kBluetoothObjectManagerServicePath)); + object_manager_->RegisterInterface( + bluetooth_adapter::kBluetoothAdapterInterface, this); + } + + private: + // Called by dbus::ObjectManager when an object with the adapter interface + // is created. Informs observers. + void ObjectAdded(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, + AdapterAdded(object_path)); + } + + // Called by dbus::ObjectManager when an object with the adapter interface + // is removed. Informs observers. + void ObjectRemoved(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, + AdapterRemoved(object_path)); + } + + // Called by dbus::PropertySet when a property value is changed, + // either by result of a signal or response to a GetAll() or Get() + // call. Informs observers. + void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) { + FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, + AdapterPropertyChanged(object_path, property_name)); + } + + // Called when a response for successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + // Error response has optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + error_message = ""; + } + error_callback.Run(error_name, error_message); + } + + dbus::ObjectManager* object_manager_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothAdapterClient::Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothAdapterClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl); +}; + +BluetoothAdapterClient::BluetoothAdapterClient() {} + +BluetoothAdapterClient::~BluetoothAdapterClient() {} + +BluetoothAdapterClient* BluetoothAdapterClient::Create() { + return new BluetoothAdapterClientImpl; +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_adapter_client.h b/device/bluetooth/dbus/bluetooth_adapter_client.h new file mode 100644 index 0000000..4af6658 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_adapter_client.h @@ -0,0 +1,186 @@ +// Copyright 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/observer_list.h" +#include "base/values.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothAdapterClient is used to communicate with objects representing +// local Bluetooth Adapters. +class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterClient : public BluezDBusClient { + public: + // A DiscoveryFilter represents a filter passed to the SetDiscoveryFilter + // method. + struct DiscoveryFilter { + DiscoveryFilter(); + ~DiscoveryFilter(); + + // Copy content of |filter| into this filter + void CopyFrom(const DiscoveryFilter& filter); + + scoped_ptr<std::vector<std::string>> uuids; + scoped_ptr<int16_t> rssi; + scoped_ptr<uint16_t> pathloss; + scoped_ptr<std::string> transport; + + private: + DISALLOW_COPY_AND_ASSIGN(DiscoveryFilter); + }; + + // Structure of properties associated with bluetooth adapters. + struct Properties : public dbus::PropertySet { + // The Bluetooth device address of the adapter. Read-only. + dbus::Property<std::string> address; + + // The Bluetooth system name, generally derived from the hostname. + dbus::Property<std::string> name; + + // The Bluetooth friendly name of the adapter, unlike remote devices, + // this property can be changed to change the presentation for when + // the adapter is discoverable. + dbus::Property<std::string> alias; + + // The Bluetooth class of the adapter device. Read-only. + dbus::Property<uint32> bluetooth_class; + + // Whether the adapter radio is powered. + dbus::Property<bool> powered; + + // Whether the adapter is discoverable by other Bluetooth devices. + // |discovering_timeout| is used to automatically disable after a time + // period. + dbus::Property<bool> discoverable; + + // Whether the adapter accepts incoming pairing requests from other + // Bluetooth devices. |pairable_timeout| is used to automatically disable + // after a time period. + dbus::Property<bool> pairable; + + // The timeout in seconds to cease accepting incoming pairing requests + // after |pairable| is set to true. Zero means adapter remains pairable + // forever. + dbus::Property<uint32> pairable_timeout; + + // The timeout in seconds to cease the adapter being discoverable by + // other Bluetooth devices after |discoverable| is set to true. Zero + // means adapter remains discoverable forever. + dbus::Property<uint32> discoverable_timeout; + + // Indicates that the adapter is discovering other Bluetooth Devices. + // Read-only. Use StartDiscovery() to begin discovery. + dbus::Property<bool> discovering; + + // List of 128-bit UUIDs that represent the available local services. + // Read-only. + dbus::Property<std::vector<std::string>> uuids; + + // Local Device ID information in Linux kernel modalias format. Read-only. + dbus::Property<std::string> modalias; + + Properties(dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback); + ~Properties() override; + }; + + // Interface for observing changes from a local bluetooth adapter. + class Observer { + public: + virtual ~Observer() {} + + // Called when the adapter with object path |object_path| is added to the + // system. + virtual void AdapterAdded(const dbus::ObjectPath& object_path) {} + + // Called when the adapter with object path |object_path| is removed from + // the system. + virtual void AdapterRemoved(const dbus::ObjectPath& object_path) {} + + // Called when the adapter with object path |object_path| has a + // change in value of the property named |property_name|. + virtual void AdapterPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) {} + }; + + ~BluetoothAdapterClient() override; + + // Adds and removes observers for events on all local bluetooth + // adapters. Check the |object_path| parameter of observer methods to + // determine which adapter is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Returns the list of adapter object paths known to the system. + virtual std::vector<dbus::ObjectPath> GetAdapters() = 0; + + // Obtain the properties for the adapter with object path |object_path|, + // any values should be copied if needed. + virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0; + + // The ErrorCallback is used by adapter methods to indicate failure. + // It receives two arguments: the name of the error in |error_name| and + // an optional message in |error_message|. + typedef base::Callback<void(const std::string& error_name, + const std::string& error_message)> ErrorCallback; + + // Starts a device discovery on the adapter with object path |object_path|. + virtual void StartDiscovery(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Cancels any previous device discovery on the adapter with object path + // |object_path|. + virtual void StopDiscovery(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Removes from the adapter with object path |object_path| the remote + // device with object path |object_path| from the list of known devices + // and discards any pairing information. + virtual void RemoveDevice(const dbus::ObjectPath& object_path, + const dbus::ObjectPath& device_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Sets the device discovery filter on the adapter with object path + // |object_path|. When this method is called with no filter parameter, filter + // is removed. + // SetDiscoveryFilter can be called before StartDiscovery. It is useful when + // client will create first discovery session, to ensure that proper scan + // will be started right after call to StartDiscovery. + virtual void SetDiscoveryFilter(const dbus::ObjectPath& object_path, + const DiscoveryFilter& discovery_filter, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Creates the instance. + static BluetoothAdapterClient* Create(); + + // Constants used to indicate exceptional error conditions. + static const char kNoResponseError[]; + static const char kUnknownAdapterError[]; + + protected: + BluetoothAdapterClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_ADAPTER_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_agent_manager_client.cc b/device/bluetooth/dbus/bluetooth_agent_manager_client.cc new file mode 100644 index 0000000..6caee9b --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_agent_manager_client.cc @@ -0,0 +1,137 @@ +// Copyright 2013 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 "device/bluetooth/dbus/bluetooth_agent_manager_client.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +const char BluetoothAgentManagerClient::kNoResponseError[] = + "org.chromium.Error.NoResponse"; + +// The BluetoothAgentManagerClient implementation used in production. +class BluetoothAgentManagerClientImpl : public BluetoothAgentManagerClient { + public: + BluetoothAgentManagerClientImpl() : weak_ptr_factory_(this) {} + + ~BluetoothAgentManagerClientImpl() override {} + + // BluetoothAgentManagerClient override. + void RegisterAgent(const dbus::ObjectPath& agent_path, + const std::string& capability, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_agent_manager::kBluetoothAgentManagerInterface, + bluetooth_agent_manager::kRegisterAgent); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(agent_path); + writer.AppendString(capability); + + object_proxy_->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAgentManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAgentManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothAgentManagerClient override. + void UnregisterAgent(const dbus::ObjectPath& agent_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_agent_manager::kBluetoothAgentManagerInterface, + bluetooth_agent_manager::kUnregisterAgent); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(agent_path); + + object_proxy_->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAgentManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAgentManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothAgentManagerClient override. + void RequestDefaultAgent(const dbus::ObjectPath& agent_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_agent_manager::kBluetoothAgentManagerInterface, + bluetooth_agent_manager::kRequestDefaultAgent); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(agent_path); + + object_proxy_->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAgentManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAgentManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + protected: + void Init(dbus::Bus* bus) override { + DCHECK(bus); + object_proxy_ = bus->GetObjectProxy( + bluetooth_agent_manager::kBluetoothAgentManagerServiceName, + dbus::ObjectPath( + bluetooth_agent_manager::kBluetoothAgentManagerServicePath)); + } + + private: + // Called when a response for successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + // Error response has optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + error_message = ""; + } + error_callback.Run(error_name, error_message); + } + + dbus::ObjectProxy* object_proxy_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothAgentManagerClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothAgentManagerClientImpl); +}; + +BluetoothAgentManagerClient::BluetoothAgentManagerClient() {} + +BluetoothAgentManagerClient::~BluetoothAgentManagerClient() {} + +BluetoothAgentManagerClient* BluetoothAgentManagerClient::Create() { + return new BluetoothAgentManagerClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_agent_manager_client.h b/device/bluetooth/dbus/bluetooth_agent_manager_client.h new file mode 100644 index 0000000..47402dd --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_agent_manager_client.h @@ -0,0 +1,70 @@ +// Copyright 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_MANAGER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_MANAGER_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/values.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothAgentManagerClient is used to communicate with the agent manager +// object of the Bluetooth daemon. +class DEVICE_BLUETOOTH_EXPORT BluetoothAgentManagerClient + : public BluezDBusClient { + public: + ~BluetoothAgentManagerClient() override; + + // The ErrorCallback is used by agent manager methods to indicate failure. + // It receives two arguments: the name of the error in |error_name| and + // an optional message in |error_message|. + typedef base::Callback<void(const std::string& error_name, + const std::string& error_message)> ErrorCallback; + + // Registers an agent within the local process at the D-bus object path + // |agent_path| with the remote agent manager. The agent is used for pairing + // and for authorization of incoming connection requests. |capability| + // specifies the input and display capabilities of the agent and should be + // one of the constants declared in the bluetooth_agent_manager:: namespace. + virtual void RegisterAgent(const dbus::ObjectPath& agent_path, + const std::string& capability, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Unregisters the agent with the D-Bus object path |agent_path| from the + // remote agent manager. + virtual void UnregisterAgent(const dbus::ObjectPath& agent_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Requests that the agent with the D-Bus object path |agent_path| be made + // the default. + virtual void RequestDefaultAgent(const dbus::ObjectPath& agent_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Creates the instance. + static BluetoothAgentManagerClient* Create(); + + // Constants used to indicate exceptional error conditions. + static const char kNoResponseError[]; + + protected: + BluetoothAgentManagerClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothAgentManagerClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_MANAGER_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_agent_service_provider.cc b/device/bluetooth/dbus/bluetooth_agent_service_provider.cc new file mode 100644 index 0000000..7392f2b --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_agent_service_provider.cc @@ -0,0 +1,444 @@ +// Copyright 2013 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 "device/bluetooth/dbus/bluetooth_agent_service_provider.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/threading/platform_thread.h" +#include "dbus/exported_object.h" +#include "dbus/message.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +// The BluetoothAgentServiceProvider implementation used in production. +class BluetoothAgentServiceProviderImpl : public BluetoothAgentServiceProvider { + public: + BluetoothAgentServiceProviderImpl(dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate) + : origin_thread_id_(base::PlatformThread::CurrentId()), + bus_(bus), + delegate_(delegate), + object_path_(object_path), + weak_ptr_factory_(this) { + VLOG(1) << "Creating Bluetooth Agent: " << object_path_.value(); + + exported_object_ = bus_->GetExportedObject(object_path_); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, bluetooth_agent::kRelease, + base::Bind(&BluetoothAgentServiceProviderImpl::Release, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kRequestPinCode, + base::Bind(&BluetoothAgentServiceProviderImpl::RequestPinCode, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kDisplayPinCode, + base::Bind(&BluetoothAgentServiceProviderImpl::DisplayPinCode, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kRequestPasskey, + base::Bind(&BluetoothAgentServiceProviderImpl::RequestPasskey, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kDisplayPasskey, + base::Bind(&BluetoothAgentServiceProviderImpl::DisplayPasskey, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kRequestConfirmation, + base::Bind(&BluetoothAgentServiceProviderImpl::RequestConfirmation, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kRequestAuthorization, + base::Bind(&BluetoothAgentServiceProviderImpl::RequestAuthorization, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, + bluetooth_agent::kAuthorizeService, + base::Bind(&BluetoothAgentServiceProviderImpl::AuthorizeService, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_agent::kBluetoothAgentInterface, bluetooth_agent::kCancel, + base::Bind(&BluetoothAgentServiceProviderImpl::Cancel, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAgentServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + } + + ~BluetoothAgentServiceProviderImpl() override { + VLOG(1) << "Cleaning up Bluetooth Agent: " << object_path_.value(); + + // Unregister the object path so we can reuse with a new agent. + bus_->UnregisterExportedObject(object_path_); + } + + private: + // Returns true if the current thread is on the origin thread. + bool OnOriginThread() { + return base::PlatformThread::CurrentId() == origin_thread_id_; + } + + // Called by dbus:: when the agent is unregistered from the Bluetooth + // daemon, generally at the end of a pairing request. + void Release(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + delegate_->Released(); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when the Bluetooth daemon requires a PIN Code for + // device authentication. + void RequestPinCode(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + if (!reader.PopObjectPath(&device_path)) { + LOG(WARNING) << "RequestPinCode called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::PinCodeCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnPinCode, + weak_ptr_factory_.GetWeakPtr(), method_call, response_sender); + + delegate_->RequestPinCode(device_path, callback); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // enter a PIN Code into the remote device so that it may be + // authenticated. + void DisplayPinCode(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + std::string pincode; + if (!reader.PopObjectPath(&device_path) || !reader.PopString(&pincode)) { + LOG(WARNING) << "DisplayPinCode called with incorrect paramters: " + << method_call->ToString(); + return; + } + + delegate_->DisplayPinCode(device_path, pincode); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when the Bluetooth daemon requires a Passkey for + // device authentication. + void RequestPasskey(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + if (!reader.PopObjectPath(&device_path)) { + LOG(WARNING) << "RequestPasskey called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::PasskeyCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnPasskey, + weak_ptr_factory_.GetWeakPtr(), method_call, response_sender); + + delegate_->RequestPasskey(device_path, callback); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // enter a Passkey into the remote device so that it may be + // authenticated. + void DisplayPasskey(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + uint32 passkey; + uint16 entered; + if (!reader.PopObjectPath(&device_path) || !reader.PopUint32(&passkey) || + !reader.PopUint16(&entered)) { + LOG(WARNING) << "DisplayPasskey called with incorrect paramters: " + << method_call->ToString(); + return; + } + + delegate_->DisplayPasskey(device_path, passkey, entered); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // confirm that a Passkey is displayed on the screen of the remote + // device so that it may be authenticated. + void RequestConfirmation( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + uint32 passkey; + if (!reader.PopObjectPath(&device_path) || !reader.PopUint32(&passkey)) { + LOG(WARNING) << "RequestConfirmation called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::ConfirmationCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnConfirmation, + weak_ptr_factory_.GetWeakPtr(), method_call, response_sender); + + delegate_->RequestConfirmation(device_path, passkey, callback); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // confirm an incoming just-works pairing. + void RequestAuthorization( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + if (!reader.PopObjectPath(&device_path)) { + LOG(WARNING) << "RequestAuthorization called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::ConfirmationCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnConfirmation, + weak_ptr_factory_.GetWeakPtr(), method_call, response_sender); + + delegate_->RequestAuthorization(device_path, callback); + } + + // Called by dbus:: when the Bluetooth daemon requires that the user + // confirm that that a remote device is authorized to connect to a service + // UUID. + void AuthorizeService(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + std::string uuid; + if (!reader.PopObjectPath(&device_path) || !reader.PopString(&uuid)) { + LOG(WARNING) << "AuthorizeService called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::ConfirmationCallback callback = base::Bind( + &BluetoothAgentServiceProviderImpl::OnConfirmation, + weak_ptr_factory_.GetWeakPtr(), method_call, response_sender); + + delegate_->AuthorizeService(device_path, uuid, callback); + } + + // Called by dbus:: when the request failed before a reply was returned + // from the device. + void Cancel(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + delegate_->Cancel(); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when a method is exported. + void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "." + << method_name; + } + + // Called by the Delegate to response to a method requesting a PIN code. + void OnPinCode(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + Delegate::Status status, + const std::string& pincode) { + DCHECK(OnOriginThread()); + + switch (status) { + case Delegate::SUCCESS: { + scoped_ptr<dbus::Response> response( + dbus::Response::FromMethodCall(method_call)); + dbus::MessageWriter writer(response.get()); + writer.AppendString(pincode); + response_sender.Run(response.Pass()); + break; + } + case Delegate::REJECTED: { + response_sender.Run(dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorRejected, "rejected")); + break; + } + case Delegate::CANCELLED: { + response_sender.Run(dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorCanceled, "canceled")); + break; + } + default: + NOTREACHED() << "Unexpected status code from delegate: " << status; + } + } + + // Called by the Delegate to response to a method requesting a Passkey. + void OnPasskey(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + Delegate::Status status, + uint32 passkey) { + DCHECK(OnOriginThread()); + + switch (status) { + case Delegate::SUCCESS: { + scoped_ptr<dbus::Response> response( + dbus::Response::FromMethodCall(method_call)); + dbus::MessageWriter writer(response.get()); + writer.AppendUint32(passkey); + response_sender.Run(response.Pass()); + break; + } + case Delegate::REJECTED: { + response_sender.Run(dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorRejected, "rejected")); + break; + } + case Delegate::CANCELLED: { + response_sender.Run(dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorCanceled, "canceled")); + break; + } + default: + NOTREACHED() << "Unexpected status code from delegate: " << status; + } + } + + // Called by the Delegate in response to a method requiring confirmation. + void OnConfirmation(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + Delegate::Status status) { + DCHECK(OnOriginThread()); + + switch (status) { + case Delegate::SUCCESS: { + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + break; + } + case Delegate::REJECTED: { + response_sender.Run(dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorRejected, "rejected")); + break; + } + case Delegate::CANCELLED: { + response_sender.Run(dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_agent::kErrorCanceled, "canceled")); + break; + } + default: + NOTREACHED() << "Unexpected status code from delegate: " << status; + } + } + + // Origin thread (i.e. the UI thread in production). + base::PlatformThreadId origin_thread_id_; + + // D-Bus bus object is exported on, not owned by this object and must + // outlive it. + dbus::Bus* bus_; + + // All incoming method calls are passed on to the Delegate and a callback + // passed to generate the reply. |delegate_| is generally the object that + // owns this one, and must outlive it. + Delegate* delegate_; + + // D-Bus object path of object we are exporting, kept so we can unregister + // again in our destructor. + dbus::ObjectPath object_path_; + + // D-Bus object we are exporting, owned by this object. + scoped_refptr<dbus::ExportedObject> exported_object_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothAgentServiceProviderImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothAgentServiceProviderImpl); +}; + +BluetoothAgentServiceProvider::BluetoothAgentServiceProvider() {} + +BluetoothAgentServiceProvider::~BluetoothAgentServiceProvider() {} + +// static +BluetoothAgentServiceProvider* BluetoothAgentServiceProvider::Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate) { + if (!bluez::BluezDBusManager::Get()->IsUsingStub()) { + return new BluetoothAgentServiceProviderImpl(bus, object_path, delegate); + } else { + return new FakeBluetoothAgentServiceProvider(object_path, delegate); + } +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_agent_service_provider.h b/device/bluetooth/dbus/bluetooth_agent_service_provider.h new file mode 100644 index 0000000..e31ef8f --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_agent_service_provider.h @@ -0,0 +1,178 @@ +// Copyright 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "dbus/bus.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" + +namespace bluez { + +// BluetoothAgentServiceProvider is used to provide a D-Bus object that +// the bluetooth daemon can communicate with during a remote device pairing +// request. +// +// Instantiate with a chosen D-Bus object path and delegate object, and pass +// the D-Bus object path as the |agent_path| argument to the +// chromeos::BluetoothAgentManagerClient::RegisterAgent() method. +// +// After initiating the pairing process with a device, using the +// chromeos::BluetoothDeviceClient::Pair() method, the Bluetooth daemon will +// make calls to this agent object and they will be passed on to your Delegate +// object for handling. Responses should be returned using the callbacks +// supplied to those methods. +class DEVICE_BLUETOOTH_EXPORT BluetoothAgentServiceProvider { + public: + // Interface for reacting to agent requests. + class Delegate { + public: + virtual ~Delegate() {} + + // Possible status values that may be returned to callbacks. Success + // indicates that a pincode or passkey has been obtained, or permission + // granted; rejected indicates the user rejected the request or denied + // permission; cancelled indicates the user cancelled the request + // without confirming either way. + enum Status { SUCCESS, REJECTED, CANCELLED }; + + // The PinCodeCallback is used for the RequestPinCode() method, it should + // be called with two arguments, the |status| of the request (success, + // rejected or cancelled) and the |pincode| requested. + typedef base::Callback<void(Status, const std::string&)> PinCodeCallback; + + // The PasskeyCallback is used for the RequestPasskey() method, it should + // be called with two arguments, the |status| of the request (success, + // rejected or cancelled) and the |passkey| requested, a numeric in the + // range 0-999999, + typedef base::Callback<void(Status, uint32)> PasskeyCallback; + + // The ConfirmationCallback is used for methods which request confirmation + // or authorization, it should be called with one argument, the |status| + // of the request (success, rejected or cancelled). + typedef base::Callback<void(Status)> ConfirmationCallback; + + // This method will be called when the agent is unregistered from the + // Bluetooth daemon, generally at the end of a pairing request. It may be + // used to perform cleanup tasks. This corresponds to the + // org.bluez.Agent1.Release method and is renamed to avoid a conflict + // with base::Refcounted<T>. + virtual void Released() = 0; + + // This method will be called when the Bluetooth daemon requires a + // PIN Code for authentication of the device with object path |device_path|, + // the agent should obtain the code from the user and call |callback| + // to provide it, or indicate rejection or cancellation of the request. + // + // PIN Codes are generally required for Bluetooth 2.0 and earlier devices + // for which there is no automatic pairing or special handling. + virtual void RequestPinCode(const dbus::ObjectPath& device_path, + const PinCodeCallback& callback) = 0; + + // This method will be called when the Bluetooth daemon requires that the + // user enter the PIN code |pincode| into the device with object path + // |device_path| so that it may be authenticated. The Cancel() method + // will be called to dismiss the display once pairing is complete or + // cancelled. + // + // This is used for Bluetooth 2.0 and earlier keyboard devices, the + // |pincode| will always be a six-digit numeric in the range 000000-999999 + // for compatibilty with later specifications. + virtual void DisplayPinCode(const dbus::ObjectPath& device_path, + const std::string& pincode) = 0; + + // This method will be called when the Bluetooth daemon requires a + // Passkey for authentication of the device with object path |device_path|, + // the agent should obtain the passkey from the user (a numeric in the + // range 0-999999) and call |callback| to provide it, or indicate + // rejection or cancellation of the request. + // + // Passkeys are generally required for Bluetooth 2.1 and later devices + // which cannot provide input or display on their own, and don't accept + // passkey-less pairing. + virtual void RequestPasskey(const dbus::ObjectPath& device_path, + const PasskeyCallback& callback) = 0; + + // This method will be called when the Bluetooth daemon requires that the + // user enter the Passkey |passkey| into the device with object path + // |device_path| so that it may be authenticated. The Cancel() method + // will be called to dismiss the display once pairing is complete or + // cancelled. + // + // This is used for Bluetooth 2.1 and later devices that support input + // but not display, such as keyboards. The Passkey is a numeric in the + // range 0-999999 and should be always presented zero-padded to six + // digits. + // + // As the user enters the passkey onto the device, |entered| will be + // updated to reflect the number of digits entered so far. + virtual void DisplayPasskey(const dbus::ObjectPath& device_path, + uint32 passkey, + uint16 entered) = 0; + + // This method will be called when the Bluetooth daemon requires that the + // user confirm that the Passkey |passkey| is displayed on the screen + // of the device with object path |object_path| so that it may be + // authenticated. The agent should display to the user and ask for + // confirmation, then call |callback| to provide their response (success, + // rejected or cancelled). + // + // This is used for Bluetooth 2.1 and later devices that support display, + // such as other computers or phones. The Passkey is a numeric in the + // range 0-999999 and should be always present zero-padded to six + // digits. + virtual void RequestConfirmation(const dbus::ObjectPath& device_path, + uint32 passkey, + const ConfirmationCallback& callback) = 0; + + // This method will be called when the Bluetooth daemon requires + // authorization of an incoming pairing attempt from the device with object + // path |device_path| that would have otherwised triggered the just-works + // pairing model. + // + // The agent should confirm the incoming pairing with the user and call + // |callback| to provide their response (success, rejected or cancelled). + virtual void RequestAuthorization(const dbus::ObjectPath& device_path, + const ConfirmationCallback& callback) = 0; + + // This method will be called when the Bluetooth daemon requires that the + // user confirm that the device with object path |object_path| is + // authorized to connect to the service with UUID |uuid|. The agent should + // confirm with the user and call |callback| to provide their response + // (success, rejected or cancelled). + virtual void AuthorizeService(const dbus::ObjectPath& device_path, + const std::string& uuid, + const ConfirmationCallback& callback) = 0; + + // This method will be called by the Bluetooth daemon to indicate that + // the request failed before a reply was returned from the device. + virtual void Cancel() = 0; + }; + + virtual ~BluetoothAgentServiceProvider(); + + // Creates the instance where |bus| is the D-Bus bus connection to export + // the object onto, |object_path| is the object path that it should have + // and |delegate| is the object to which all method calls will be passed + // and responses generated from. + static BluetoothAgentServiceProvider* Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate); + + protected: + BluetoothAgentServiceProvider(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothAgentServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc new file mode 100644 index 0000000..29a4ce8 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.cc @@ -0,0 +1,84 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_dbus_client_bundle.h" + +#include <vector> + +#include "base/command_line.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "chromeos/chromeos_switches.h" +#include "device/bluetooth/dbus/bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_device_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h" +#include "device/bluetooth/dbus/bluetooth_input_client.h" +#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_media_client.h" +#include "device/bluetooth/dbus/bluetooth_media_transport_client.h" +#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_device_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_input_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h" + +namespace bluez { + +BluetoothDBusClientBundle::BluetoothDBusClientBundle(bool use_stubs) + : use_stubs_(use_stubs) { + if (!use_stubs) { + bluetooth_adapter_client_.reset(BluetoothAdapterClient::Create()); + bluetooth_le_advertising_manager_client_.reset( + BluetoothLEAdvertisingManagerClient::Create()); + bluetooth_agent_manager_client_.reset( + BluetoothAgentManagerClient::Create()); + bluetooth_device_client_.reset(BluetoothDeviceClient::Create()); + bluetooth_input_client_.reset(BluetoothInputClient::Create()); + bluetooth_media_client_.reset(BluetoothMediaClient::Create()); + bluetooth_media_transport_client_.reset( + BluetoothMediaTransportClient::Create()); + bluetooth_profile_manager_client_.reset( + BluetoothProfileManagerClient::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()); + } else { + bluetooth_adapter_client_.reset(new FakeBluetoothAdapterClient); + bluetooth_le_advertising_manager_client_.reset( + new FakeBluetoothLEAdvertisingManagerClient); + bluetooth_agent_manager_client_.reset(new FakeBluetoothAgentManagerClient); + bluetooth_device_client_.reset(new FakeBluetoothDeviceClient); + bluetooth_input_client_.reset(new FakeBluetoothInputClient); + bluetooth_media_client_.reset(new FakeBluetoothMediaClient); + bluetooth_media_transport_client_.reset( + new FakeBluetoothMediaTransportClient); + bluetooth_profile_manager_client_.reset( + new FakeBluetoothProfileManagerClient); + bluetooth_gatt_characteristic_client_.reset( + new FakeBluetoothGattCharacteristicClient); + bluetooth_gatt_descriptor_client_.reset( + new FakeBluetoothGattDescriptorClient); + bluetooth_gatt_manager_client_.reset(new FakeBluetoothGattManagerClient); + bluetooth_gatt_service_client_.reset(new FakeBluetoothGattServiceClient); + } +} + +BluetoothDBusClientBundle::~BluetoothDBusClientBundle() {} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h new file mode 100644 index 0000000..3beef61 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h @@ -0,0 +1,114 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DBUS_CLIENT_BUNDLE_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DBUS_CLIENT_BUNDLE_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "device/bluetooth/bluetooth_export.h" + +namespace bluez { + +class BluetoothAdapterClient; +class BluetoothAgentManagerClient; +class BluetoothDeviceClient; +class BluetoothGattCharacteristicClient; +class BluetoothGattDescriptorClient; +class BluetoothGattManagerClient; +class BluetoothGattServiceClient; +class BluetoothInputClient; +class BluetoothLEAdvertisingManagerClient; +class BluetoothMediaClient; +class BluetoothMediaTransportClient; +class BluetoothProfileManagerClient; + +// The bundle of all D-Bus clients used in DBusThreadManager. 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 DBusThreadManager. +class DEVICE_BLUETOOTH_EXPORT BluetoothDBusClientBundle { + public: + explicit BluetoothDBusClientBundle(bool use_stubs); + ~BluetoothDBusClientBundle(); + + // Returns true if |client| is stubbed. + bool IsUsingStub() { return use_stubs_; } + + BluetoothAdapterClient* bluetooth_adapter_client() { + return bluetooth_adapter_client_.get(); + } + + BluetoothLEAdvertisingManagerClient* + bluetooth_le_advertising_manager_client() { + return bluetooth_le_advertising_manager_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(); + } + + BluetoothMediaClient* bluetooth_media_client() { + return bluetooth_media_client_.get(); + } + + BluetoothMediaTransportClient* bluetooth_media_transport_client() { + return bluetooth_media_transport_client_.get(); + } + + BluetoothProfileManagerClient* bluetooth_profile_manager_client() { + return bluetooth_profile_manager_client_.get(); + } + + private: + friend class BluezDBusManagerSetter; + + bool use_stubs_; + + scoped_ptr<BluetoothAdapterClient> bluetooth_adapter_client_; + scoped_ptr<BluetoothLEAdvertisingManagerClient> + bluetooth_le_advertising_manager_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<BluetoothMediaClient> bluetooth_media_client_; + scoped_ptr<BluetoothMediaTransportClient> bluetooth_media_transport_client_; + scoped_ptr<BluetoothProfileManagerClient> bluetooth_profile_manager_client_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothDBusClientBundle); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DBUS_CLIENT_BUNDLE_H_ diff --git a/device/bluetooth/dbus/bluetooth_device_client.cc b/device/bluetooth/dbus/bluetooth_device_client.cc new file mode 100644 index 0000000..7aaafa2 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_device_client.cc @@ -0,0 +1,379 @@ +// Copyright 2013 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 "device/bluetooth/dbus/bluetooth_device_client.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/stl_util.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_manager.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +namespace { + +// Value returned for the the RSSI or TX power if it cannot be read. +const int kUnknownPower = 127; + +} // namespace + +const char BluetoothDeviceClient::kNoResponseError[] = + "org.chromium.Error.NoResponse"; +const char BluetoothDeviceClient::kUnknownDeviceError[] = + "org.chromium.Error.UnknownDevice"; + +BluetoothDeviceClient::Properties::Properties( + dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback) + : dbus::PropertySet(object_proxy, interface_name, callback) { + RegisterProperty(bluetooth_device::kAddressProperty, &address); + RegisterProperty(bluetooth_device::kNameProperty, &name); + RegisterProperty(bluetooth_device::kIconProperty, &icon); + RegisterProperty(bluetooth_device::kClassProperty, &bluetooth_class); + RegisterProperty(bluetooth_device::kAppearanceProperty, &appearance); + RegisterProperty(bluetooth_device::kUUIDsProperty, &uuids); + RegisterProperty(bluetooth_device::kPairedProperty, &paired); + RegisterProperty(bluetooth_device::kConnectedProperty, &connected); + RegisterProperty(bluetooth_device::kTrustedProperty, &trusted); + RegisterProperty(bluetooth_device::kBlockedProperty, &blocked); + RegisterProperty(bluetooth_device::kAliasProperty, &alias); + RegisterProperty(bluetooth_device::kAdapterProperty, &adapter); + RegisterProperty(bluetooth_device::kLegacyPairingProperty, &legacy_pairing); + RegisterProperty(bluetooth_device::kModaliasProperty, &modalias); + RegisterProperty(bluetooth_device::kRSSIProperty, &rssi); + RegisterProperty(bluetooth_device::kTxPowerProperty, &tx_power); + RegisterProperty(bluetooth_device::kGattServicesProperty, &gatt_services); +} + +BluetoothDeviceClient::Properties::~Properties() {} + +// The BluetoothDeviceClient implementation used in production. +class BluetoothDeviceClientImpl : public BluetoothDeviceClient, + public dbus::ObjectManager::Interface { + public: + BluetoothDeviceClientImpl() + : object_manager_(NULL), weak_ptr_factory_(this) {} + + ~BluetoothDeviceClientImpl() override { + object_manager_->UnregisterInterface( + bluetooth_device::kBluetoothDeviceInterface); + } + + // BluetoothDeviceClient override. + void AddObserver(BluetoothDeviceClient::Observer* observer) override { + DCHECK(observer); + observers_.AddObserver(observer); + } + + // BluetoothDeviceClient override. + void RemoveObserver(BluetoothDeviceClient::Observer* observer) override { + DCHECK(observer); + observers_.RemoveObserver(observer); + } + + // dbus::ObjectManager::Interface override. + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + Properties* properties = + new Properties(object_proxy, interface_name, + base::Bind(&BluetoothDeviceClientImpl::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), object_path)); + return static_cast<dbus::PropertySet*>(properties); + } + + // BluetoothDeviceClient override. + std::vector<dbus::ObjectPath> GetDevicesForAdapter( + const dbus::ObjectPath& adapter_path) override { + std::vector<dbus::ObjectPath> object_paths, device_paths; + device_paths = object_manager_->GetObjectsWithInterface( + bluetooth_device::kBluetoothDeviceInterface); + for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin(); + iter != device_paths.end(); ++iter) { + Properties* properties = GetProperties(*iter); + if (properties->adapter.value() == adapter_path) + object_paths.push_back(*iter); + } + return object_paths; + } + + // BluetoothDeviceClient override. + Properties* GetProperties(const dbus::ObjectPath& object_path) override { + return static_cast<Properties*>(object_manager_->GetProperties( + object_path, bluetooth_device::kBluetoothDeviceInterface)); + } + + // BluetoothDeviceClient override. + void Connect(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface, + bluetooth_device::kConnect); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownDeviceError, ""); + return; + } + + // Connect may take an arbitrary length of time, so use no timeout. + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE, + base::Bind(&BluetoothDeviceClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothDeviceClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothDeviceClient override. + void Disconnect(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface, + bluetooth_device::kDisconnect); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownDeviceError, ""); + return; + } + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothDeviceClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothDeviceClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothDeviceClient override. + void ConnectProfile(const dbus::ObjectPath& object_path, + const std::string& uuid, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface, + bluetooth_device::kConnectProfile); + + dbus::MessageWriter writer(&method_call); + writer.AppendString(uuid); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownDeviceError, ""); + return; + } + + // Connect may take an arbitrary length of time, so use no timeout. + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE, + base::Bind(&BluetoothDeviceClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothDeviceClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothDeviceClient override. + void DisconnectProfile(const dbus::ObjectPath& object_path, + const std::string& uuid, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface, + bluetooth_device::kDisconnectProfile); + + dbus::MessageWriter writer(&method_call); + writer.AppendString(uuid); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownDeviceError, ""); + return; + } + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothDeviceClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothDeviceClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothDeviceClient override. + void Pair(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface, + bluetooth_device::kPair); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownDeviceError, ""); + return; + } + + // Pairing may take an arbitrary length of time, so use no timeout. + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_INFINITE, + base::Bind(&BluetoothDeviceClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothDeviceClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothDeviceClient override. + void CancelPairing(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface, + bluetooth_device::kCancelPairing); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownDeviceError, ""); + return; + } + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothDeviceClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothDeviceClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothDeviceClient override. + void GetConnInfo(const dbus::ObjectPath& object_path, + const ConnInfoCallback& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_plugin_device::kBluetoothPluginInterface, + bluetooth_plugin_device::kGetConnInfo); + + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownDeviceError, ""); + return; + } + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothDeviceClientImpl::OnGetConnInfoSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothDeviceClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + protected: + void Init(dbus::Bus* bus) override { + object_manager_ = bus->GetObjectManager( + bluetooth_object_manager::kBluetoothObjectManagerServiceName, + dbus::ObjectPath( + bluetooth_object_manager::kBluetoothObjectManagerServicePath)); + object_manager_->RegisterInterface( + bluetooth_device::kBluetoothDeviceInterface, this); + } + + private: + // Called by dbus::ObjectManager when an object with the device interface + // is created. Informs observers. + void ObjectAdded(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, + DeviceAdded(object_path)); + } + + // Called by dbus::ObjectManager when an object with the device interface + // is removed. Informs observers. + void ObjectRemoved(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, + DeviceRemoved(object_path)); + } + + // Called by BluetoothPropertySet when a property value is changed, + // either by result of a signal or response to a GetAll() or Get() + // call. Informs observers. + void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) { + FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, + DevicePropertyChanged(object_path, property_name)); + } + + // Called when a response for successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a response for the GetConnInfo method is received. + void OnGetConnInfoSuccess(const ConnInfoCallback& callback, + dbus::Response* response) { + int16 rssi = kUnknownPower; + int16 transmit_power = kUnknownPower; + int16 max_transmit_power = kUnknownPower; + + if (!response) { + LOG(ERROR) << "GetConnInfo succeeded, but no response received."; + callback.Run(rssi, transmit_power, max_transmit_power); + return; + } + + dbus::MessageReader reader(response); + if (!reader.PopInt16(&rssi) || !reader.PopInt16(&transmit_power) || + !reader.PopInt16(&max_transmit_power)) { + LOG(ERROR) << "Arguments for GetConnInfo invalid."; + } + callback.Run(rssi, transmit_power, max_transmit_power); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + // Error response has optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + error_message = ""; + } + error_callback.Run(error_name, error_message); + } + + dbus::ObjectManager* object_manager_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothDeviceClient::Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothDeviceClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl); +}; + +BluetoothDeviceClient::BluetoothDeviceClient() {} + +BluetoothDeviceClient::~BluetoothDeviceClient() {} + +BluetoothDeviceClient* BluetoothDeviceClient::Create() { + return new BluetoothDeviceClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_device_client.h b/device/bluetooth/dbus/bluetooth_device_client.h new file mode 100644 index 0000000..33b3f5d --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_device_client.h @@ -0,0 +1,213 @@ +// Copyright 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DEVICE_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DEVICE_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/observer_list.h" +#include "base/values.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothDeviceClient is used to communicate with objects representing +// remote Bluetooth Devices. +class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceClient : public BluezDBusClient { + public: + // Structure of properties associated with bluetooth devices. + struct Properties : public dbus::PropertySet { + // The Bluetooth device address of the device. Read-only. + dbus::Property<std::string> address; + + // The Bluetooth friendly name of the device. Read-only, to give a + // different local name, use the |alias| property. + dbus::Property<std::string> name; + + // Proposed icon name for the device according to the freedesktop.org + // icon naming specification. Read-only. + dbus::Property<std::string> icon; + + // The Bluetooth class of the device. Read-only. + dbus::Property<uint32> bluetooth_class; + + // The GAP external appearance of the device. Read-only. + dbus::Property<uint16> appearance; + + // Unique numeric identifier for the vendor of the device. Read-only. + dbus::Property<uint16> vendor; + + // List of 128-bit UUIDs that represent the available remote services. + // Read-only. + dbus::Property<std::vector<std::string>> uuids; + + // Transmitted power level. This field is avaliable only for LE devices + // that include this field in AD. Read-only. + dbus::Property<int16> tx_power; + + // Indicates that the device is currently paired. Read-only. + dbus::Property<bool> paired; + + // Indicates that the device is currently connected. Read-only. + dbus::Property<bool> connected; + + // Whether the device is trusted, and connections should be always + // accepted and attempted when the device is visible. + dbus::Property<bool> trusted; + + // Whether the device is blocked, connections will be always rejected + // and the device will not be visible. + dbus::Property<bool> blocked; + + // Local alias for the device, if not set, is equal to |name|. + dbus::Property<std::string> alias; + + // Object path of the adapter the device belongs to. Read-only. + dbus::Property<dbus::ObjectPath> adapter; + + // Indicates whether the device is likely to only support pre-2.1 + // PIN Code pairing rather than 2.1 Secure Simple Pairing, this can + // give false positives. Read-only. + dbus::Property<bool> legacy_pairing; + + // Remote Device ID information in Linux kernel modalias format. Read-only. + dbus::Property<std::string> modalias; + + // Received signal strength indicator that is set when the device is + // discovered during inquiry. Read-only. + dbus::Property<int16> rssi; + + // List of GATT service object paths. Each referenced object exports the + // org.bluez.GattService1 interface and represents a remote GATT service. + // This property will be updated once all remote GATT services of this + // device have been discovered and exported over D-Bus. Read-only. + dbus::Property<std::vector<dbus::ObjectPath>> gatt_services; + + Properties(dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback); + ~Properties() override; + }; + + // Interface for observing changes from a remote bluetooth device. + class Observer { + public: + virtual ~Observer() {} + + // Called when the remote device with object path |object_path| is added + // to the set of known devices. + virtual void DeviceAdded(const dbus::ObjectPath& object_path) {} + + // Called when the remote device with object path |object_path| is removed + // from the set of known devices. + virtual void DeviceRemoved(const dbus::ObjectPath& object_path) {} + + // Called when the device with object path |object_path| has a + // change in value of the property named |property_name|. + virtual void DevicePropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) {} + }; + + ~BluetoothDeviceClient() override; + + // Adds and removes observers for events on all remote bluetooth + // devices. Check the |object_path| parameter of observer methods to + // determine which device is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Returns the list of device object paths associated with the given adapter + // identified by the D-Bus object path |adapter_path|. + virtual std::vector<dbus::ObjectPath> GetDevicesForAdapter( + const dbus::ObjectPath& adapter_path) = 0; + + // Obtain the properties for the device with object path |object_path|, + // any values should be copied if needed. + virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0; + + // The ErrorCallback is used by device methods to indicate failure. + // It receives two arguments: the name of the error in |error_name| and + // an optional message in |error_message|. + typedef base::Callback<void(const std::string& error_name, + const std::string& error_message)> ErrorCallback; + + // Connects to the device with object path |object_path|, connecting any + // profiles that can be connected to and have been flagged as auto-connected; + // may be used to connect additional profiles for an already connected device, + // and succeeds if at least one profile is connected. + virtual void Connect(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Disconnects the device with object path |object_path|, terminating + // the low-level ACL connection and any profiles using it. + virtual void Disconnect(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Connects to the profile |uuid| on the device with object path + // |object_path|, provided that the profile has been registered with a + // handler on the local device. + virtual void ConnectProfile(const dbus::ObjectPath& object_path, + const std::string& uuid, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Disconnects from the profile |uuid| on the device with object path + // |object_path|. + virtual void DisconnectProfile(const dbus::ObjectPath& object_path, + const std::string& uuid, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Initiates pairing with the device with object path |object_path| and + // retrieves all SDP records or GATT primary services. An agent must be + // registered to handle the pairing request. + virtual void Pair(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Cancels an in-progress pairing with the device with object path + // |object_path| initiated by Pair(). + virtual void CancelPairing(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // The callback invoked for a successful GetConnInfo API call with the + // RSSI, TX power, and maximum TX power of the current connection. + typedef base::Callback<void(int16 rssi, + int16 transmit_power, + int16 max_transmit_power)> ConnInfoCallback; + + // Returns the RSSI, TX power, and maximum TX power of a connection to the + // device with object path |object_path|. If the device is not connected, then + // an error will be returned. + virtual void GetConnInfo(const dbus::ObjectPath& object_path, + const ConnInfoCallback& callback, + const ErrorCallback& error_callback) = 0; + + // Creates the instance. + static BluetoothDeviceClient* Create(); + + // Constants used to indicate exceptional error conditions. + static const char kNoResponseError[]; + static const char kUnknownDeviceError[]; + + protected: + BluetoothDeviceClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_DEVICE_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc new file mode 100644 index 0000000..6000a52 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc @@ -0,0 +1,303 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" + +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "dbus/bus.h" +#include "dbus/object_manager.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +namespace { + +// TODO(armansito): Move this constant to cros_system_api. +const char kValueProperty[] = "Value"; + +} // namespace + +// static +const char BluetoothGattCharacteristicClient::kNoResponseError[] = + "org.chromium.Error.NoResponse"; +// static +const char BluetoothGattCharacteristicClient::kUnknownCharacteristicError[] = + "org.chromium.Error.UnknownCharacteristic"; + +BluetoothGattCharacteristicClient::Properties::Properties( + dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback) + : dbus::PropertySet(object_proxy, interface_name, callback) { + RegisterProperty(bluetooth_gatt_characteristic::kUUIDProperty, &uuid); + RegisterProperty(bluetooth_gatt_characteristic::kServiceProperty, &service); + RegisterProperty(kValueProperty, &value); + RegisterProperty(bluetooth_gatt_characteristic::kNotifyingProperty, + ¬ifying); + RegisterProperty(bluetooth_gatt_characteristic::kFlagsProperty, &flags); + RegisterProperty(bluetooth_gatt_characteristic::kDescriptorsProperty, + &descriptors); +} + +BluetoothGattCharacteristicClient::Properties::~Properties() {} + +// The BluetoothGattCharacteristicClient implementation used in production. +class BluetoothGattCharacteristicClientImpl + : public BluetoothGattCharacteristicClient, + public dbus::ObjectManager::Interface { + public: + BluetoothGattCharacteristicClientImpl() + : object_manager_(NULL), weak_ptr_factory_(this) {} + + ~BluetoothGattCharacteristicClientImpl() override { + object_manager_->UnregisterInterface( + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface); + } + + // BluetoothGattCharacteristicClient override. + void AddObserver( + BluetoothGattCharacteristicClient::Observer* observer) override { + DCHECK(observer); + observers_.AddObserver(observer); + } + + // BluetoothGattCharacteristicClient override. + void RemoveObserver( + BluetoothGattCharacteristicClient::Observer* observer) override { + DCHECK(observer); + observers_.RemoveObserver(observer); + } + + // BluetoothGattCharacteristicClient override. + std::vector<dbus::ObjectPath> GetCharacteristics() override { + DCHECK(object_manager_); + return object_manager_->GetObjectsWithInterface( + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface); + } + + // BluetoothGattCharacteristicClient override. + Properties* GetProperties(const dbus::ObjectPath& object_path) override { + DCHECK(object_manager_); + return static_cast<Properties*>(object_manager_->GetProperties( + object_path, + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface)); + } + + // BluetoothGattCharacteristicClient override. + void ReadValue(const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const ErrorCallback& error_callback) override { + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownCharacteristicError, ""); + return; + } + + dbus::MethodCall method_call( + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface, + bluetooth_gatt_characteristic::kReadValue); + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothGattCharacteristicClientImpl::OnValueSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothGattCharacteristicClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothGattCharacteristicClient override. + void WriteValue(const dbus::ObjectPath& object_path, + const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownCharacteristicError, ""); + return; + } + + dbus::MethodCall method_call( + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface, + bluetooth_gatt_characteristic::kWriteValue); + dbus::MessageWriter writer(&method_call); + writer.AppendArrayOfBytes(value.data(), value.size()); + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothGattCharacteristicClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothGattCharacteristicClient override. + void StartNotify(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownCharacteristicError, ""); + return; + } + + dbus::MethodCall method_call( + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface, + bluetooth_gatt_characteristic::kStartNotify); + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothGattCharacteristicClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothGattCharacteristicClient override. + void StopNotify(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownCharacteristicError, ""); + return; + } + + dbus::MethodCall method_call( + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface, + bluetooth_gatt_characteristic::kStopNotify); + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothGattCharacteristicClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothGattCharacteristicClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // dbus::ObjectManager::Interface override. + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + Properties* properties = new Properties( + object_proxy, interface_name, + base::Bind(&BluetoothGattCharacteristicClientImpl::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), object_path)); + return static_cast<dbus::PropertySet*>(properties); + } + + // dbus::ObjectManager::Interface override. + void ObjectAdded(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(2) << "Remote GATT characteristic added: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_, + GattCharacteristicAdded(object_path)); + } + + // dbus::ObjectManager::Interface override. + void ObjectRemoved(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(2) << "Remote GATT characteristic removed: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_, + GattCharacteristicRemoved(object_path)); + } + + protected: + // chromeos::DBusClient override. + void Init(dbus::Bus* bus) override { + object_manager_ = bus->GetObjectManager( + bluetooth_object_manager::kBluetoothObjectManagerServiceName, + dbus::ObjectPath( + bluetooth_object_manager::kBluetoothObjectManagerServicePath)); + object_manager_->RegisterInterface( + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface, + this); + } + + private: + // Called by dbus::PropertySet when a property value is changed, either by + // result of a signal or response to a GetAll() or Get() call. Informs + // observers. + virtual void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) { + VLOG(2) << "Remote GATT characteristic property changed: " + << object_path.value() << ": " << property_name; + FOR_EACH_OBSERVER( + BluetoothGattCharacteristicClient::Observer, observers_, + GattCharacteristicPropertyChanged(object_path, property_name)); + } + + // Called when a response for successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a characteristic value response for a successful method call + // is received. + void OnValueSuccess(const ValueCallback& callback, dbus::Response* response) { + DCHECK(response); + dbus::MessageReader reader(response); + + const uint8* bytes = NULL; + size_t length = 0; + + if (!reader.PopArrayOfBytes(&bytes, &length)) + VLOG(2) << "Error reading array of bytes in ValueCallback"; + + std::vector<uint8> value; + + if (bytes) + value.assign(bytes, bytes + length); + + callback.Run(value); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + // Error response has optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + error_message = ""; + } + error_callback.Run(error_name, error_message); + } + + dbus::ObjectManager* object_manager_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothGattCharacteristicClient::Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothGattCharacteristicClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClientImpl); +}; + +BluetoothGattCharacteristicClient::BluetoothGattCharacteristicClient() {} + +BluetoothGattCharacteristicClient::~BluetoothGattCharacteristicClient() {} + +// static +BluetoothGattCharacteristicClient* BluetoothGattCharacteristicClient::Create() { + return new BluetoothGattCharacteristicClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h new file mode 100644 index 0000000..3c476eb --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h @@ -0,0 +1,144 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothGattCharacteristicClient is used to communicate with remote GATT +// characteristic objects exposed by the Bluetooth daemon. +class DEVICE_BLUETOOTH_EXPORT BluetoothGattCharacteristicClient + : public BluezDBusClient { + public: + // Structure of properties associated with GATT characteristics. + struct Properties : public dbus::PropertySet { + // The 128-bit characteristic UUID. [read-only] + dbus::Property<std::string> uuid; + + // Object path of the GATT service the characteristic belongs to. + // [read-only] + dbus::Property<dbus::ObjectPath> service; + + // The cached value of the characteristic. This property gets updated only + // after a successful read request and when a notification or indication is + // received. [read-only] + dbus::Property<std::vector<uint8_t>> value; + + // Whether or not this characteristic is currently sending ValueUpdated + // signals. [read-only] + dbus::Property<bool> notifying; + + // List of flags representing the GATT "Characteristic Properties bit field" + // and properties read from the GATT "Characteristic Extended Properties" + // descriptor bit field. [read-only, optional] + dbus::Property<std::vector<std::string>> flags; + + // Array of object paths representing the descriptors of this + // characteristic. [read-only] + dbus::Property<std::vector<dbus::ObjectPath>> descriptors; + + Properties(dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback); + ~Properties() override; + }; + + // Interface for observing changes from a remote GATT characteristic. + class Observer { + public: + virtual ~Observer() {} + + // Called when the GATT characteristic with object path |object_path| is + // added to the system. + virtual void GattCharacteristicAdded(const dbus::ObjectPath& object_path) {} + + // Called when the GATT characteristic with object path |object_path| is + // removed from the system. + virtual void GattCharacteristicRemoved( + const dbus::ObjectPath& object_path) {} + + // Called when the GATT characteristic with object path |object_path| has a + // change in the value of the property named |property_name|. + virtual void GattCharacteristicPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) {} + }; + + // Callbacks used to report the result of asynchronous methods. + typedef base::Callback<void(const std::string& error_name, + const std::string& error_message)> ErrorCallback; + typedef base::Callback<void(const std::vector<uint8>& value)> ValueCallback; + + ~BluetoothGattCharacteristicClient() override; + + // Adds and removes observers for events on all remote GATT characteristics. + // Check the |object_path| parameter of observer methods to determine which + // GATT characteristic is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Returns the list of GATT characteristic object paths known to the system. + virtual std::vector<dbus::ObjectPath> GetCharacteristics() = 0; + + // Obtain the properties for the GATT characteristic with object path + // |object_path|. Values should be copied if needed. + virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0; + + // Issues a request to read the value of GATT characteristic with object path + // |object_path| and returns the value in |callback| on success. On error, + // invokes |error_callback|. + virtual void ReadValue(const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const ErrorCallback& error_callback) = 0; + + // Issues a request to write the value of GATT characteristic with object path + // |object_path| with value |value|. Invokes |callback| on success and + // |error_callback| on failure. + virtual void WriteValue(const dbus::ObjectPath& object_path, + const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Starts a notification session from this characteristic with object path + // |object_path| if it supports value notifications or indications. Invokes + // |callback| on success and |error_callback| on failure. + virtual void StartNotify(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Cancels any previous StartNotify transaction for characteristic with + // object path |object_path|. Invokes |callback| on success and + // |error_callback| on failure. + virtual void StopNotify(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Creates the instance. + static BluetoothGattCharacteristicClient* Create(); + + // Constants used to indicate exceptional error conditions. + static const char kNoResponseError[]; + static const char kUnknownCharacteristicError[]; + + protected: + BluetoothGattCharacteristicClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc new file mode 100644 index 0000000..4decdf0 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.cc @@ -0,0 +1,464 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/weak_ptr.h" +#include "base/strings/string_util.h" +#include "base/threading/platform_thread.h" +#include "dbus/exported_object.h" +#include "dbus/message.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { +namespace { +const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs"; +const char kErrorPropertyReadOnly[] = + "org.freedesktop.DBus.Error.PropertyReadOnly"; +const char kErrorFailed[] = "org.freedesktop.DBus.Error.Failed"; +} // namespace + +// The BluetoothGattCharacteristicServiceProvider implementation used in +// production. +class BluetoothGattCharacteristicServiceProviderImpl + : public BluetoothGattCharacteristicServiceProvider { + public: + BluetoothGattCharacteristicServiceProviderImpl( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& flags, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& service_path) + : origin_thread_id_(base::PlatformThread::CurrentId()), + uuid_(uuid), + bus_(bus), + delegate_(delegate), + object_path_(object_path), + service_path_(service_path), + weak_ptr_factory_(this) { + VLOG(1) << "Created Bluetooth GATT characteristic: " << object_path.value() + << " UUID: " << uuid; + DCHECK(bus_); + DCHECK(delegate_); + DCHECK(!uuid_.empty()); + DCHECK(object_path_.IsValid()); + DCHECK(service_path_.IsValid()); + DCHECK(base::StartsWith(object_path_.value(), service_path_.value() + "/", + base::CompareCase::SENSITIVE)); + + exported_object_ = bus_->GetExportedObject(object_path_); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet, + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::Get, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesSet, + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::Set, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll, + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::GetAll, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + } + + ~BluetoothGattCharacteristicServiceProviderImpl() override { + VLOG(1) << "Cleaning up Bluetooth GATT characteristic: " + << object_path_.value(); + bus_->UnregisterExportedObject(object_path_); + } + + // BluetoothGattCharacteristicServiceProvider override. + void SendValueChanged(const std::vector<uint8>& value) override { + VLOG(2) << "Emitting a PropertiesChanged signal for characteristic value."; + dbus::Signal signal(dbus::kDBusPropertiesInterface, + dbus::kDBusPropertiesChangedSignal); + dbus::MessageWriter writer(&signal); + dbus::MessageWriter array_writer(NULL); + dbus::MessageWriter dict_entry_writer(NULL); + dbus::MessageWriter variant_writer(NULL); + + // interface_name + writer.AppendString( + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface); + + // changed_properties + writer.OpenArray("{sv}", &array_writer); + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_gatt_characteristic::kValueProperty); + dict_entry_writer.OpenVariant("ay", &variant_writer); + variant_writer.AppendArrayOfBytes(value.data(), value.size()); + dict_entry_writer.CloseContainer(&variant_writer); + array_writer.CloseContainer(&dict_entry_writer); + writer.CloseContainer(&array_writer); + + // invalidated_properties. + writer.OpenArray("s", &array_writer); + writer.CloseContainer(&array_writer); + + exported_object_->SendSignal(&signal); + } + + private: + // Returns true if the current thread is on the origin thread. + bool OnOriginThread() { + return base::PlatformThread::CurrentId() == origin_thread_id_; + } + + // Called by dbus:: when the Bluetooth daemon fetches a single property of + // the characteristic. + void Get(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothGattCharacteristicServiceProvider::Get: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + std::string property_name; + if (!reader.PopString(&interface_name) || + !reader.PopString(&property_name) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 'ss'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the GATT characteristic interface is supported. + if (interface_name != + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + // If getting the "Value" property, obtain the value from the delegate. + if (property_name == bluetooth_gatt_characteristic::kValueProperty) { + DCHECK(delegate_); + delegate_->GetCharacteristicValue( + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGet, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender), + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender)); + return; + } + + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter variant_writer(NULL); + + // TODO(armansito): Process the "Flags" and "Permissions" properties below. + if (property_name == bluetooth_gatt_characteristic::kUUIDProperty) { + writer.OpenVariant("s", &variant_writer); + variant_writer.AppendString(uuid_); + writer.CloseContainer(&variant_writer); + } else if (property_name == + bluetooth_gatt_characteristic::kServiceProperty) { + writer.OpenVariant("o", &variant_writer); + variant_writer.AppendObjectPath(service_path_); + writer.CloseContainer(&variant_writer); + } else { + response = dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such property: '" + property_name + "'."); + } + + response_sender.Run(response.Pass()); + } + + // Called by dbus:: when the Bluetooth daemon sets a single property of the + // characteristic. + void Set(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothGattCharacteristicServiceProvider::Set: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + std::string property_name; + dbus::MessageReader variant_reader(NULL); + if (!reader.PopString(&interface_name) || + !reader.PopString(&property_name) || + !reader.PopVariant(&variant_reader) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 'ssv'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the GATT characteristic interface is allowed. + if (interface_name != + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the "Value" property is writeable. + if (property_name != bluetooth_gatt_characteristic::kValueProperty) { + std::string error_name; + std::string error_message; + if (property_name == bluetooth_gatt_characteristic::kUUIDProperty || + property_name == bluetooth_gatt_characteristic::kServiceProperty) { + error_name = kErrorPropertyReadOnly; + error_message = "Read-only property: '" + property_name + "'."; + } else { + error_name = kErrorInvalidArgs; + error_message = "No such property: '" + property_name + "'."; + } + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, error_name, + error_message); + response_sender.Run(error_response.Pass()); + return; + } + + // Obtain the value. + const uint8* bytes = NULL; + size_t length = 0; + if (!variant_reader.PopArrayOfBytes(&bytes, &length)) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "Property '" + property_name + "' has type 'ay'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Pass the set request onto the delegate. + std::vector<uint8> value(bytes, bytes + length); + DCHECK(delegate_); + delegate_->SetCharacteristicValue( + value, + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnSet, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender), + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender)); + } + + // Called by dbus:: when the Bluetooth daemon fetches all properties of the + // characteristic. + void GetAll(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothGattCharacteristicServiceProvider::GetAll: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + if (!reader.PopString(&interface_name) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 's'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the GATT characteristic interface is supported. + if (interface_name != + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Try to obtain the value from the delegate. We will construct the + // response in the success callback. + DCHECK(delegate_); + delegate_->GetCharacteristicValue( + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGetAll, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender), + base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender)); + } + + // Called by dbus:: when a method is exported. + void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "." + << method_name; + } + + // Called by the Delegate in response to a method to call to get all + // properties, in which the delegate has successfully returned the + // characteristic value. + void OnGetAll(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + const std::vector<uint8>& value) { + VLOG(2) << "Characteristic value obtained from delegate. Responding to " + << "GetAll."; + + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter array_writer(NULL); + dbus::MessageWriter dict_entry_writer(NULL); + dbus::MessageWriter variant_writer(NULL); + + writer.OpenArray("{sv}", &array_writer); + + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_gatt_characteristic::kUUIDProperty); + dict_entry_writer.AppendVariantOfString(uuid_); + array_writer.CloseContainer(&dict_entry_writer); + + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_gatt_characteristic::kServiceProperty); + dict_entry_writer.AppendVariantOfObjectPath(service_path_); + array_writer.CloseContainer(&dict_entry_writer); + + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_gatt_characteristic::kValueProperty); + dict_entry_writer.OpenVariant("ay", &variant_writer); + variant_writer.AppendArrayOfBytes(value.data(), value.size()); + dict_entry_writer.CloseContainer(&variant_writer); + array_writer.CloseContainer(&dict_entry_writer); + + // TODO(armansito): Process Flags & Permissions properties. + + writer.CloseContainer(&array_writer); + + response_sender.Run(response.Pass()); + } + + // Called by the Delegate in response to a successful method call to get the + // characteristic value. + void OnGet(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + const std::vector<uint8>& value) { + VLOG(2) << "Returning characteristic value obtained from delegate."; + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter variant_writer(NULL); + + writer.OpenVariant("ay", &variant_writer); + variant_writer.AppendArrayOfBytes(value.data(), value.size()); + writer.CloseContainer(&variant_writer); + + response_sender.Run(response.Pass()); + } + + // Called by the Delegate in response to a successful method call to set the + // characteristic value. + void OnSet(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "Successfully set characteristic value. Return success."; + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by the Delegate in response to a failed method call to get or set + // the characteristic value. + void OnFailure(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "Failed to get/set characteristic value. Report error."; + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorFailed, + "Failed to get/set characteristic value."); + response_sender.Run(error_response.Pass()); + } + + // Origin thread (i.e. the UI thread in production). + base::PlatformThreadId origin_thread_id_; + + // 128-bit characteristic UUID of this object. + std::string uuid_; + + // D-Bus bus object is exported on, not owned by this object and must + // outlive it. + dbus::Bus* bus_; + + // Incoming methods to get and set the "Value" property are passed on to the + // delegate and callbacks passed to generate a reply. |delegate_| is generally + // the object that owns this one and must outlive it. + Delegate* delegate_; + + // D-Bus object path of object we are exporting, kept so we can unregister + // again in our destructor. + dbus::ObjectPath object_path_; + + // Object path of the GATT service that the exported characteristic belongs + // to. + dbus::ObjectPath service_path_; + + // D-Bus object we are exporting, owned by this object. + scoped_refptr<dbus::ExportedObject> exported_object_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothGattCharacteristicServiceProviderImpl> + weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicServiceProviderImpl); +}; + +BluetoothGattCharacteristicServiceProvider:: + BluetoothGattCharacteristicServiceProvider() {} + +BluetoothGattCharacteristicServiceProvider:: + ~BluetoothGattCharacteristicServiceProvider() {} + +// static +BluetoothGattCharacteristicServiceProvider* +BluetoothGattCharacteristicServiceProvider::Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& flags, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& service_path) { + if (!bluez::BluezDBusManager::Get()->IsUsingStub()) { + return new BluetoothGattCharacteristicServiceProviderImpl( + bus, object_path, delegate, uuid, flags, permissions, service_path); + } + return new FakeBluetoothGattCharacteristicServiceProvider( + object_path, delegate, uuid, flags, permissions, service_path); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h new file mode 100644 index 0000000..ad5d999 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h @@ -0,0 +1,113 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "dbus/bus.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" + +namespace bluez { + +// BluetoothGattCharacteristicServiceProvider is used to provide a D-Bus object +// that represents a local GATT characteristic that the Bluetooth daemon can +// communicate with. +// +// Instantiate with a chosen D-Bus object path, delegate, and other fields. +// The Bluetooth daemon communicates with a GATT characteristic using the +// standard DBus.Properties interface. While most properties of the GATT +// characteristic interface are read-only and don't change throughout the +// life-time of the object, the "Value" property is both writeable and its +// value can change. Both Get and Set operations performed on the "Value" +// property are delegated to the Delegate object, an instance of which is +// mandatory during initialization. In addition, a "SendValueChanged" method is +// provided, which emits a DBus.Properties.PropertyChanged signal for the +// "Value" property. +class DEVICE_BLUETOOTH_EXPORT BluetoothGattCharacteristicServiceProvider { + public: + // Interface for reacting to GATT characteristic value requests. + class Delegate { + public: + virtual ~Delegate() {} + + // ValueCallback is used for methods that require a characteristic value + // to be returned. + typedef base::Callback<void(const std::vector<uint8>&)> ValueCallback; + + // ErrorCallback is used by methods to report failure. + typedef base::Closure ErrorCallback; + + // This method will be called when a remote device requests to read the + // value of the exported GATT characteristic. Invoke |callback| with a value + // to return that value to the requester. Invoke |error_callback| to report + // a failure to read the value. This can happen, for example, if the + // characteristic has no read permission set. Either callback should be + // invoked after a reasonable amount of time, since the request will time + // out if left pending for too long. + virtual void GetCharacteristicValue( + const ValueCallback& callback, + const ErrorCallback& error_callback) = 0; + + // This method will be called, when a remote device requests to write the + // value of the exported GATT characteristic. Invoke |callback| to report + // that the value was successfully written. Invoke |error_callback| to + // report a failure to write the value. This can happen, for example, if the + // characteristic has no write permission set. Either callback should be + // invoked after a reasonable amount of time, since the request will time + // out if left pending for too long. + // + // The delegate should use this method to perform any side-effects that may + // occur based on the set value and potentially send a property changed + // signal to notify the Bluetooth daemon that the value has changed. + virtual void SetCharacteristicValue( + const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + }; + + virtual ~BluetoothGattCharacteristicServiceProvider(); + + // Send a PropertyChanged signal to notify the Bluetooth daemon that the value + // of the "Value" property has changed to |value|. + virtual void SendValueChanged(const std::vector<uint8>& value) = 0; + + // Creates the instance, where |bus| is the D-Bus bus connection to export + // the object onto, |uuid| is the 128-bit GATT characteristic UUID, + // |flags| is the list of GATT characteristic properties, |permissions| is the + // list of attribute permissions, |service_path| is the object path of the + // exported GATT service the characteristic belongs to, |object_path| is the + // object path that the characteristic should have, and |delegate| is the + // object that "Value" Get/Set requests will be passed to and responses + // generated from. + // + // Object paths of GATT characteristics must be hierarchical to the path of + // the GATT service they belong to. Hence, |object_path| must have + // |service_path| as its prefix. Ownership of |delegate| is not taken, thus + // the delegate should outlive this instance. A delegate should handle only + // a single exported characteristic and own it. + static BluetoothGattCharacteristicServiceProvider* Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& flags, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& service_path); + + protected: + BluetoothGattCharacteristicServiceProvider(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc new file mode 100644 index 0000000..f3ba343 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc @@ -0,0 +1,251 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h" + +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "dbus/bus.h" +#include "dbus/object_manager.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +namespace { + +// TODO(armansito): Move this constant to cros_system_api. +const char kValueProperty[] = "Value"; + +} // namespace + +// static +const char BluetoothGattDescriptorClient::kNoResponseError[] = + "org.chromium.Error.NoResponse"; +// static +const char BluetoothGattDescriptorClient::kUnknownDescriptorError[] = + "org.chromium.Error.UnknownDescriptor"; + +BluetoothGattDescriptorClient::Properties::Properties( + dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback) + : dbus::PropertySet(object_proxy, interface_name, callback) { + RegisterProperty(bluetooth_gatt_descriptor::kUUIDProperty, &uuid); + RegisterProperty(bluetooth_gatt_descriptor::kCharacteristicProperty, + &characteristic); + RegisterProperty(kValueProperty, &value); +} + +BluetoothGattDescriptorClient::Properties::~Properties() {} + +// The BluetoothGattDescriptorClient implementation used in production. +class BluetoothGattDescriptorClientImpl + : public BluetoothGattDescriptorClient, + public dbus::ObjectManager::Interface { + public: + BluetoothGattDescriptorClientImpl() + : object_manager_(NULL), weak_ptr_factory_(this) {} + + ~BluetoothGattDescriptorClientImpl() override { + object_manager_->UnregisterInterface( + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface); + } + + // BluetoothGattDescriptorClientImpl override. + void AddObserver(BluetoothGattDescriptorClient::Observer* observer) override { + DCHECK(observer); + observers_.AddObserver(observer); + } + + // BluetoothGattDescriptorClientImpl override. + void RemoveObserver( + BluetoothGattDescriptorClient::Observer* observer) override { + DCHECK(observer); + observers_.RemoveObserver(observer); + } + + // BluetoothGattDescriptorClientImpl override. + std::vector<dbus::ObjectPath> GetDescriptors() override { + DCHECK(object_manager_); + return object_manager_->GetObjectsWithInterface( + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface); + } + + // BluetoothGattDescriptorClientImpl override. + Properties* GetProperties(const dbus::ObjectPath& object_path) override { + DCHECK(object_manager_); + return static_cast<Properties*>(object_manager_->GetProperties( + object_path, + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface)); + } + + // BluetoothGattDescriptorClientImpl override. + void ReadValue(const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const ErrorCallback& error_callback) override { + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownDescriptorError, ""); + return; + } + + dbus::MethodCall method_call( + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface, + bluetooth_gatt_descriptor::kReadValue); + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothGattDescriptorClientImpl::OnValueSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothGattDescriptorClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothGattDescriptorClientImpl override. + void WriteValue(const dbus::ObjectPath& object_path, + const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(object_path); + if (!object_proxy) { + error_callback.Run(kUnknownDescriptorError, ""); + return; + } + + dbus::MethodCall method_call( + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface, + bluetooth_gatt_descriptor::kWriteValue); + dbus::MessageWriter writer(&method_call); + writer.AppendArrayOfBytes(value.data(), value.size()); + + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothGattDescriptorClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothGattDescriptorClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // dbus::ObjectManager::Interface override. + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + Properties* properties = new Properties( + object_proxy, interface_name, + base::Bind(&BluetoothGattDescriptorClientImpl::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), object_path)); + return static_cast<dbus::PropertySet*>(properties); + } + + // dbus::ObjectManager::Interface override. + void ObjectAdded(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(2) << "Remote GATT descriptor added: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, + GattDescriptorAdded(object_path)); + } + + // dbus::ObjectManager::Interface override. + void ObjectRemoved(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(2) << "Remote GATT descriptor removed: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, + GattDescriptorRemoved(object_path)); + } + + protected: + // chromeos::DBusClient override. + void Init(dbus::Bus* bus) override { + object_manager_ = bus->GetObjectManager( + bluetooth_object_manager::kBluetoothObjectManagerServiceName, + dbus::ObjectPath( + bluetooth_object_manager::kBluetoothObjectManagerServicePath)); + object_manager_->RegisterInterface( + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface, this); + } + + private: + // Called by dbus::PropertySet when a property value is changed, either by + // result of a signal or response to a GetAll() or Get() call. Informs + // observers. + virtual void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) { + VLOG(2) << "Remote GATT descriptor property changed: " + << object_path.value() << ": " << property_name; + FOR_EACH_OBSERVER( + BluetoothGattDescriptorClient::Observer, observers_, + GattDescriptorPropertyChanged(object_path, property_name)); + } + + // Called when a response for a successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a descriptor value response for a successful method call is + // received. + void OnValueSuccess(const ValueCallback& callback, dbus::Response* response) { + DCHECK(response); + dbus::MessageReader reader(response); + + const uint8* bytes = NULL; + size_t length = 0; + + if (!reader.PopArrayOfBytes(&bytes, &length)) + VLOG(2) << "Error reading array of bytes in ValueCallback"; + + std::vector<uint8> value; + + if (bytes) + value.assign(bytes, bytes + length); + + callback.Run(value); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + // Error response has optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + error_message = ""; + } + error_callback.Run(error_name, error_message); + } + + dbus::ObjectManager* object_manager_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothGattDescriptorClient::Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothGattDescriptorClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorClientImpl); +}; + +BluetoothGattDescriptorClient::BluetoothGattDescriptorClient() {} + +BluetoothGattDescriptorClient::~BluetoothGattDescriptorClient() {} + +// static +BluetoothGattDescriptorClient* BluetoothGattDescriptorClient::Create() { + return new BluetoothGattDescriptorClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h new file mode 100644 index 0000000..364331e --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h @@ -0,0 +1,116 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothGattDescriptorClient is used to communicate with remote GATT +// characteristic descriptor objects exposed by the Bluetooth daemon. +class DEVICE_BLUETOOTH_EXPORT BluetoothGattDescriptorClient + : public BluezDBusClient { + public: + // Structure of properties associated with GATT descriptors. + struct Properties : public dbus::PropertySet { + // The 128-bit characteristic descriptor UUID. [read-only] + dbus::Property<std::string> uuid; + + // Object path of the GATT characteristic the descriptor belongs to. + // [read-only] + dbus::Property<dbus::ObjectPath> characteristic; + + // The cached value of the descriptor. This property gets updated only after + // a successful read request. [read-only] + dbus::Property<std::vector<uint8_t>> value; + + Properties(dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback); + ~Properties() override; + }; + + // Interface for observing changes from a remote GATT characteristic + // descriptor. + class Observer { + public: + virtual ~Observer() {} + + // Called when the GATT descriptor with object path |object_path| is added + // to the system. + virtual void GattDescriptorAdded(const dbus::ObjectPath& object_path) {} + + // Called when the GATT descriptor with object path |object_path| is removed + // from the system. + virtual void GattDescriptorRemoved(const dbus::ObjectPath& object_path) {} + + // Called when the GATT descriptor with object path |object_path| has a + // change in the value of the property named |property_name|. + virtual void GattDescriptorPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) {} + }; + + // Callbacks used to report the result of asynchronous methods. + typedef base::Callback<void(const std::string& error_name, + const std::string& error_message)> ErrorCallback; + typedef base::Callback<void(const std::vector<uint8>& value)> ValueCallback; + + ~BluetoothGattDescriptorClient() override; + + // Adds and removes observers for events on all remote GATT descriptors. Check + // the |object_path| parameter of observer methods to determine which GATT + // descriptor is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Returns the list of GATT descriptor object paths known to the system. + virtual std::vector<dbus::ObjectPath> GetDescriptors() = 0; + + // Obtain the properties for the GATT descriptor with object path + // |object_path|. Values should be copied if needed. + virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0; + + // Issues a request to read the value of GATT descriptor with object path + // |object_path| and returns the value in |callback| on success. On error, + // invokes |error_callback|. + virtual void ReadValue(const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const ErrorCallback& error_callback) = 0; + + // Issues a request to write the value of GATT descriptor with object path + // |object_path| with value |value|. Invokes |callback| on success and + // |error_callback| on failure. + virtual void WriteValue(const dbus::ObjectPath& object_path, + const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Creates the instance. + static BluetoothGattDescriptorClient* Create(); + + // Constants used to indicate exceptional error conditions. + static const char kNoResponseError[]; + static const char kUnknownDescriptorError[]; + + protected: + BluetoothGattDescriptorClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc new file mode 100644 index 0000000..e4aa245 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.cc @@ -0,0 +1,457 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/weak_ptr.h" +#include "base/strings/string_util.h" +#include "base/threading/platform_thread.h" +#include "dbus/exported_object.h" +#include "dbus/message.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { +namespace { +const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs"; +const char kErrorPropertyReadOnly[] = + "org.freedesktop.DBus.Error.PropertyReadOnly"; +const char kErrorFailed[] = "org.freedesktop.DBus.Error.Failed"; +} // namespace + +// The BluetoothGattDescriptorServiceProvider implementation used in production. +class BluetoothGattDescriptorServiceProviderImpl + : public BluetoothGattDescriptorServiceProvider { + public: + BluetoothGattDescriptorServiceProviderImpl( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& characteristic_path) + : origin_thread_id_(base::PlatformThread::CurrentId()), + uuid_(uuid), + bus_(bus), + delegate_(delegate), + object_path_(object_path), + characteristic_path_(characteristic_path), + weak_ptr_factory_(this) { + VLOG(1) << "Created Bluetooth GATT characteristic descriptor: " + << object_path.value() << " UUID: " << uuid; + DCHECK(bus_); + DCHECK(delegate_); + DCHECK(!uuid_.empty()); + DCHECK(object_path_.IsValid()); + DCHECK(characteristic_path_.IsValid()); + DCHECK(base::StartsWith(object_path_.value(), + characteristic_path_.value() + "/", + base::CompareCase::SENSITIVE)); + + exported_object_ = bus_->GetExportedObject(object_path_); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet, + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::Get, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesSet, + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::Set, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll, + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::GetAll, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + } + + ~BluetoothGattDescriptorServiceProviderImpl() override { + VLOG(1) << "Cleaning up Bluetooth GATT characteristic descriptor: " + << object_path_.value(); + bus_->UnregisterExportedObject(object_path_); + } + + // BluetoothGattDescriptorServiceProvider override. + void SendValueChanged(const std::vector<uint8>& value) override { + VLOG(2) << "Emitting a PropertiesChanged signal for descriptor value."; + dbus::Signal signal(dbus::kDBusPropertiesInterface, + dbus::kDBusPropertiesChangedSignal); + dbus::MessageWriter writer(&signal); + dbus::MessageWriter array_writer(NULL); + dbus::MessageWriter dict_entry_writer(NULL); + dbus::MessageWriter variant_writer(NULL); + + // interface_name + writer.AppendString( + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface); + + // changed_properties + writer.OpenArray("{sv}", &array_writer); + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kValueProperty); + dict_entry_writer.OpenVariant("ay", &variant_writer); + variant_writer.AppendArrayOfBytes(value.data(), value.size()); + dict_entry_writer.CloseContainer(&variant_writer); + array_writer.CloseContainer(&dict_entry_writer); + writer.CloseContainer(&array_writer); + + // invalidated_properties. + writer.OpenArray("s", &array_writer); + writer.CloseContainer(&array_writer); + + exported_object_->SendSignal(&signal); + } + + private: + // Returns true if the current thread is on the origin thread. + bool OnOriginThread() { + return base::PlatformThread::CurrentId() == origin_thread_id_; + } + + // Called by dbus:: when the Bluetooth daemon fetches a single property of + // the descriptor. + void Get(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothGattDescriptorServiceProvider::Get: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + std::string property_name; + if (!reader.PopString(&interface_name) || + !reader.PopString(&property_name) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 'ss'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the GATT descriptor interface is supported. + if (interface_name != + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + // If getting the "Value" property, obtain the value from the delegate. + if (property_name == bluetooth_gatt_descriptor::kValueProperty) { + DCHECK(delegate_); + delegate_->GetDescriptorValue( + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnGet, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender), + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnFailure, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender)); + return; + } + + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter variant_writer(NULL); + + // TODO(armansito): Process the "Permissions" property below. + if (property_name == bluetooth_gatt_descriptor::kUUIDProperty) { + writer.OpenVariant("s", &variant_writer); + variant_writer.AppendString(uuid_); + writer.CloseContainer(&variant_writer); + } else if (property_name == + bluetooth_gatt_descriptor::kCharacteristicProperty) { + writer.OpenVariant("o", &variant_writer); + variant_writer.AppendObjectPath(characteristic_path_); + writer.CloseContainer(&variant_writer); + } else { + response = dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such property: '" + property_name + "'."); + } + + response_sender.Run(response.Pass()); + } + + // Called by dbus:: when the Bluetooth daemon sets a single property of the + // descriptor. + void Set(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothGattDescriptorServiceProvider::Set: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + std::string property_name; + dbus::MessageReader variant_reader(NULL); + if (!reader.PopString(&interface_name) || + !reader.PopString(&property_name) || + !reader.PopVariant(&variant_reader) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 'ssv'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the GATT descriptor interface is allowed. + if (interface_name != + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the "Value" property is writeable. + if (property_name != bluetooth_gatt_descriptor::kValueProperty) { + std::string error_name; + std::string error_message; + if (property_name == bluetooth_gatt_descriptor::kUUIDProperty || + property_name == bluetooth_gatt_descriptor::kCharacteristicProperty) { + error_name = kErrorPropertyReadOnly; + error_message = "Read-only property: '" + property_name + "'."; + } else { + error_name = kErrorInvalidArgs; + error_message = "No such property: '" + property_name + "'."; + } + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, error_name, + error_message); + response_sender.Run(error_response.Pass()); + return; + } + + // Obtain the value. + const uint8* bytes = NULL; + size_t length = 0; + if (!variant_reader.PopArrayOfBytes(&bytes, &length)) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "Property '" + property_name + "' has type 'ay'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Pass the set request onto the delegate. + std::vector<uint8> value(bytes, bytes + length); + DCHECK(delegate_); + delegate_->SetDescriptorValue( + value, base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnSet, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender), + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnFailure, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender)); + } + + // Called by dbus:: when the Bluetooth daemon fetches all properties of the + // descriptor. + void GetAll(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothGattDescriptorServiceProvider::GetAll: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + if (!reader.PopString(&interface_name) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 's'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the GATT descriptor interface is supported. + if (interface_name != + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Try to obtain the value from the delegate. We will construct the + // response in the success callback. + DCHECK(delegate_); + delegate_->GetDescriptorValue( + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnGetAll, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender), + base::Bind(&BluetoothGattDescriptorServiceProviderImpl::OnFailure, + weak_ptr_factory_.GetWeakPtr(), method_call, + response_sender)); + } + + // Called by dbus:: when a method is exported. + void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "." + << method_name; + } + + // Called by the Delegate in response to a method to call to get all + // properties, in which the delegate has successfully returned the + // descriptor value. + void OnGetAll(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + const std::vector<uint8>& value) { + VLOG(2) << "Descriptor value obtained from delegate. Responding to " + << "GetAll."; + + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter array_writer(NULL); + dbus::MessageWriter dict_entry_writer(NULL); + dbus::MessageWriter variant_writer(NULL); + + writer.OpenArray("{sv}", &array_writer); + + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kUUIDProperty); + dict_entry_writer.AppendVariantOfString(uuid_); + array_writer.CloseContainer(&dict_entry_writer); + + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_gatt_descriptor::kCharacteristicProperty); + dict_entry_writer.AppendVariantOfObjectPath(characteristic_path_); + array_writer.CloseContainer(&dict_entry_writer); + + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString(bluetooth_gatt_descriptor::kValueProperty); + dict_entry_writer.OpenVariant("ay", &variant_writer); + variant_writer.AppendArrayOfBytes(value.data(), value.size()); + dict_entry_writer.CloseContainer(&variant_writer); + array_writer.CloseContainer(&dict_entry_writer); + + // TODO(armansito): Process "Permissions" property. + + writer.CloseContainer(&array_writer); + + response_sender.Run(response.Pass()); + } + + // Called by the Delegate in response to a successful method call to get the + // descriptor value. + void OnGet(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + const std::vector<uint8>& value) { + VLOG(2) << "Returning descriptor value obtained from delegate."; + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter variant_writer(NULL); + + writer.OpenVariant("ay", &variant_writer); + variant_writer.AppendArrayOfBytes(value.data(), value.size()); + writer.CloseContainer(&variant_writer); + + response_sender.Run(response.Pass()); + } + + // Called by the Delegate in response to a successful method call to set the + // descriptor value. + void OnSet(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "Successfully set descriptor value. Return success."; + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by the Delegate in response to a failed method call to get or set + // the descriptor value. + void OnFailure(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "Failed to get/set descriptor value. Report error."; + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorFailed, "Failed to get/set descriptor value."); + response_sender.Run(error_response.Pass()); + } + + // Origin thread (i.e. the UI thread in production). + base::PlatformThreadId origin_thread_id_; + + // 128-bit descriptor UUID of this object. + std::string uuid_; + + // D-Bus bus object is exported on, not owned by this object and must + // outlive it. + dbus::Bus* bus_; + + // Incoming methods to get and set the "Value" property are passed on to the + // delegate and callbacks passed to generate a reply. |delegate_| is generally + // the object that owns this one and must outlive it. + Delegate* delegate_; + + // D-Bus object path of object we are exporting, kept so we can unregister + // again in our destructor. + dbus::ObjectPath object_path_; + + // Object path of the GATT characteristic that the exported descriptor belongs + // to. + dbus::ObjectPath characteristic_path_; + + // D-Bus object we are exporting, owned by this object. + scoped_refptr<dbus::ExportedObject> exported_object_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothGattDescriptorServiceProviderImpl> + weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorServiceProviderImpl); +}; + +BluetoothGattDescriptorServiceProvider:: + BluetoothGattDescriptorServiceProvider() {} + +BluetoothGattDescriptorServiceProvider:: + ~BluetoothGattDescriptorServiceProvider() {} + +// static +BluetoothGattDescriptorServiceProvider* +BluetoothGattDescriptorServiceProvider::Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& characteristic_path) { + if (!bluez::BluezDBusManager::Get()->IsUsingStub()) { + return new BluetoothGattDescriptorServiceProviderImpl( + bus, object_path, delegate, uuid, permissions, characteristic_path); + } + return new FakeBluetoothGattDescriptorServiceProvider( + object_path, delegate, uuid, permissions, characteristic_path); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h new file mode 100644 index 0000000..e4925ff --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h @@ -0,0 +1,109 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "dbus/bus.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" + +namespace bluez { + +// BluetoothGattDescriptorServiceProvider is used to provide a D-Bus object that +// represents a local GATT characteristic descriptor that the Bluetooth daemon +// can communicate with. +// +// Instantiate with a chosen D-Bus object path, delegate, and other fields. +// The Bluetooth daemon communicates with a GATT descriptor using the +// standard DBus.Properties interface. While most properties of the GATT +// descriptor interface are read-only and don't change throughout the +// life-time of the object, the "Value" property is both writeable and its +// value can change. Both Get and Set operations performed on the "Value" +// property are delegated to the Delegate object, an instance of which is +// mandatory during initialization. In addition, a "SendValueChanged" method is +// provided, which emits a DBus.Properties.PropertyChanged signal for the +// "Value" property. +class DEVICE_BLUETOOTH_EXPORT BluetoothGattDescriptorServiceProvider { + public: + // Interface for reacting to GATT characteristic descriptor value requests. + class Delegate { + public: + virtual ~Delegate() {} + + // ValueCallback is used for methods that require a descriptor value + // to be returned. + typedef base::Callback<void(const std::vector<uint8>&)> ValueCallback; + + // ErrorCallback is used by methods to report failure. + typedef base::Closure ErrorCallback; + + // This method will be called when a remote device requests to read the + // value of the exported GATT descriptor. Invoke |callback| with a value + // to return that value to the requester. Invoke |error_callback| to report + // a failure to read the value. This can happen, for example, if the + // descriptor has no read permission set. Either callback should be + // invoked after a reasonable amount of time, since the request will time + // out if left pending for too long. + virtual void GetDescriptorValue(const ValueCallback& callback, + const ErrorCallback& error_callback) = 0; + + // This method will be called, when a remote device requests to write the + // value of the exported GATT descriptor. Invoke |callback| to report + // that the value was successfully written. Invoke |error_callback| to + // report a failure to write the value. This can happen, for example, if the + // descriptor has no write permission set. Either callback should be + // invoked after a reasonable amount of time, since the request will time + // out if left pending for too long. + // + // The delegate should use this method to perform any side-effects that may + // occur based on the set value and potentially send a property changed + // signal to notify the Bluetooth daemon that the value has changed. + virtual void SetDescriptorValue(const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + }; + + virtual ~BluetoothGattDescriptorServiceProvider(); + + // Send a PropertyChanged signal to notify the Bluetooth daemon that the value + // of the "Value" property has changed to |value|. + virtual void SendValueChanged(const std::vector<uint8>& value) = 0; + + // Creates the instance, where |bus| is the D-Bus bus connection to export + // the object onto, |uuid| is the 128-bit GATT descriptor UUID, |permissions| + // is the list of attribute permissions, |characteristic_path| is the object + // path of the exported GATT characteristic the descriptor belongs to, + // |object_path| is the object path that the descriptor should have, and + // |delegate| is the object that value Get/Set requests will be passed to and + // responses generated from. + // + // Object paths of GATT descriptors must be hierarchical to the path of the + // GATT characteristic they belong to. Hence, |object_path| must have + // |characteristic_path| as its prefix. Ownership of |delegate| is not taken, + // thus the delegate should outlive this instance. A delegate should handle + // only a single exported descriptor and own it. + static BluetoothGattDescriptorServiceProvider* Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& characteristic_path); + + protected: + BluetoothGattDescriptorServiceProvider(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc new file mode 100644 index 0000000..7e471a5 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc @@ -0,0 +1,129 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_gatt_manager_client.h" + +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +const char BluetoothGattManagerClient::kNoResponseError[] = + "org.chromium.Error.NoResponse"; + +// The BluetoothGattManagerClient implementation used in production. +class BluetoothGattManagerClientImpl : public BluetoothGattManagerClient { + public: + BluetoothGattManagerClientImpl() + : object_proxy_(NULL), weak_ptr_factory_(this) {} + + ~BluetoothGattManagerClientImpl() override {} + + // BluetoothGattManagerClient override. + void RegisterService(const dbus::ObjectPath& service_path, + const Options& options, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_gatt_manager::kBluetoothGattManagerInterface, + bluetooth_gatt_manager::kRegisterService); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(service_path); + + // TODO(armansito): The parameters of the Options dictionary are undefined + // but the method signature still requires a value dictionary. Pass an + // empty dictionary and fill in the contents later once this is defined. + dbus::MessageWriter array_writer(NULL); + writer.OpenArray("{sv}", &array_writer); + writer.CloseContainer(&array_writer); + + DCHECK(object_proxy_); + object_proxy_->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothGattManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothGattManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothGattManagerClient override. + void UnregisterService(const dbus::ObjectPath& service_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_gatt_manager::kBluetoothGattManagerInterface, + bluetooth_gatt_manager::kUnregisterService); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(service_path); + + DCHECK(object_proxy_); + object_proxy_->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothGattManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothGattManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + protected: + // chromeos::DBusClient override. + void Init(dbus::Bus* bus) override { + DCHECK(bus); + object_proxy_ = bus->GetObjectProxy( + bluetooth_gatt_manager::kBluetoothGattManagerServiceName, + dbus::ObjectPath( + bluetooth_gatt_manager::kBluetoothGattManagerInterface)); + } + + private: + // Called when a response for a successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + // Error response has optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + } + error_callback.Run(error_name, error_message); + } + + // The proxy to the remote GATT manager object. + dbus::ObjectProxy* object_proxy_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothGattManagerClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothGattManagerClientImpl); +}; + +BluetoothGattManagerClient::BluetoothGattManagerClient() {} + +BluetoothGattManagerClient::~BluetoothGattManagerClient() {} + +// static +BluetoothGattManagerClient* BluetoothGattManagerClient::Create() { + return new BluetoothGattManagerClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_gatt_manager_client.h b/device/bluetooth/dbus/bluetooth_gatt_manager_client.h new file mode 100644 index 0000000..b735f77 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.h @@ -0,0 +1,74 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_MANAGER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_MANAGER_CLIENT_H_ + +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothGattManagerClient is used to communicate with the GATT Service +// manager object of the Bluetooth daemon. +class DEVICE_BLUETOOTH_EXPORT BluetoothGattManagerClient + : public BluezDBusClient { + public: + // Options used to register a GATT service hierarchy. + struct DEVICE_BLUETOOTH_EXPORT Options { + // TODO(armansito): This parameter is not yet clearly defined. Add fields + // later as we know more about how this will be used. + }; + + ~BluetoothGattManagerClient() override; + + // The ErrorCallback is used by GATT manager methods to indicate failure. It + // receives two arguments: the name of the error in |error_name| and an + // optional message in |error_message|. + typedef base::Callback<void(const std::string& error_name, + const std::string& error_message)> ErrorCallback; + + // Registers a GATT service implementation within the local process at the + // D-Bus object path |service_path| with the remote GATT manager. The local + // service must implement the GattService1 interface. Characteristic objects + // must be hierarchical to their service and must use the interface + // GattCharacteristic1. Similarly, characteristic descriptor objects must + // implement the GattDescriptor1 interface and must be hierarchical to their + // characteristic. In a successful invocation of RegisterService, the + // Bluetooth daemon will discover all objects in the registered hierarchy by + // using D-Bus Object Manager. Hence, the object paths and the interfaces in + // the registered hierarchy must comply with the BlueZ GATT D-Bus + // specification. + virtual void RegisterService(const dbus::ObjectPath& service_path, + const Options& options, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Unregisters the GATT service with the D-Bus object path |service_path| from + // the remote GATT manager. + virtual void UnregisterService(const dbus::ObjectPath& service_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Creates the instance. + static BluetoothGattManagerClient* Create(); + + // Constants used to indicate exceptional error conditions. + static const char kNoResponseError[]; + + protected: + BluetoothGattManagerClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothGattManagerClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_MANAGER_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_client.cc b/device/bluetooth/dbus/bluetooth_gatt_service_client.cc new file mode 100644 index 0000000..dc3ef5a --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_service_client.cc @@ -0,0 +1,143 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_gatt_service_client.h" + +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "dbus/bus.h" +#include "dbus/object_manager.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +BluetoothGattServiceClient::Properties::Properties( + dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback) + : dbus::PropertySet(object_proxy, interface_name, callback) { + RegisterProperty(bluetooth_gatt_service::kUUIDProperty, &uuid); + RegisterProperty(bluetooth_gatt_service::kIncludesProperty, &includes); + RegisterProperty(bluetooth_gatt_service::kDeviceProperty, &device); + RegisterProperty(bluetooth_gatt_service::kPrimaryProperty, &primary); + RegisterProperty(bluetooth_gatt_service::kCharacteristicsProperty, + &characteristics); +} + +BluetoothGattServiceClient::Properties::~Properties() {} + +// The BluetoothGattServiceClient implementation used in production. +class BluetoothGattServiceClientImpl : public BluetoothGattServiceClient, + public dbus::ObjectManager::Interface { + public: + BluetoothGattServiceClientImpl() + : object_manager_(NULL), weak_ptr_factory_(this) {} + + ~BluetoothGattServiceClientImpl() override { + object_manager_->UnregisterInterface( + bluetooth_gatt_service::kBluetoothGattServiceInterface); + } + + // BluetoothGattServiceClientImpl override. + void AddObserver(BluetoothGattServiceClient::Observer* observer) override { + DCHECK(observer); + observers_.AddObserver(observer); + } + + // BluetoothGattServiceClientImpl override. + void RemoveObserver(BluetoothGattServiceClient::Observer* observer) override { + DCHECK(observer); + observers_.RemoveObserver(observer); + } + + // BluetoothGattServiceClientImpl override. + std::vector<dbus::ObjectPath> GetServices() override { + DCHECK(object_manager_); + return object_manager_->GetObjectsWithInterface( + bluetooth_gatt_service::kBluetoothGattServiceInterface); + } + + // BluetoothGattServiceClientImpl override. + Properties* GetProperties(const dbus::ObjectPath& object_path) override { + DCHECK(object_manager_); + return static_cast<Properties*>(object_manager_->GetProperties( + object_path, bluetooth_gatt_service::kBluetoothGattServiceInterface)); + } + + // dbus::ObjectManager::Interface override. + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + Properties* properties = new Properties( + object_proxy, interface_name, + base::Bind(&BluetoothGattServiceClientImpl::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), object_path)); + return static_cast<dbus::PropertySet*>(properties); + } + + // dbus::ObjectManager::Interface override. + void ObjectAdded(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(2) << "Remote GATT service added: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_, + GattServiceAdded(object_path)); + } + + // dbus::ObjectManager::Interface override. + void ObjectRemoved(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(2) << "Remote GATT service removed: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_, + GattServiceRemoved(object_path)); + } + + protected: + // chromeos::DBusClient override. + void Init(dbus::Bus* bus) override { + object_manager_ = bus->GetObjectManager( + bluetooth_object_manager::kBluetoothObjectManagerServiceName, + dbus::ObjectPath( + bluetooth_object_manager::kBluetoothObjectManagerServicePath)); + object_manager_->RegisterInterface( + bluetooth_gatt_service::kBluetoothGattServiceInterface, this); + } + + private: + // Called by dbus::PropertySet when a property value is changed, either by + // result of a signal or response to a GetAll() or Get() call. Informs + // observers. + virtual void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) { + VLOG(2) << "Remote GATT service property changed: " << object_path.value() + << ": " << property_name; + FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_, + GattServicePropertyChanged(object_path, property_name)); + } + + dbus::ObjectManager* object_manager_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothGattServiceClient::Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothGattServiceClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceClientImpl); +}; + +BluetoothGattServiceClient::BluetoothGattServiceClient() {} + +BluetoothGattServiceClient::~BluetoothGattServiceClient() {} + +// static +BluetoothGattServiceClient* BluetoothGattServiceClient::Create() { + return new BluetoothGattServiceClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_client.h b/device/bluetooth/dbus/bluetooth_gatt_service_client.h new file mode 100644 index 0000000..641f505 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_service_client.h @@ -0,0 +1,95 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/macros.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothGattServiceClient is used to communicate with remote GATT service +// objects exposed by the Bluetooth daemon. +class DEVICE_BLUETOOTH_EXPORT BluetoothGattServiceClient + : public BluezDBusClient { + public: + // Structure of properties associated with GATT services. + struct Properties : public dbus::PropertySet { + // The 128-bit service UUID. [read-only] + dbus::Property<std::string> uuid; + + // Object path of the Bluetooth device that the GATT service belongs to. + dbus::Property<dbus::ObjectPath> device; + + // Whether or not this service is a primary service. + dbus::Property<bool> primary; + + // Array of object paths representing the characteristics of this service. + // [read-only] + dbus::Property<std::vector<dbus::ObjectPath>> characteristics; + + // Array of object paths representing the included services of this service. + // [read-only] + dbus::Property<std::vector<dbus::ObjectPath>> includes; + + Properties(dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback); + ~Properties() override; + }; + + // Interface for observing changes from a remote GATT service. + class Observer { + public: + virtual ~Observer() {} + + // Called when the GATT service with object path |object_path| is added to + // the system. + virtual void GattServiceAdded(const dbus::ObjectPath& object_path) {} + + // Called when the GATT service with object path |object_path| is removed + // from the system. + virtual void GattServiceRemoved(const dbus::ObjectPath& object_path) {} + + // Called when the GATT service with object path |object_path| has a change + // in the value of the property named |property_name|. + virtual void GattServicePropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) {} + }; + + ~BluetoothGattServiceClient() override; + + // Adds and removes observers for events on all remote GATT services. Check + // the |object_path| parameter of observer methods to determine which GATT + // service is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Returns the list of GATT service object paths known to the system. + virtual std::vector<dbus::ObjectPath> GetServices() = 0; + + // Obtain the properties for the GATT service with object path |object_path|. + // Values should be copied if needed. + virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0; + + // Creates the instance. + static BluetoothGattServiceClient* Create(); + + protected: + BluetoothGattServiceClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc new file mode 100644 index 0000000..06b6827 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.cc @@ -0,0 +1,272 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/platform_thread.h" +#include "dbus/exported_object.h" +#include "dbus/message.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { +namespace { +const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs"; +const char kErrorPropertyReadOnly[] = + "org.freedesktop.DBus.Error.PropertyReadOnly"; +} // namespace + +// The BluetoothGattServiceServiceProvider implementation used in production. +class BluetoothGattServiceServiceProviderImpl + : public BluetoothGattServiceServiceProvider { + public: + BluetoothGattServiceServiceProviderImpl( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + const std::string& uuid, + const std::vector<dbus::ObjectPath>& includes) + : origin_thread_id_(base::PlatformThread::CurrentId()), + uuid_(uuid), + includes_(includes), + bus_(bus), + object_path_(object_path), + weak_ptr_factory_(this) { + VLOG(1) << "Creating Bluetooth GATT service: " << object_path_.value() + << " UUID: " << uuid; + DCHECK(!uuid_.empty()); + DCHECK(object_path_.IsValid()); + DCHECK(bus_); + + exported_object_ = bus_->GetExportedObject(object_path_); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet, + base::Bind(&BluetoothGattServiceServiceProviderImpl::Get, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothGattServiceServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesSet, + base::Bind(&BluetoothGattServiceServiceProviderImpl::Set, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothGattServiceServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll, + base::Bind(&BluetoothGattServiceServiceProviderImpl::GetAll, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothGattServiceServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + } + + ~BluetoothGattServiceServiceProviderImpl() override { + VLOG(1) << "Cleaning up Bluetooth GATT service: " << object_path_.value(); + bus_->UnregisterExportedObject(object_path_); + } + + private: + // Returns true if the current thread is on the origin thread. + bool OnOriginThread() { + return base::PlatformThread::CurrentId() == origin_thread_id_; + } + + // Called by dbus:: when the Bluetooth daemon fetches a single property of + // the service. + void Get(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothGattServiceServiceProvider::Get: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + std::string property_name; + if (!reader.PopString(&interface_name) || + !reader.PopString(&property_name) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 'ss'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the GATT service interface is allowed. + if (interface_name != + bluetooth_gatt_service::kBluetoothGattServiceInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Return error if |property_name| is unknown. + if (property_name != bluetooth_gatt_service::kUUIDProperty && + property_name != bluetooth_gatt_service::kIncludesProperty) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such property: '" + property_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter variant_writer(NULL); + + if (property_name == bluetooth_gatt_service::kUUIDProperty) { + writer.OpenVariant("s", &variant_writer); + variant_writer.AppendString(uuid_); + writer.CloseContainer(&variant_writer); + } else { + writer.OpenVariant("ao", &variant_writer); + variant_writer.AppendArrayOfObjectPaths(includes_); + writer.CloseContainer(&variant_writer); + } + + response_sender.Run(response.Pass()); + } + + // Called by dbus:: when the Bluetooth daemon sets a single property of the + // service. + void Set(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothGattServiceServiceProvider::Set: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + // All of the properties on this interface are read-only, so just return + // error. + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorPropertyReadOnly, + "All properties are read-only."); + response_sender.Run(error_response.Pass()); + } + + // Called by dbus:: when the Bluetooth daemon fetches all properties of the + // service. + void GetAll(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothGattServiceServiceProvider::GetAll: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + if (!reader.PopString(&interface_name) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 's'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the GATT service interface is allowed. + if (interface_name != + bluetooth_gatt_service::kBluetoothGattServiceInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter array_writer(NULL); + dbus::MessageWriter dict_entry_writer(NULL); + dbus::MessageWriter variant_writer(NULL); + + writer.OpenArray("{sv}", &array_writer); + + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString(bluetooth_gatt_service::kUUIDProperty); + dict_entry_writer.AppendVariantOfString(uuid_); + array_writer.CloseContainer(&dict_entry_writer); + + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString(bluetooth_gatt_service::kIncludesProperty); + dict_entry_writer.OpenVariant("ao", &variant_writer); + variant_writer.AppendArrayOfObjectPaths(includes_); + dict_entry_writer.CloseContainer(&variant_writer); + array_writer.CloseContainer(&dict_entry_writer); + + writer.CloseContainer(&array_writer); + + response_sender.Run(response.Pass()); + } + + // Called by dbus:: when a method is exported. + void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "." + << method_name; + } + + // Origin thread (i.e. the UI thread in production). + base::PlatformThreadId origin_thread_id_; + + // 128-bit service UUID of this object. + std::string uuid_; + + // List of object paths that represent other exported GATT services that are + // included from this service. + std::vector<dbus::ObjectPath> includes_; + + // D-Bus bus object is exported on, not owned by this object and must + // outlive it. + dbus::Bus* bus_; + + // D-Bus object path of object we are exporting, kept so we can unregister + // again in our destructor. + dbus::ObjectPath object_path_; + + // D-Bus object we are exporting, owned by this object. + scoped_refptr<dbus::ExportedObject> exported_object_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothGattServiceServiceProviderImpl> + weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceServiceProviderImpl); +}; + +BluetoothGattServiceServiceProvider::BluetoothGattServiceServiceProvider() {} + +BluetoothGattServiceServiceProvider::~BluetoothGattServiceServiceProvider() {} + +// static +BluetoothGattServiceServiceProvider* +BluetoothGattServiceServiceProvider::Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + const std::string& uuid, + const std::vector<dbus::ObjectPath>& includes) { + if (!bluez::BluezDBusManager::Get()->IsUsingStub()) { + return new BluetoothGattServiceServiceProviderImpl(bus, object_path, uuid, + includes); + } + return new FakeBluetoothGattServiceServiceProvider(object_path, uuid, + includes); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h new file mode 100644 index 0000000..cedec1e --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h @@ -0,0 +1,53 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_ + +#include <string> +#include <vector> + +#include "base/macros.h" +#include "dbus/bus.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" + +namespace bluez { + +// BluetoothGattServiceServiceProvider is used to provide a D-Bus object that +// the Bluetooth daemon can communicate with to register GATT service +// hierarchies. +// +// Instantiate with a chosen D-Bus object path (that conforms to the BlueZ GATT +// service specification), service UUID, and the list of included services, and +// pass the D-Bus object path as the |service_path| argument to the +// chromeos::BluetoothGattManagerClient::RegisterService method. Make sure to +// create characteristic and descriptor objects using the appropriate service +// providers before registering a GATT service with the Bluetooth daemon. +class DEVICE_BLUETOOTH_EXPORT BluetoothGattServiceServiceProvider { + public: + virtual ~BluetoothGattServiceServiceProvider(); + + // Creates the instance where |bus| is the D-Bus bus connection to export the + // object onto, |object_path| is the object path that it should have, |uuid| + // is the 128-bit GATT service UUID, and |includes| are a list of object paths + // belonging to other exported GATT services that are included by the GATT + // service being created. Make sure that all included services have been + // exported before registering a GATT services with the GATT manager. + static BluetoothGattServiceServiceProvider* Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + const std::string& uuid, + const std::vector<dbus::ObjectPath>& includes); + + protected: + BluetoothGattServiceServiceProvider(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/bluetooth_input_client.cc b/device/bluetooth/dbus/bluetooth_input_client.cc new file mode 100644 index 0000000..42542a8 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_input_client.cc @@ -0,0 +1,128 @@ +// Copyright 2013 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 "device/bluetooth/dbus/bluetooth_input_client.h" + +#include <map> + +#include "base/logging.h" +#include "base/stl_util.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_manager.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +BluetoothInputClient::Properties::Properties( + dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback) + : dbus::PropertySet(object_proxy, interface_name, callback) { + RegisterProperty(bluetooth_input::kReconnectModeProperty, &reconnect_mode); +} + +BluetoothInputClient::Properties::~Properties() {} + +// The BluetoothInputClient implementation used in production. +class BluetoothInputClientImpl : public BluetoothInputClient, + public dbus::ObjectManager::Interface { + public: + BluetoothInputClientImpl() : object_manager_(NULL), weak_ptr_factory_(this) {} + + ~BluetoothInputClientImpl() override { + object_manager_->UnregisterInterface( + bluetooth_input::kBluetoothInputInterface); + } + + // BluetoothInputClient override. + void AddObserver(BluetoothInputClient::Observer* observer) override { + DCHECK(observer); + observers_.AddObserver(observer); + } + + // BluetoothInputClient override. + void RemoveObserver(BluetoothInputClient::Observer* observer) override { + DCHECK(observer); + observers_.RemoveObserver(observer); + } + + // dbus::ObjectManager::Interface override. + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + Properties* properties = + new Properties(object_proxy, interface_name, + base::Bind(&BluetoothInputClientImpl::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), object_path)); + return static_cast<dbus::PropertySet*>(properties); + } + + // BluetoothInputClient override. + Properties* GetProperties(const dbus::ObjectPath& object_path) override { + return static_cast<Properties*>(object_manager_->GetProperties( + object_path, bluetooth_input::kBluetoothInputInterface)); + } + + protected: + void Init(dbus::Bus* bus) override { + object_manager_ = bus->GetObjectManager( + bluetooth_object_manager::kBluetoothObjectManagerServiceName, + dbus::ObjectPath( + bluetooth_object_manager::kBluetoothObjectManagerServicePath)); + object_manager_->RegisterInterface( + bluetooth_input::kBluetoothInputInterface, this); + } + + private: + // Called by dbus::ObjectManager when an object with the input interface + // is created. Informs observers. + void ObjectAdded(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_, + InputAdded(object_path)); + } + + // Called by dbus::ObjectManager when an object with the input interface + // is removed. Informs observers. + void ObjectRemoved(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_, + InputRemoved(object_path)); + } + + // Called by BluetoothPropertySet when a property value is changed, + // either by result of a signal or response to a GetAll() or Get() + // call. Informs observers. + void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) { + FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_, + InputPropertyChanged(object_path, property_name)); + } + + dbus::ObjectManager* object_manager_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothInputClient::Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothInputClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothInputClientImpl); +}; + +BluetoothInputClient::BluetoothInputClient() {} + +BluetoothInputClient::~BluetoothInputClient() {} + +BluetoothInputClient* BluetoothInputClient::Create() { + return new BluetoothInputClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_input_client.h b/device/bluetooth/dbus/bluetooth_input_client.h new file mode 100644 index 0000000..829e94c --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_input_client.h @@ -0,0 +1,82 @@ +// Copyright 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_INPUT_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_INPUT_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothInputClient is used to communicate with objects representing +// Bluetooth Input (HID) devices. +class DEVICE_BLUETOOTH_EXPORT BluetoothInputClient : public BluezDBusClient { + public: + // Structure of properties associated with bluetooth input devices. + struct Properties : public dbus::PropertySet { + // The Bluetooth input device reconnect mode. Read-only. + dbus::Property<std::string> reconnect_mode; + + Properties(dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback); + ~Properties() override; + }; + + // Interface for observing changes from a remote bluetooth input device. + class Observer { + public: + virtual ~Observer() {} + + // Called when the remote device with object path |object_path| implementing + // the Input interface is added to the set of known devices or an already + // known device implements the Input interface. + virtual void InputAdded(const dbus::ObjectPath& object_path) {} + + // Called when the remote device with object path |object_path| is removed + // from the set of known devices or does not implement the Input interface + // anymore. + virtual void InputRemoved(const dbus::ObjectPath& object_path) {} + + // Called when the device with object path |object_path| has a + // change in value of the property named |property_name| of its Input + // interface. + virtual void InputPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) {} + }; + + ~BluetoothInputClient() override; + + // Adds and removes observers for events on all remote bluetooth input + // devices. Check the |object_path| parameter of observer methods to + // determine which device is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Obtain the properties for the device with object path |object_path|, + // any values should be copied if needed. + virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0; + + // Creates the instance. + static BluetoothInputClient* Create(); + + protected: + BluetoothInputClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothInputClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_INPUT_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc new file mode 100644 index 0000000..e981124 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc @@ -0,0 +1,426 @@ +// Copyright 2015 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 "device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/stl_util.h" +#include "base/threading/platform_thread.h" +#include "dbus/exported_object.h" +#include "dbus/message.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +namespace { +const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs"; +} // namespace + +// The BluetoothAdvertisementServiceProvider implementation used in production. +class BluetoothAdvertisementServiceProviderImpl + : public BluetoothLEAdvertisementServiceProvider { + public: + BluetoothAdvertisementServiceProviderImpl( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate, + AdvertisementType type, + scoped_ptr<UUIDList> service_uuids, + scoped_ptr<ManufacturerData> manufacturer_data, + scoped_ptr<UUIDList> solicit_uuids, + scoped_ptr<ServiceData> service_data) + : origin_thread_id_(base::PlatformThread::CurrentId()), + bus_(bus), + delegate_(delegate), + type_(type), + service_uuids_(service_uuids.Pass()), + manufacturer_data_(manufacturer_data.Pass()), + solicit_uuids_(solicit_uuids.Pass()), + service_data_(service_data.Pass()), + weak_ptr_factory_(this) { + DCHECK(bus); + DCHECK(delegate); + + VLOG(1) << "Creating Bluetooth Advertisement: " << object_path_.value(); + + object_path_ = object_path; + exported_object_ = bus_->GetExportedObject(object_path_); + + // Export Bluetooth Advertisement interface methods. + exported_object_->ExportMethod( + bluetooth_advertisement::kBluetoothAdvertisementInterface, + bluetooth_advertisement::kRelease, + base::Bind(&BluetoothAdvertisementServiceProviderImpl::Release, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAdvertisementServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + // Export dbus property methods. + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGet, + base::Bind(&BluetoothAdvertisementServiceProviderImpl::Get, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAdvertisementServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + dbus::kDBusPropertiesInterface, dbus::kDBusPropertiesGetAll, + base::Bind(&BluetoothAdvertisementServiceProviderImpl::GetAll, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothAdvertisementServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + } + + ~BluetoothAdvertisementServiceProviderImpl() override { + VLOG(1) << "Cleaning up Bluetooth Advertisement: " << object_path_.value(); + + // Unregister the object path so we can reuse with a new agent. + bus_->UnregisterExportedObject(object_path_); + } + + private: + // Returns true if the current thread is on the origin thread. + bool OnOriginThread() { + return base::PlatformThread::CurrentId() == origin_thread_id_; + } + + // Called by dbus:: when this advertisement is unregistered from the Bluetooth + // daemon, generally by our request. + void Release(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + delegate_->Released(); + } + + // Called by dbus:: when the Bluetooth daemon fetches a single property of + // the descriptor. + void Get(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothAdvertisementServiceProvider::Get: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + std::string property_name; + if (!reader.PopString(&interface_name) || + !reader.PopString(&property_name) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 'ss'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the advertisement interface is supported. + if (interface_name != + bluetooth_advertisement::kBluetoothAdvertisementInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter variant_writer(NULL); + + if (property_name == bluetooth_advertisement::kTypeProperty) { + writer.OpenVariant("s", &variant_writer); + if (type_ == ADVERTISEMENT_TYPE_BROADCAST) { + variant_writer.AppendString("broadcast"); + } else { + variant_writer.AppendString("peripheral"); + } + } else if ((property_name == + bluetooth_advertisement::kServiceUUIDsProperty) && + service_uuids_) { + writer.OpenVariant("as", &variant_writer); + variant_writer.AppendArrayOfStrings(*service_uuids_); + } else if ((property_name == + bluetooth_advertisement::kSolicitUUIDsProperty) && + solicit_uuids_) { + writer.OpenVariant("as", &variant_writer); + variant_writer.AppendArrayOfStrings(*solicit_uuids_); + } else if ((property_name == + bluetooth_advertisement::kManufacturerDataProperty) && + manufacturer_data_) { + writer.OpenVariant("o", &variant_writer); + AppendManufacturerDataVariant(&variant_writer); + } else if ((property_name == + bluetooth_advertisement::kServiceDataProperty) && + service_data_) { + writer.OpenVariant("o", &variant_writer); + AppendServiceDataVariant(&variant_writer); + } else { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such property: '" + property_name + "'."); + response_sender.Run(error_response.Pass()); + } + + writer.CloseContainer(&variant_writer); + response_sender.Run(response.Pass()); + } + + // Called by dbus:: when the Bluetooth daemon fetches all properties of the + // descriptor. + void GetAll(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(2) << "BluetoothAdvertisementServiceProvider::GetAll: " + << object_path_.value(); + DCHECK(OnOriginThread()); + + dbus::MessageReader reader(method_call); + + std::string interface_name; + if (!reader.PopString(&interface_name) || reader.HasMoreData()) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall(method_call, kErrorInvalidArgs, + "Expected 's'."); + response_sender.Run(error_response.Pass()); + return; + } + + // Only the advertisement interface is supported. + if (interface_name != + bluetooth_advertisement::kBluetoothAdvertisementInterface) { + scoped_ptr<dbus::ErrorResponse> error_response = + dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidArgs, + "No such interface: '" + interface_name + "'."); + response_sender.Run(error_response.Pass()); + return; + } + + response_sender.Run(CreateGetAllResponse(method_call).Pass()); + } + + // Called by dbus:: when a method is exported. + void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "." + << method_name; + } + + // Helper for populating the DBus response with the advertisement data. + scoped_ptr<dbus::Response> CreateGetAllResponse( + dbus::MethodCall* method_call) { + VLOG(2) << "Descriptor value obtained from delegate. Responding to " + << "GetAll."; + + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter array_writer(NULL); + + writer.OpenArray("{sv}", &array_writer); + + AppendType(&array_writer); + AppendServiceUUIDs(&array_writer); + AppendManufacturerData(&array_writer); + AppendSolicitUUIDs(&array_writer); + AppendServiceData(&array_writer); + + writer.CloseContainer(&array_writer); + return response; + } + + // Called by the Delegate in response to a successful method call to get the + // descriptor value. + void OnGet(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + const std::vector<uint8>& value) { + VLOG(2) << "Returning descriptor value obtained from delegate."; + scoped_ptr<dbus::Response> response = + dbus::Response::FromMethodCall(method_call); + dbus::MessageWriter writer(response.get()); + dbus::MessageWriter variant_writer(NULL); + + writer.OpenVariant("ay", &variant_writer); + variant_writer.AppendArrayOfBytes(value.data(), value.size()); + writer.CloseContainer(&variant_writer); + + response_sender.Run(response.Pass()); + } + + void AppendArrayVariantOfStrings(dbus::MessageWriter* dict_writer, + const UUIDList& strings) { + dbus::MessageWriter strings_array_variant(nullptr); + dict_writer->OpenVariant("as", &strings_array_variant); + strings_array_variant.AppendArrayOfStrings(strings); + dict_writer->CloseContainer(&strings_array_variant); + } + + void AppendType(dbus::MessageWriter* array_writer) { + dbus::MessageWriter dict_entry_writer(NULL); + array_writer->OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString(bluetooth_advertisement::kTypeProperty); + if (type_ == ADVERTISEMENT_TYPE_BROADCAST) { + dict_entry_writer.AppendVariantOfString("broadcast"); + } else { + dict_entry_writer.AppendVariantOfString("peripheral"); + } + array_writer->CloseContainer(&dict_entry_writer); + } + + void AppendServiceUUIDs(dbus::MessageWriter* array_writer) { + if (!service_uuids_) + return; + dbus::MessageWriter dict_entry_writer(NULL); + array_writer->OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_advertisement::kServiceUUIDsProperty); + AppendArrayVariantOfStrings(&dict_entry_writer, *service_uuids_); + array_writer->CloseContainer(&dict_entry_writer); + } + + void AppendManufacturerData(dbus::MessageWriter* array_writer) { + if (!manufacturer_data_) + return; + dbus::MessageWriter dict_entry_writer(NULL); + array_writer->OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_advertisement::kManufacturerDataProperty); + dbus::MessageWriter variant_writer(NULL); + dict_entry_writer.OpenVariant("a{qay}", &variant_writer); + AppendManufacturerDataVariant(&variant_writer); + dict_entry_writer.CloseContainer(&variant_writer); + array_writer->CloseContainer(&dict_entry_writer); + } + + void AppendSolicitUUIDs(dbus::MessageWriter* array_writer) { + if (!solicit_uuids_) + return; + dbus::MessageWriter dict_entry_writer(NULL); + array_writer->OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_advertisement::kSolicitUUIDsProperty); + AppendArrayVariantOfStrings(&dict_entry_writer, *solicit_uuids_); + array_writer->CloseContainer(&dict_entry_writer); + } + + void AppendServiceData(dbus::MessageWriter* array_writer) { + if (!service_data_) + return; + dbus::MessageWriter dict_entry_writer(NULL); + array_writer->OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_advertisement::kServiceDataProperty); + dbus::MessageWriter variant_writer(NULL); + dict_entry_writer.OpenVariant("a{say}", &variant_writer); + AppendServiceDataVariant(&variant_writer); + dict_entry_writer.CloseContainer(&variant_writer); + array_writer->CloseContainer(&dict_entry_writer); + } + + void AppendManufacturerDataVariant(dbus::MessageWriter* writer) { + DCHECK(manufacturer_data_); + dbus::MessageWriter array_writer(NULL); + writer->OpenArray("{qay}", &array_writer); + for (const auto& m : *manufacturer_data_) { + dbus::MessageWriter entry_writer(NULL); + + array_writer.OpenDictEntry(&entry_writer); + + entry_writer.AppendUint32(m.first); + entry_writer.AppendArrayOfBytes(vector_as_array(&m.second), + m.second.size()); + + array_writer.CloseContainer(&entry_writer); + } + writer->CloseContainer(&array_writer); + } + + void AppendServiceDataVariant(dbus::MessageWriter* writer) { + DCHECK(service_data_); + dbus::MessageWriter array_writer(NULL); + writer->OpenArray("{say}", &array_writer); + for (const auto& m : *service_data_) { + dbus::MessageWriter entry_writer(NULL); + + array_writer.OpenDictEntry(&entry_writer); + + entry_writer.AppendString(m.first); + entry_writer.AppendArrayOfBytes(vector_as_array(&m.second), + m.second.size()); + + array_writer.CloseContainer(&entry_writer); + } + writer->CloseContainer(&array_writer); + } + + // Origin thread (i.e. the UI thread in production). + base::PlatformThreadId origin_thread_id_; + + // D-Bus bus object is exported on, not owned by this object and must + // outlive it. + dbus::Bus* bus_; + + // All incoming method calls are passed on to the Delegate and a callback + // passed to generate the reply. |delegate_| is generally the object that + // owns this one, and must outlive it. + Delegate* delegate_; + + // Advertisement data that needs to be provided to BlueZ when requested. + AdvertisementType type_; + scoped_ptr<UUIDList> service_uuids_; + scoped_ptr<ManufacturerData> manufacturer_data_; + scoped_ptr<UUIDList> solicit_uuids_; + scoped_ptr<ServiceData> service_data_; + + // D-Bus object we are exporting, owned by this object. + scoped_refptr<dbus::ExportedObject> exported_object_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothAdvertisementServiceProviderImpl> + weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisementServiceProviderImpl); +}; + +BluetoothLEAdvertisementServiceProvider:: + BluetoothLEAdvertisementServiceProvider() {} + +BluetoothLEAdvertisementServiceProvider:: + ~BluetoothLEAdvertisementServiceProvider() {} + +// static +scoped_ptr<BluetoothLEAdvertisementServiceProvider> +BluetoothLEAdvertisementServiceProvider::Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate, + AdvertisementType type, + scoped_ptr<UUIDList> service_uuids, + scoped_ptr<ManufacturerData> manufacturer_data, + scoped_ptr<UUIDList> solicit_uuids, + scoped_ptr<ServiceData> service_data) { + if (!bluez::BluezDBusManager::Get()->IsUsingStub()) { + return make_scoped_ptr(new BluetoothAdvertisementServiceProviderImpl( + bus, object_path, delegate, type, service_uuids.Pass(), + manufacturer_data.Pass(), solicit_uuids.Pass(), service_data.Pass())); + } else { + return make_scoped_ptr( + new FakeBluetoothLEAdvertisementServiceProvider(object_path, delegate)); + } +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h new file mode 100644 index 0000000..8f4692f --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h @@ -0,0 +1,82 @@ +// Copyright 2015 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_ + +#include <stdint.h> + +#include <map> +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "dbus/bus.h" +#include "dbus/file_descriptor.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" + +namespace bluez { + +// BluetoothAdvertisementServiceProvider is used to provide a D-Bus object that +// the Bluetooth daemon can communicate with to advertise data. +class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisementServiceProvider { + public: + using UUIDList = std::vector<std::string>; + using ManufacturerData = std::map<uint16_t, std::vector<uint8_t>>; + using ServiceData = std::map<std::string, std::vector<uint8_t>>; + + // Type of advertisement. + enum AdvertisementType { + ADVERTISEMENT_TYPE_BROADCAST, + ADVERTISEMENT_TYPE_PERIPHERAL + }; + + // Interface for reacting to advertisement changes. + class Delegate { + public: + virtual ~Delegate() {} + + // This method will be called when the advertisement is unregistered from + // the Bluetooth daemon, generally at shutdown or if the adapter goes away. + // It may be used to perform cleanup tasks. This corresponds to the + // org.bluez.LEAdvertisement1.Release method and is renamed to avoid a + // conflict with base::Refcounted<T>. + virtual void Released() = 0; + }; + + virtual ~BluetoothLEAdvertisementServiceProvider(); + + const dbus::ObjectPath& object_path() { return object_path_; } + + // Creates the instance where |bus| is the D-Bus bus connection to export + // the object onto, |object_path| is the object path that it should have + // and |delegate| is the object to which all method calls will be passed + // and responses generated from. + static scoped_ptr<BluetoothLEAdvertisementServiceProvider> Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate, + AdvertisementType type, + scoped_ptr<UUIDList> service_uuids, + scoped_ptr<ManufacturerData> manufacturer_data, + scoped_ptr<UUIDList> solicit_uuids, + scoped_ptr<ServiceData> service_data); + + protected: + BluetoothLEAdvertisementServiceProvider(); + + // D-Bus object path of object we are exporting, kept so we can unregister + // again in our destructor. + dbus::ObjectPath object_path_; + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothLEAdvertisementServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc new file mode 100644 index 0000000..3c934e6 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc @@ -0,0 +1,187 @@ +// Copyright 2015 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 "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/observer_list.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_manager.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +const char BluetoothLEAdvertisingManagerClient::kNoResponseError[] = + "org.chromium.Error.NoResponse"; + +// The BluetoothAdvertisementManagerClient implementation used in production. +class BluetoothAdvertisementManagerClientImpl + : public BluetoothLEAdvertisingManagerClient, + public dbus::ObjectManager::Interface { + public: + BluetoothAdvertisementManagerClientImpl() + : object_manager_(NULL), weak_ptr_factory_(this) {} + + ~BluetoothAdvertisementManagerClientImpl() override { + if (object_manager_) { + object_manager_->UnregisterInterface( + bluetooth_advertising_manager::kBluetoothAdvertisingManagerInterface); + } + } + + // BluetoothAdapterClient override. + void AddObserver( + BluetoothLEAdvertisingManagerClient::Observer* observer) override { + DCHECK(observer); + observers_.AddObserver(observer); + } + + // BluetoothAdapterClient override. + void RemoveObserver( + BluetoothLEAdvertisingManagerClient::Observer* observer) override { + DCHECK(observer); + observers_.RemoveObserver(observer); + } + + // dbus::ObjectManager::Interface override. + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + return new dbus::PropertySet(object_proxy, interface_name, + dbus::PropertySet::PropertyChangedCallback()); + } + + // BluetoothAdvertisementManagerClient override. + void RegisterAdvertisement(const dbus::ObjectPath& manager_object_path, + const dbus::ObjectPath& advertisement_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_advertising_manager::kBluetoothAdvertisingManagerInterface, + bluetooth_advertising_manager::kRegisterAdvertisement); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(advertisement_object_path); + + // Empty dictionary for options. + dbus::MessageWriter array_writer(NULL); + writer.OpenArray("{sv}", &array_writer); + writer.CloseContainer(&array_writer); + + DCHECK(object_manager_); + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(manager_object_path); + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAdvertisementManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAdvertisementManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothAdvertisementManagerClient override. + void UnregisterAdvertisement( + const dbus::ObjectPath& manager_object_path, + const dbus::ObjectPath& advertisement_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_advertising_manager::kBluetoothAdvertisingManagerInterface, + bluetooth_advertising_manager::kUnregisterAdvertisement); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(advertisement_object_path); + + DCHECK(object_manager_); + dbus::ObjectProxy* object_proxy = + object_manager_->GetObjectProxy(manager_object_path); + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothAdvertisementManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothAdvertisementManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + protected: + void Init(dbus::Bus* bus) override { + DCHECK(bus); + object_manager_ = bus->GetObjectManager( + bluetooth_object_manager::kBluetoothObjectManagerServiceName, + dbus::ObjectPath( + bluetooth_object_manager::kBluetoothObjectManagerServicePath)); + object_manager_->RegisterInterface( + bluetooth_advertising_manager::kBluetoothAdvertisingManagerInterface, + this); + } + + private: + // Called by dbus::ObjectManager when an object with the advertising manager + // interface is created. Informs observers. + void ObjectAdded(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + FOR_EACH_OBSERVER(BluetoothLEAdvertisingManagerClient::Observer, observers_, + AdvertisingManagerAdded(object_path)); + } + + // Called by dbus::ObjectManager when an object with the advertising manager + // interface is removed. Informs observers. + void ObjectRemoved(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + FOR_EACH_OBSERVER(BluetoothLEAdvertisingManagerClient::Observer, observers_, + AdvertisingManagerRemoved(object_path)); + } + + // Called when a response for successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + // Error response has optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + error_message = ""; + } + error_callback.Run(error_name, error_message); + } + + dbus::ObjectManager* object_manager_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothLEAdvertisingManagerClient::Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothAdvertisementManagerClientImpl> + weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisementManagerClientImpl); +}; + +BluetoothLEAdvertisingManagerClient::BluetoothLEAdvertisingManagerClient() {} + +BluetoothLEAdvertisingManagerClient::~BluetoothLEAdvertisingManagerClient() {} + +BluetoothLEAdvertisingManagerClient* +BluetoothLEAdvertisingManagerClient::Create() { + return new BluetoothAdvertisementManagerClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h new file mode 100644 index 0000000..73aa9ed --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h @@ -0,0 +1,85 @@ +// Copyright 2015 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothAdvertisingManagerClient is used to communicate with the advertising +// manager object of the BlueZ daemon. +class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisingManagerClient + : public BluezDBusClient { + public: + // Interface for observing changes to advertising managers. + class Observer { + public: + virtual ~Observer() {} + + // Called when an advertising manager with object path |object_path| is + // added to the system. + virtual void AdvertisingManagerAdded(const dbus::ObjectPath& object_path) {} + + // Called when an advertising manager with object path |object_path| is + // removed from the system. + virtual void AdvertisingManagerRemoved( + const dbus::ObjectPath& object_path) {} + }; + + ~BluetoothLEAdvertisingManagerClient() override; + + // Adds and removes observers for events which change the advertising + // managers on the system. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // The ErrorCallback is used by advertising manager methods to indicate + // failure. It receives two arguments: the name of the error in |error_name| + // and an optional message in |error_message|. + using ErrorCallback = base::Callback<void(const std::string& error_name, + const std::string& error_message)>; + + // Registers an advertisement with the DBus object path + // |advertisement_object_path| with BlueZ's advertising manager. + virtual void RegisterAdvertisement( + const dbus::ObjectPath& manager_object_path, + const dbus::ObjectPath& advertisement_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Unregisters an advertisement with the DBus object path + // |advertisement_object_path| with BlueZ's advertising manager. + virtual void UnregisterAdvertisement( + const dbus::ObjectPath& manager_object_path, + const dbus::ObjectPath& advertisement_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Creates the instance. + static BluetoothLEAdvertisingManagerClient* Create(); + + // Constants used to indicate exceptional error conditions. + static const char kNoResponseError[]; + + protected: + BluetoothLEAdvertisingManagerClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothLEAdvertisingManagerClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_media_client.cc b/device/bluetooth/dbus/bluetooth_media_client.cc new file mode 100644 index 0000000..0927d45 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_media_client.cc @@ -0,0 +1,227 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_media_client.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/observer_list.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_manager.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace { + +// Since there is no property associated with Media objects, an empty callback +// is used. +void DoNothing(const std::string& property_name) {} + +// TODO(mcchou): Add these service constants into dbus/service_constants.h +// later. +const char kBluetoothMediaInterface[] = "org.bluez.Media1"; + +// Method names supported by Media Interface. +const char kRegisterEndpoint[] = "RegisterEndpoint"; +const char kUnregisterEndpoint[] = "UnregisterEndpoint"; + +// The set of properties which are used to register a media endpoint. +const char kUUIDEndpointProperty[] = "UUID"; +const char kCodecEndpointProperty[] = "Codec"; +const char kCapabilitiesEndpointProperty[] = "Capabilities"; + +} // namespace + +namespace bluez { + +// static +const char BluetoothMediaClient::kNoResponseError[] = + "org.chromium.Error.NoResponse"; + +// static +const char BluetoothMediaClient::kBluetoothAudioSinkUUID[] = + "0000110b-0000-1000-8000-00805f9b34fb"; + +BluetoothMediaClient::EndpointProperties::EndpointProperties() : codec(0x00) {} + +BluetoothMediaClient::EndpointProperties::~EndpointProperties() {} + +class BluetoothMediaClientImpl : public BluetoothMediaClient, + dbus::ObjectManager::Interface { + public: + BluetoothMediaClientImpl() + : object_manager_(nullptr), weak_ptr_factory_(this) {} + + ~BluetoothMediaClientImpl() override { + object_manager_->UnregisterInterface(kBluetoothMediaInterface); + } + + // dbus::ObjectManager::Interface overrides. + + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + return new dbus::PropertySet(object_proxy, interface_name, + base::Bind(&DoNothing)); + } + + void ObjectAdded(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(1) << "Remote Media added: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothMediaClient::Observer, observers_, + MediaAdded(object_path)); + } + + void ObjectRemoved(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(1) << "Remote Media removed: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothMediaClient::Observer, observers_, + MediaRemoved(object_path)); + } + + // BluetoothMediaClient overrides. + + void AddObserver(BluetoothMediaClient::Observer* observer) override { + DCHECK(observer); + observers_.AddObserver(observer); + } + + void RemoveObserver(BluetoothMediaClient::Observer* observer) override { + DCHECK(observer); + observers_.RemoveObserver(observer); + } + + void RegisterEndpoint(const dbus::ObjectPath& object_path, + const dbus::ObjectPath& endpoint_path, + const EndpointProperties& properties, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + VLOG(1) << "RegisterEndpoint - endpoint: " << endpoint_path.value(); + + dbus::MethodCall method_call(kBluetoothMediaInterface, kRegisterEndpoint); + + dbus::MessageWriter writer(&method_call); + dbus::MessageWriter array_writer(nullptr); + dbus::MessageWriter dict_entry_writer(nullptr); + + // Send the path to the endpoint. + writer.AppendObjectPath(endpoint_path); + + writer.OpenArray("{sv}", &array_writer); + + // Send UUID. + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString(kUUIDEndpointProperty); + dict_entry_writer.AppendVariantOfString(properties.uuid); + array_writer.CloseContainer(&dict_entry_writer); + + // Send Codec. + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString(kCodecEndpointProperty); + dict_entry_writer.AppendVariantOfByte(properties.codec); + array_writer.CloseContainer(&dict_entry_writer); + + // Send Capabilities. + dbus::MessageWriter variant_writer(nullptr); + array_writer.OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString(kCapabilitiesEndpointProperty); + dict_entry_writer.OpenVariant("ay", &variant_writer); + variant_writer.AppendArrayOfBytes(properties.capabilities.data(), + properties.capabilities.size()); + dict_entry_writer.CloseContainer(&variant_writer); + array_writer.CloseContainer(&dict_entry_writer); + + writer.CloseContainer(&array_writer); + + // Get Object Proxy based on the service name and the service path and call + // RegisterEndpoint medthod. + scoped_refptr<dbus::ObjectProxy> object_proxy( + object_manager_->GetObjectProxy(object_path)); + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothMediaClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothMediaClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + void UnregisterEndpoint(const dbus::ObjectPath& object_path, + const dbus::ObjectPath& endpoint_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + VLOG(1) << "UnregisterEndpoint - endpoint: " << endpoint_path.value(); + + dbus::MethodCall method_call(kBluetoothMediaInterface, kUnregisterEndpoint); + + // Send the path to the endpoint. + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(endpoint_path); + + // Get Object Proxy based on the service name and the service path and call + // RegisterEndpoint medthod. + scoped_refptr<dbus::ObjectProxy> object_proxy( + object_manager_->GetObjectProxy(object_path)); + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothMediaClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothMediaClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + protected: + void Init(dbus::Bus* bus) override { + DCHECK(bus); + object_manager_ = bus->GetObjectManager( + bluetooth_object_manager::kBluetoothObjectManagerServiceName, + dbus::ObjectPath( + bluetooth_object_manager::kBluetoothObjectManagerServicePath)); + object_manager_->RegisterInterface(kBluetoothMediaInterface, this); + } + + private: + // Called when a response for successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + // Error response has an optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + } + error_callback.Run(error_name, error_message); + } + + dbus::ObjectManager* object_manager_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothMediaClient::Observer> observers_; + + base::WeakPtrFactory<BluetoothMediaClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothMediaClientImpl); +}; + +BluetoothMediaClient::BluetoothMediaClient() {} + +BluetoothMediaClient::~BluetoothMediaClient() {} + +BluetoothMediaClient* BluetoothMediaClient::Create() { + return new BluetoothMediaClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_media_client.h b/device/bluetooth/dbus/bluetooth_media_client.h new file mode 100644 index 0000000..88597c5 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_media_client.h @@ -0,0 +1,108 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_CLIENT_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/values.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothMediaClient is used to communicate with the Media interface of a +// local Bluetooth adapter. +class DEVICE_BLUETOOTH_EXPORT BluetoothMediaClient : public BluezDBusClient { + public: + // Properties used to register a Media Endpoint. + struct DEVICE_BLUETOOTH_EXPORT EndpointProperties { + EndpointProperties(); + ~EndpointProperties(); + + // UUID of the profile implemented by the endpoint. + std::string uuid; + + // Assigned codec value supported by the endpoint. The byte should match the + // codec specification indicated by the UUID. + // Since SBC codec is mandatory for A2DP, the default value of codec should + // be 0x00. + uint8_t codec; + + // Capabilities of the endpoints. The order of bytes should match the bit + // arrangement in the specification indicated by the UUID. + std::vector<uint8_t> capabilities; + }; + + class Observer { + public: + virtual ~Observer() {} + + // Called when the Media object with object path |object_path| is added to + // the system. + virtual void MediaAdded(const dbus::ObjectPath& object_path) {} + + // Called when the Media object with object path |object_path| is removed + // from the system. + virtual void MediaRemoved(const dbus::ObjectPath& object_path) {} + }; + + // Constants used to indicate exceptional error conditions. + static const char kNoResponseError[]; + + // The string representation for the 128-bit UUID for A2DP Sink. + static const char kBluetoothAudioSinkUUID[]; + + ~BluetoothMediaClient() override; + + // The ErrorCallback is used by media API methods to indicate failure. + // It receives two arguments: the name of the error in |error_name| and + // an optional message in |error_message|. + typedef base::Callback<void(const std::string& error_name, + const std::string& error_message)> ErrorCallback; + + // Adds and removes observers for events on all Media objects. Check the + // |object_path| parameter of observer methods to determine which Media object + // is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + // Registers a media endpoint to sender at the D-Bus object path + // |endpoint_path|. |properties| specifies profile UUID which the endpoint is + // for, Codec implemented by the endpoint and the Capabilities of the + // endpoint. + virtual void RegisterEndpoint(const dbus::ObjectPath& object_path, + const dbus::ObjectPath& endpoint_path, + const EndpointProperties& properties, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Unregisters the media endpoint with the D-Bus object path |endpoint_path|. + virtual void UnregisterEndpoint(const dbus::ObjectPath& object_path, + const dbus::ObjectPath& endpoint_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // TODO(mcchou): The RegisterPlayer and UnregisterPlayer methods are not + // included, since they are not used. These two methods may be added later. + + static BluetoothMediaClient* Create(); + + protected: + BluetoothMediaClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothMediaClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.cc b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.cc new file mode 100644 index 0000000..864a04d --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.cc @@ -0,0 +1,313 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/threading/platform_thread.h" +#include "dbus/exported_object.h" +#include "device/bluetooth/dbus/bluetooth_media_transport_client.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h" + +namespace { + +// TODO(mcchou): Move these constants to dbus/service_constants.h. +// Bluetooth Media Endpoint service identifier. +const char kBluetoothMediaEndpointInterface[] = "org.bluez.MediaEndpoint1"; + +// Method names in Bluetooth Media Endpoint interface. +const char kSetConfiguration[] = "SetConfiguration"; +const char kSelectConfiguration[] = "SelectConfiguration"; +const char kClearConfiguration[] = "ClearConfiguration"; +const char kRelease[] = "Release"; + +const uint8_t kInvalidCodec = 0xff; +const char kInvalidState[] = "unknown"; + +} // namespace + +namespace bluez { + +// The BluetoothMediaEndopintServiceProvider implementation used in production. +class DEVICE_BLUETOOTH_EXPORT BluetoothMediaEndpointServiceProviderImpl + : public BluetoothMediaEndpointServiceProvider { + public: + BluetoothMediaEndpointServiceProviderImpl(dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate) + : origin_thread_id_(base::PlatformThread::CurrentId()), + bus_(bus), + delegate_(delegate), + object_path_(object_path), + weak_ptr_factory_(this) { + VLOG(1) << "Creating Bluetooth Media Endpoint: " << object_path_.value(); + DCHECK(bus_); + DCHECK(delegate_); + DCHECK(object_path_.IsValid()); + + exported_object_ = bus_->GetExportedObject(object_path_); + + exported_object_->ExportMethod( + kBluetoothMediaEndpointInterface, kSetConfiguration, + base::Bind(&BluetoothMediaEndpointServiceProviderImpl::SetConfiguration, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothMediaEndpointServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + kBluetoothMediaEndpointInterface, kSelectConfiguration, + base::Bind( + &BluetoothMediaEndpointServiceProviderImpl::SelectConfiguration, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothMediaEndpointServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + kBluetoothMediaEndpointInterface, kClearConfiguration, + base::Bind( + &BluetoothMediaEndpointServiceProviderImpl::ClearConfiguration, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothMediaEndpointServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + kBluetoothMediaEndpointInterface, kRelease, + base::Bind(&BluetoothMediaEndpointServiceProviderImpl::Release, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothMediaEndpointServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + } + + ~BluetoothMediaEndpointServiceProviderImpl() override { + VLOG(1) << "Cleaning up Bluetooth Media Endpoint: " << object_path_.value(); + + bus_->UnregisterExportedObject(object_path_); + } + + private: + // Returns true if the current thread is on the origin thread, false + // otherwise. + bool OnOriginThread() const { + return base::PlatformThread::CurrentId() == origin_thread_id_; + } + + // Called by dbus:: when a method is exported. + void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + LOG_IF(ERROR, !success) << "Failed to export " << interface_name << "." + << method_name; + } + + // Called by dbus:: when the remote device connects to the Media Endpoint. + void SetConfiguration(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(1) << "SetConfiguration"; + + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath transport_path; + dbus::MessageReader property_reader(method_call); + if (!reader.PopObjectPath(&transport_path) || + !reader.PopArray(&property_reader)) { + LOG(ERROR) << "SetConfiguration called with incorrect parameters: " + << method_call->ToString(); + return; + } + + // Parses |properties| and passes the property set as a + // Delegate::TransportProperties structure to |delegate_|. + Delegate::TransportProperties properties; + while (property_reader.HasMoreData()) { + dbus::MessageReader dict_entry_reader(nullptr); + std::string key; + if (!property_reader.PopDictEntry(&dict_entry_reader) || + !dict_entry_reader.PopString(&key)) { + LOG(ERROR) << "SetConfiguration called with incorrect parameters: " + << method_call->ToString(); + } else if (key == BluetoothMediaTransportClient::kDeviceProperty) { + dict_entry_reader.PopVariantOfObjectPath(&properties.device); + } else if (key == BluetoothMediaTransportClient::kUUIDProperty) { + dict_entry_reader.PopVariantOfString(&properties.uuid); + } else if (key == BluetoothMediaTransportClient::kCodecProperty) { + dict_entry_reader.PopVariantOfByte(&properties.codec); + } else if (key == BluetoothMediaTransportClient::kConfigurationProperty) { + dbus::MessageReader variant_reader(nullptr); + const uint8_t* bytes = nullptr; + size_t length = 0; + dict_entry_reader.PopVariant(&variant_reader); + variant_reader.PopArrayOfBytes(&bytes, &length); + properties.configuration.assign(bytes, bytes + length); + } else if (key == BluetoothMediaTransportClient::kStateProperty) { + dict_entry_reader.PopVariantOfString(&properties.state); + } else if (key == BluetoothMediaTransportClient::kDelayProperty) { + properties.delay.reset(new uint16_t()); + dict_entry_reader.PopVariantOfUint16(properties.delay.get()); + } else if (key == BluetoothMediaTransportClient::kVolumeProperty) { + properties.volume.reset(new uint16_t()); + dict_entry_reader.PopVariantOfUint16(properties.volume.get()); + } + } + + if (properties.codec != kInvalidCodec && + properties.state != kInvalidState) { + delegate_->SetConfiguration(transport_path, properties); + } else { + LOG(ERROR) << "SetConfiguration called with incorrect parameters: " + << method_call->ToString(); + } + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when the remote device receives the configuration for + // media transport. + void SelectConfiguration( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(1) << "SelectConfiguration"; + + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + const uint8_t* capabilities = nullptr; + size_t length = 0; + if (!reader.PopArrayOfBytes(&capabilities, &length)) { + LOG(ERROR) << "SelectConfiguration called with incorrect parameters: " + << method_call->ToString(); + return; + } + + std::vector<uint8_t> configuration(capabilities, capabilities + length); + + // |delegate_| generates the response to |SelectConfiguration| and sends it + // back via |callback|. + Delegate::SelectConfigurationCallback callback = base::Bind( + &BluetoothMediaEndpointServiceProviderImpl::OnConfiguration, + weak_ptr_factory_.GetWeakPtr(), method_call, response_sender); + + delegate_->SelectConfiguration(configuration, callback); + } + + // Called by dbus:: when the remote device is about to close the connection. + void ClearConfiguration( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(1) << "ClearConfiguration"; + + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath transport_path; + if (!reader.PopObjectPath(&transport_path)) { + LOG(ERROR) << "ClearConfiguration called with incorrect parameters: " + << method_call->ToString(); + return; + } + + delegate_->ClearConfiguration(transport_path); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by Bluetooth daemon to do the clean up after unregistering the Media + // Endpoint. + void Release(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + VLOG(1) << "Release"; + + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + delegate_->Released(); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by Delegate to response to a method requiring transport + // configuration. + void OnConfiguration(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + const std::vector<uint8_t>& configuration) { + VLOG(1) << "OnConfiguration"; + + DCHECK(OnOriginThread()); + + // Generates the response to the method call. + scoped_ptr<dbus::Response> response( + dbus::Response::FromMethodCall(method_call)); + dbus::MessageWriter writer(response.get()); + if (configuration.empty()) { + LOG(ERROR) << "OnConfiguration called with empty configuration."; + writer.AppendArrayOfBytes(nullptr, 0); + } else { + writer.AppendArrayOfBytes(&configuration[0], configuration.size()); + } + response_sender.Run(response.Pass()); + } + + // Origin thread (i.e. the UI thread in production). + base::PlatformThreadId origin_thread_id_; + + // D-Bus Bus object is exported on. + dbus::Bus* bus_; + + // All incoming method calls are passed on to |delegate_|. |callback| passed + // to |delegate+| will generate the response for those methods whose returns + // are non-void. + Delegate* delegate_; + + // D-Bus object path of the object we are exporting, kept so we can unregister + // again in you destructor. + dbus::ObjectPath object_path_; + + // D-Bus object we are exporting, owned by this object. + scoped_refptr<dbus::ExportedObject> exported_object_; + + // Weak pointer factory for generating 'this' printers that might live longer + // than we do. + // Note This should remain the last member so it'll be destroyed and + // invalidate it's weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothMediaEndpointServiceProviderImpl> + weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothMediaEndpointServiceProviderImpl); +}; + +BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties:: + TransportProperties() + : codec(kInvalidCodec), state(kInvalidState) {} + +BluetoothMediaEndpointServiceProvider::Delegate::TransportProperties:: + ~TransportProperties() {} + +BluetoothMediaEndpointServiceProvider::BluetoothMediaEndpointServiceProvider() { +} + +BluetoothMediaEndpointServiceProvider:: + ~BluetoothMediaEndpointServiceProvider() {} + +BluetoothMediaEndpointServiceProvider* +BluetoothMediaEndpointServiceProvider::Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate) { + // Returns a real implementation. + if (!bluez::BluezDBusManager::Get()->IsUsingStub()) { + return new BluetoothMediaEndpointServiceProviderImpl(bus, object_path, + delegate); + } + // Returns a fake implementation. + return new FakeBluetoothMediaEndpointServiceProvider(object_path, delegate); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h new file mode 100644 index 0000000..d44c065 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h @@ -0,0 +1,134 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" + +namespace bluez { + +// BluetoothMediaEndpointServiceProvider is used to provide a D-Bus object that +// the Bluetooth daemon can commuicate with to serve as a media source/sink. +// +// Instantiate with a chosen D-Bus object path and a delegate object, and pass +// the D-Bus object path as |endpoint_path| argument to the +// chromeos::BluetoothMediaClient::RegisterEndoint() method. +// +// After initiating a connection between an audio source and an audio sink, the +// Bluetooth daemon will make calls to this endpoint object and they will be +// passed to user's Delegate object for handling. For SelectConfiguration method +// the response is returned using the SelectConfiguration callback. +class DEVICE_BLUETOOTH_EXPORT BluetoothMediaEndpointServiceProvider { + public: + // Delegate is the interface for reacting to endpoint requests. User + // applications will implement this interface to handle either A2DP Sink or + // Source. + class Delegate { + public: + // Transport-specific properties. + struct DEVICE_BLUETOOTH_EXPORT TransportProperties { + TransportProperties(); + ~TransportProperties(); + + // The path to the device object which the transport is connected to. + dbus::ObjectPath device; + + // The UUID of the profile which the transport is for. + std::string uuid; + + // The Codec value agreed by the remote device and used by the media + // transport. + uint8_t codec; + + // The configuration used by the media transport. + std::vector<uint8_t> configuration; + + // The state of the transport. The values can be one of the following: + // "idle": not streaming + // "pending": streaming but not acquired + // "active": streaming and acquired + std::string state; + + // The unit of transport is in 1/10 millisecond. Optional. + scoped_ptr<uint16_t> delay; + + // The volume level of the transport. Optional. + scoped_ptr<uint16_t> volume; + + private: + DISALLOW_COPY_AND_ASSIGN(TransportProperties); + }; + + virtual ~Delegate() {} + + // SelectConfigurationCallback is used for the SelectConfiguration() method, + // it should be called with two arguements, the |configuration| which is + // agreed by the application and the |length| of |configuration|. + typedef base::Callback<void(const std::vector<uint8_t>&)> + SelectConfigurationCallback; + + // This method will be called after an Audio Source receives the agreed + // capabilities from the Audio Sink to set the configuration for the + // media transport object. |transport_path| is the path to the + // MediaTransport object, and |properties| are the properties for that + // MediaTransport object. + virtual void SetConfiguration(const dbus::ObjectPath& transport_path, + const TransportProperties& properties) = 0; + + // This method will be called when an Audio Source connects to an Audio Sink + // and asks it to decide the configuration to be used during the oncoming + // streaming. Audio Sources provide |capabilities| as a reference, where + // a user application can use these |capabilities| to figure out + // a well-matched configuration and return it to the Audio Source via + // |callback|. + virtual void SelectConfiguration( + const std::vector<uint8_t>& capabilities, + const SelectConfigurationCallback& callback) = 0; + + // This method will be called when an Audio Source disconnects from an Audio + // Sink. A user application is supposed to clear any of its resources which + // it keeps for that particular connection. |transport_path| is the Media + // Transport object which has been kept by an endpoint during the + // connection. + virtual void ClearConfiguration(const dbus::ObjectPath& transport_path) = 0; + + // This method will be called when the Bluetooth daemon unregisters the + // Media Endpoint. Media Endpoint objects can use this method to clean up + // tasks. There is no need to unregister the endpoint, since when this + // method gets called, that endpoint has been unregistered. This corresponds + // to the org.bluez.MediaEndpoint1.Release and is renamed to avoid + // a conflict with base::RefCounted<T>. + virtual void Released() = 0; + }; + + virtual ~BluetoothMediaEndpointServiceProvider(); + + // Creates the instance where |bus| is the D-Bus bus connection to export the + // object onto, |object_path| is the object path that it should have and + // |delegate| is the object to which all method calls will be passed and + // responses generated from. + static BluetoothMediaEndpointServiceProvider* Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate); + + protected: + BluetoothMediaEndpointServiceProvider(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothMediaEndpointServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/bluetooth_media_transport_client.cc b/device/bluetooth/dbus/bluetooth_media_transport_client.cc new file mode 100644 index 0000000..7fc47d7 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_media_transport_client.cc @@ -0,0 +1,286 @@ +// Copyright 2014 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 "device/bluetooth/dbus/bluetooth_media_transport_client.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/observer_list.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_manager.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace { + +// TODO(mcchou): Add these service constants into dbus/service_constants.h +// later. +const char kBluetoothMediaTransportInterface[] = "org.bluez.MediaTransport1"; + +// Constants used to indicate exceptional error conditions. +const char kNoResponseError[] = "org.chromium.Error.NoResponse"; +const char kUnexpectedResponse[] = "org.chromium.Error.UnexpectedResponse"; + +// Method names of Media Transport interface. +const char kAcquire[] = "Acquire"; +const char kTryAcquire[] = "TryAcquire"; +const char kRelease[] = "Release"; + +} // namespace + +namespace bluez { + +// static +const char BluetoothMediaTransportClient::kDeviceProperty[] = "Device"; +const char BluetoothMediaTransportClient::kUUIDProperty[] = "UUID"; +const char BluetoothMediaTransportClient::kCodecProperty[] = "Codec"; +const char BluetoothMediaTransportClient::kConfigurationProperty[] = + "Configuration"; +const char BluetoothMediaTransportClient::kStateProperty[] = "State"; +const char BluetoothMediaTransportClient::kDelayProperty[] = "Delay"; +const char BluetoothMediaTransportClient::kVolumeProperty[] = "Volume"; + +// static +const char BluetoothMediaTransportClient::kStateIdle[] = "idle"; +const char BluetoothMediaTransportClient::kStatePending[] = "pending"; +const char BluetoothMediaTransportClient::kStateActive[] = "active"; + +BluetoothMediaTransportClient::Properties::Properties( + dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback) + : dbus::PropertySet(object_proxy, interface_name, callback) { + RegisterProperty(kDeviceProperty, &device); + RegisterProperty(kUUIDProperty, &uuid); + RegisterProperty(kCodecProperty, &codec); + RegisterProperty(kConfigurationProperty, &configuration); + RegisterProperty(kStateProperty, &state); + RegisterProperty(kDelayProperty, &delay); + RegisterProperty(kVolumeProperty, &volume); +} + +BluetoothMediaTransportClient::Properties::~Properties() {} + +class BluetoothMediaTransportClientImpl + : public BluetoothMediaTransportClient, + public dbus::ObjectManager::Interface { + public: + BluetoothMediaTransportClientImpl() + : object_manager_(nullptr), weak_ptr_factory_(this) {} + + ~BluetoothMediaTransportClientImpl() override { + object_manager_->UnregisterInterface(kBluetoothMediaTransportInterface); + } + + // dbus::ObjectManager::Interface overrides. + + dbus::PropertySet* CreateProperties( + dbus::ObjectProxy* object_proxy, + const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + Properties* properties = new Properties( + object_proxy, interface_name, + base::Bind(&BluetoothMediaTransportClientImpl::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), object_path)); + return properties; + } + + void ObjectAdded(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(1) << "Remote Media Transport added: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_, + MediaTransportAdded(object_path)); + } + + void ObjectRemoved(const dbus::ObjectPath& object_path, + const std::string& interface_name) override { + VLOG(1) << "Remote Media Transport removed: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_, + MediaTransportRemoved(object_path)); + } + + // BluetoothMediaTransportClient overrides. + + void AddObserver(BluetoothMediaTransportClient::Observer* observer) override { + DCHECK(observer); + observers_.AddObserver(observer); + } + + void RemoveObserver( + BluetoothMediaTransportClient::Observer* observer) override { + DCHECK(observer); + observers_.RemoveObserver(observer); + } + + Properties* GetProperties(const dbus::ObjectPath& object_path) override { + DCHECK(object_manager_); + return static_cast<Properties*>(object_manager_->GetProperties( + object_path, kBluetoothMediaTransportInterface)); + } + + void Acquire(const dbus::ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback) override { + VLOG(1) << "Acquire - transport: " << object_path.value(); + + DCHECK(object_manager_); + + dbus::MethodCall method_call(kBluetoothMediaTransportInterface, kAcquire); + + // Get object proxy. + scoped_refptr<dbus::ObjectProxy> object_proxy( + object_manager_->GetObjectProxy(object_path)); + + // Call Acquire method of Media Transport interface. + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothMediaTransportClientImpl::OnAcquireSuccess, + weak_ptr_factory_.GetWeakPtr(), callback, error_callback), + base::Bind(&BluetoothMediaTransportClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + void TryAcquire(const dbus::ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback) override { + VLOG(1) << "TryAcquire - transport: " << object_path.value(); + + DCHECK(object_manager_); + + dbus::MethodCall method_call(kBluetoothMediaTransportInterface, + kTryAcquire); + + // Get object proxy. + scoped_refptr<dbus::ObjectProxy> object_proxy( + object_manager_->GetObjectProxy(object_path)); + + // Call TryAcquire method of Media Transport interface. + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothMediaTransportClientImpl::OnAcquireSuccess, + weak_ptr_factory_.GetWeakPtr(), callback, error_callback), + base::Bind(&BluetoothMediaTransportClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + void Release(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + VLOG(1) << "Release - transport: " << object_path.value(); + + DCHECK(object_manager_); + + dbus::MethodCall method_call(kBluetoothMediaTransportInterface, kRelease); + + // Get object proxy. + scoped_refptr<dbus::ObjectProxy> object_proxy( + object_manager_->GetObjectProxy(object_path)); + + // Call TryAcquire method of Media Transport interface. + object_proxy->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothMediaTransportClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothMediaTransportClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + protected: + void Init(dbus::Bus* bus) override { + DCHECK(bus); + object_manager_ = bus->GetObjectManager( + bluetooth_object_manager::kBluetoothObjectManagerServiceName, + dbus::ObjectPath( + bluetooth_object_manager::kBluetoothObjectManagerServicePath)); + object_manager_->RegisterInterface(kBluetoothMediaTransportInterface, this); + } + + private: + // Called by dbus::PropertySet when a property value is changed. + void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name) { + VLOG(1) << "Name of the changed property: " << property_name; + + // Dispatches the change to the corresponding property-changed handler. + FOR_EACH_OBSERVER( + BluetoothMediaTransportClient::Observer, observers_, + MediaTransportPropertyChanged(object_path, property_name)); + } + + // Called when a response for successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a response for |Acquire|/|TryAcquire| method call is received. + void OnAcquireSuccess(const AcquireCallback& callback, + const ErrorCallback& error_callback, + dbus::Response* response) { + DCHECK(response); + + dbus::FileDescriptor fd; + uint16_t read_mtu; + uint16_t write_mtu; + + // Parse the response. + dbus::MessageReader reader(response); + if (reader.PopFileDescriptor(&fd) && reader.PopUint16(&read_mtu) && + reader.PopUint16(&write_mtu)) { + fd.CheckValidity(); + DCHECK(fd.is_valid()); + + VLOG(1) << "OnAcquireSuccess - fd: " << fd.value() + << ", read MTU: " << read_mtu << ", write MTU: " << write_mtu; + + // The ownership of the file descriptor is transferred to the user + // application. + callback.Run(&fd, read_mtu, write_mtu); + return; + } + + error_callback.Run( + kUnexpectedResponse, + "Failed to retrieve file descriptor, read MTU and write MTU."); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + DCHECK(response); + + // Error response has optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + } + error_callback.Run(error_name, error_message); + } + + dbus::ObjectManager* object_manager_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothMediaTransportClient::Observer> observers_; + + base::WeakPtrFactory<BluetoothMediaTransportClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothMediaTransportClientImpl); +}; + +BluetoothMediaTransportClient::BluetoothMediaTransportClient() {} + +BluetoothMediaTransportClient::~BluetoothMediaTransportClient() {} + +BluetoothMediaTransportClient* BluetoothMediaTransportClient::Create() { + return new BluetoothMediaTransportClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_media_transport_client.h b/device/bluetooth/dbus/bluetooth_media_transport_client.h new file mode 100644 index 0000000..09c6ea0 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_media_transport_client.h @@ -0,0 +1,144 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "dbus/file_descriptor.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +class DEVICE_BLUETOOTH_EXPORT BluetoothMediaTransportClient + : public BluezDBusClient { + public: + struct Properties : public dbus::PropertySet { + // The path to the device object which the transport is connected to. + // Read-only. + dbus::Property<dbus::ObjectPath> device; + + // UUID of the profile which the transport is for. Read-only. + dbus::Property<std::string> uuid; + + // Assigned codec value supported by the media transport. Read-only. + dbus::Property<uint8_t> codec; + + // The configuration used by the media transport. Read-only. + dbus::Property<std::vector<uint8_t>> configuration; + + // The state of the transport. Read-only. + // The values can be one of the following: + // "idle": not streaming + // "pending": streaming but not acquired + // "active": streaming and acquired + dbus::Property<std::string> state; + + // The unit of transport delay is in 1/10 of millisecond. This property is + // only writeable when the transport was aquired by the sender. Optional. + dbus::Property<uint16_t> delay; + + // The volume level of the transport. This property is only writable when + // the transport was aquired by the sender. Optional. + dbus::Property<uint16_t> volume; + + Properties(dbus::ObjectProxy* object_proxy, + const std::string& interface_name, + const PropertyChangedCallback& callback); + ~Properties() override; + }; + + class Observer { + public: + virtual ~Observer() {} + + // Called when the Media Transport with object path |object_path| is added + // to the system. + virtual void MediaTransportAdded(const dbus::ObjectPath& object_path) {} + + // Called when the Media Transport with object path |object_path| is removed + // from the system. + virtual void MediaTransportRemoved(const dbus::ObjectPath& object_path) {} + + // Called when the Media Transport with object path |object_path| has + // a change in the value of the property with name |property_name|. + virtual void MediaTransportPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) {} + }; + + // TODO(mcchou): Move all static constants to service_constants.h. + // Constants used for the names of Media Transport's properties. + static const char kDeviceProperty[]; + static const char kUUIDProperty[]; + static const char kCodecProperty[]; + static const char kConfigurationProperty[]; + static const char kStateProperty[]; + static const char kDelayProperty[]; + static const char kVolumeProperty[]; + + // All possible states of a valid media transport object. + static const char kStateIdle[]; + static const char kStatePending[]; + static const char kStateActive[]; + + ~BluetoothMediaTransportClient() override; + + // The ErrorCallback is used by media transport API methods to indicate + // failure. It receives two arguments: the name of the error in |error_name| + // and an optional message in |error_message|. + typedef base::Callback<void(const std::string& error_name, + const std::string& error_message)> ErrorCallback; + + // The AcquireCallback is used by |Acquire| method of media tansport API tp + // indicate the success of the method. + typedef base::Callback<void(dbus::FileDescriptor* fd, + const uint16_t read_mtu, + const uint16_t write_mtu)> AcquireCallback; + + // Adds and removes observers for events on all remote Media Transports. Check + // the |object_path| parameter of observer methods to determine which Media + // Transport is issuing the event. + virtual void AddObserver(Observer* observer) = 0; + virtual void RemoveObserver(Observer* observer) = 0; + + virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0; + + // Acquires transport file descriptor and the MTU for read and write. + virtual void Acquire(const dbus::ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback) = 0; + + // Acquires transport file descriptor only if the transport is in "pending" + // state at the time the message is received by BlueZ. Otherwise no request + // will be sent to the remote device and the function will just fail with + // org.bluez.Error.NotAvailable. + virtual void TryAcquire(const dbus::ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback) = 0; + + // Releases the file descriptor of the transport. + virtual void Release(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + static BluetoothMediaTransportClient* Create(); + + protected: + BluetoothMediaTransportClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothMediaTransportClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_profile_manager_client.cc b/device/bluetooth/dbus/bluetooth_profile_manager_client.cc new file mode 100644 index 0000000..742988a --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_profile_manager_client.cc @@ -0,0 +1,234 @@ +// Copyright 2013 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 "device/bluetooth/dbus/bluetooth_profile_manager_client.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_proxy.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +const char BluetoothProfileManagerClient::kNoResponseError[] = + "org.chromium.Error.NoResponse"; + +BluetoothProfileManagerClient::Options::Options() {} + +BluetoothProfileManagerClient::Options::~Options() {} + +// The BluetoothProfileManagerClient implementation used in production. +class BluetoothProfileManagerClientImpl : public BluetoothProfileManagerClient { + public: + BluetoothProfileManagerClientImpl() : weak_ptr_factory_(this) {} + + ~BluetoothProfileManagerClientImpl() override {} + + // BluetoothProfileManagerClient override. + void RegisterProfile(const dbus::ObjectPath& profile_path, + const std::string& uuid, + const Options& options, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_profile_manager::kBluetoothProfileManagerInterface, + bluetooth_profile_manager::kRegisterProfile); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(profile_path); + writer.AppendString(uuid); + + dbus::MessageWriter array_writer(NULL); + writer.OpenArray("{sv}", &array_writer); + + dbus::MessageWriter dict_writer(NULL); + + // Send Name if provided. + if (options.name.get() != NULL) { + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString(bluetooth_profile_manager::kNameOption); + dict_writer.AppendVariantOfString(*(options.name)); + array_writer.CloseContainer(&dict_writer); + } + + // Send Service if provided. + if (options.service.get() != NULL) { + dbus::MessageWriter dict_writer(NULL); + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString(bluetooth_profile_manager::kServiceOption); + dict_writer.AppendVariantOfString(*(options.service)); + array_writer.CloseContainer(&dict_writer); + } + + // Send Role if not the default value. + if (options.role != SYMMETRIC) { + dbus::MessageWriter dict_writer(NULL); + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString(bluetooth_profile_manager::kRoleOption); + if (options.role == CLIENT) + dict_writer.AppendVariantOfString( + bluetooth_profile_manager::kClientRoleOption); + else if (options.role == SERVER) + dict_writer.AppendVariantOfString( + bluetooth_profile_manager::kServerRoleOption); + else + dict_writer.AppendVariantOfString(""); + array_writer.CloseContainer(&dict_writer); + } + + // Send Channel if provided. + if (options.channel.get() != NULL) { + dbus::MessageWriter dict_writer(NULL); + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString(bluetooth_profile_manager::kChannelOption); + dict_writer.AppendVariantOfUint16(*(options.channel)); + array_writer.CloseContainer(&dict_writer); + } + + // Send PSM if provided. + if (options.psm.get() != NULL) { + dbus::MessageWriter dict_writer(NULL); + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString(bluetooth_profile_manager::kPSMOption); + dict_writer.AppendVariantOfUint16(*(options.psm)); + array_writer.CloseContainer(&dict_writer); + } + + // Send RequireAuthentication if provided. + if (options.require_authentication.get() != NULL) { + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString( + bluetooth_profile_manager::kRequireAuthenticationOption); + dict_writer.AppendVariantOfBool(*(options.require_authentication)); + array_writer.CloseContainer(&dict_writer); + } + + // Send RequireAuthorization if provided. + if (options.require_authorization.get() != NULL) { + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString( + bluetooth_profile_manager::kRequireAuthorizationOption); + dict_writer.AppendVariantOfBool(*(options.require_authorization)); + array_writer.CloseContainer(&dict_writer); + } + + // Send AutoConnect if provided. + if (options.auto_connect.get() != NULL) { + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString(bluetooth_profile_manager::kAutoConnectOption); + dict_writer.AppendVariantOfBool(*(options.auto_connect)); + array_writer.CloseContainer(&dict_writer); + } + + // Send ServiceRecord if provided. + if (options.service_record.get() != NULL) { + dbus::MessageWriter dict_writer(NULL); + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString(bluetooth_profile_manager::kServiceRecordOption); + dict_writer.AppendVariantOfString(*(options.service_record)); + array_writer.CloseContainer(&dict_writer); + } + + // Send Version if provided. + if (options.version.get() != NULL) { + dbus::MessageWriter dict_writer(NULL); + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString(bluetooth_profile_manager::kVersionOption); + dict_writer.AppendVariantOfUint16(*(options.version)); + array_writer.CloseContainer(&dict_writer); + } + + // Send Features if provided. + if (options.features.get() != NULL) { + dbus::MessageWriter dict_writer(NULL); + array_writer.OpenDictEntry(&dict_writer); + dict_writer.AppendString(bluetooth_profile_manager::kFeaturesOption); + dict_writer.AppendVariantOfUint16(*(options.features)); + array_writer.CloseContainer(&dict_writer); + } + + writer.CloseContainer(&array_writer); + + object_proxy_->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothProfileManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothProfileManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + // BluetoothProfileManagerClient override. + void UnregisterProfile(const dbus::ObjectPath& profile_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override { + dbus::MethodCall method_call( + bluetooth_profile_manager::kBluetoothProfileManagerInterface, + bluetooth_profile_manager::kUnregisterProfile); + + dbus::MessageWriter writer(&method_call); + writer.AppendObjectPath(profile_path); + + object_proxy_->CallMethodWithErrorCallback( + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::Bind(&BluetoothProfileManagerClientImpl::OnSuccess, + weak_ptr_factory_.GetWeakPtr(), callback), + base::Bind(&BluetoothProfileManagerClientImpl::OnError, + weak_ptr_factory_.GetWeakPtr(), error_callback)); + } + + protected: + void Init(dbus::Bus* bus) override { + DCHECK(bus); + object_proxy_ = bus->GetObjectProxy( + bluetooth_profile_manager::kBluetoothProfileManagerServiceName, + dbus::ObjectPath( + bluetooth_profile_manager::kBluetoothProfileManagerServicePath)); + } + + private: + // Called when a response for successful method call is received. + void OnSuccess(const base::Closure& callback, dbus::Response* response) { + DCHECK(response); + callback.Run(); + } + + // Called when a response for a failed method call is received. + void OnError(const ErrorCallback& error_callback, + dbus::ErrorResponse* response) { + // Error response has optional error message argument. + std::string error_name; + std::string error_message; + if (response) { + dbus::MessageReader reader(response); + error_name = response->GetErrorName(); + reader.PopString(&error_message); + } else { + error_name = kNoResponseError; + error_message = ""; + } + error_callback.Run(error_name, error_message); + } + + dbus::ObjectProxy* object_proxy_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothProfileManagerClientImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothProfileManagerClientImpl); +}; + +BluetoothProfileManagerClient::BluetoothProfileManagerClient() {} + +BluetoothProfileManagerClient::~BluetoothProfileManagerClient() {} + +BluetoothProfileManagerClient* BluetoothProfileManagerClient::Create() { + return new BluetoothProfileManagerClientImpl(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_profile_manager_client.h b/device/bluetooth/dbus/bluetooth_profile_manager_client.h new file mode 100644 index 0000000..4b6bd96 --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_profile_manager_client.h @@ -0,0 +1,109 @@ +// Copyright 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluez_dbus_client.h" + +namespace bluez { + +// BluetoothProfileManagerClient is used to communicate with the profile +// manager object of the Bluetooth daemon. +class DEVICE_BLUETOOTH_EXPORT BluetoothProfileManagerClient + : public BluezDBusClient { + public: + // Species the role of the object within the profile. SYMMETRIC should be + // usually used unless the profile requires you specify as a CLIENT or as a + // SERVER. + enum ProfileRole { SYMMETRIC, CLIENT, SERVER }; + + // Options used to register a Profile object. + struct DEVICE_BLUETOOTH_EXPORT Options { + Options(); + ~Options(); + + // Human readable name for the profile. + scoped_ptr<std::string> name; + + // Primary service class UUID (if different from the actual UUID) + scoped_ptr<std::string> service; + + // Role. + enum ProfileRole role; + + // RFCOMM channel number. + scoped_ptr<uint16> channel; + + // PSM number. + scoped_ptr<uint16> psm; + + // Pairing is required before connections will be established. + scoped_ptr<bool> require_authentication; + + // Request authorization before connections will be established. + scoped_ptr<bool> require_authorization; + + // Force connections when a remote device is connected. + scoped_ptr<bool> auto_connect; + + // Manual SDP record. + scoped_ptr<std::string> service_record; + + // Profile version. + scoped_ptr<uint16> version; + + // Profile features. + scoped_ptr<uint16> features; + }; + + ~BluetoothProfileManagerClient() override; + + // The ErrorCallback is used by adapter methods to indicate failure. + // It receives two arguments: the name of the error in |error_name| and + // an optional message in |error_message|. + typedef base::Callback<void(const std::string& error_name, + const std::string& error_message)> ErrorCallback; + + // Registers a profile implementation within the local process at the + // D-bus object path |profile_path| with the remote profile manager. + // |uuid| specifies the identifier of the profile and |options| the way in + // which the profile is implemented. + virtual void RegisterProfile(const dbus::ObjectPath& profile_path, + const std::string& uuid, + const Options& options, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Unregisters the profile with the D-Bus object path |agent_path| from the + // remote profile manager. + virtual void UnregisterProfile(const dbus::ObjectPath& profile_path, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Creates the instance. + static BluetoothProfileManagerClient* Create(); + + // Constants used to indicate exceptional error conditions. + static const char kNoResponseError[]; + + protected: + BluetoothProfileManagerClient(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothProfileManagerClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluetooth_profile_service_provider.cc b/device/bluetooth/dbus/bluetooth_profile_service_provider.cc new file mode 100644 index 0000000..a2a23bb --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_profile_service_provider.cc @@ -0,0 +1,248 @@ +// Copyright 2013 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 "device/bluetooth/dbus/bluetooth_profile_service_provider.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/threading/platform_thread.h" +#include "dbus/exported_object.h" +#include "dbus/message.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +// The BluetoothProfileServiceProvider implementation used in production. +class BluetoothProfileServiceProviderImpl + : public BluetoothProfileServiceProvider { + public: + BluetoothProfileServiceProviderImpl(dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate) + : origin_thread_id_(base::PlatformThread::CurrentId()), + bus_(bus), + delegate_(delegate), + object_path_(object_path), + weak_ptr_factory_(this) { + VLOG(1) << "Creating Bluetooth Profile: " << object_path_.value(); + + exported_object_ = bus_->GetExportedObject(object_path_); + + exported_object_->ExportMethod( + bluetooth_profile::kBluetoothProfileInterface, + bluetooth_profile::kRelease, + base::Bind(&BluetoothProfileServiceProviderImpl::Release, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothProfileServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_profile::kBluetoothProfileInterface, + bluetooth_profile::kNewConnection, + base::Bind(&BluetoothProfileServiceProviderImpl::NewConnection, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothProfileServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_profile::kBluetoothProfileInterface, + bluetooth_profile::kRequestDisconnection, + base::Bind(&BluetoothProfileServiceProviderImpl::RequestDisconnection, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothProfileServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + + exported_object_->ExportMethod( + bluetooth_profile::kBluetoothProfileInterface, + bluetooth_profile::kCancel, + base::Bind(&BluetoothProfileServiceProviderImpl::Cancel, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&BluetoothProfileServiceProviderImpl::OnExported, + weak_ptr_factory_.GetWeakPtr())); + } + + ~BluetoothProfileServiceProviderImpl() override { + VLOG(1) << "Cleaning up Bluetooth Profile: " << object_path_.value(); + + // Unregister the object path so we can reuse with a new agent. + bus_->UnregisterExportedObject(object_path_); + } + + private: + // Returns true if the current thread is on the origin thread. + bool OnOriginThread() { + return base::PlatformThread::CurrentId() == origin_thread_id_; + } + + // Called by dbus:: when the profile is unregistered from the Bluetooth + // daemon, generally by our request. + void Release(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + delegate_->Released(); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when the Bluetooth daemon establishes a new connection + // to the profile. + void NewConnection(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + scoped_ptr<dbus::FileDescriptor> fd(new dbus::FileDescriptor()); + dbus::MessageReader array_reader(NULL); + if (!reader.PopObjectPath(&device_path) || + !reader.PopFileDescriptor(fd.get()) || + !reader.PopArray(&array_reader)) { + LOG(WARNING) << "NewConnection called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::Options options; + while (array_reader.HasMoreData()) { + dbus::MessageReader dict_entry_reader(NULL); + std::string key; + if (!array_reader.PopDictEntry(&dict_entry_reader) || + !dict_entry_reader.PopString(&key)) { + LOG(WARNING) << "NewConnection called with incorrect paramters: " + << method_call->ToString(); + } else { + if (key == bluetooth_profile::kVersionProperty) + dict_entry_reader.PopVariantOfUint16(&options.version); + else if (key == bluetooth_profile::kFeaturesProperty) + dict_entry_reader.PopVariantOfUint16(&options.features); + } + } + + Delegate::ConfirmationCallback callback = base::Bind( + &BluetoothProfileServiceProviderImpl::OnConfirmation, + weak_ptr_factory_.GetWeakPtr(), method_call, response_sender); + + delegate_->NewConnection(device_path, fd.Pass(), options, callback); + } + + // Called by dbus:: when the Bluetooth daemon is about to disconnect the + // profile. + void RequestDisconnection( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + dbus::MessageReader reader(method_call); + dbus::ObjectPath device_path; + if (!reader.PopObjectPath(&device_path)) { + LOG(WARNING) << "RequestDisconnection called with incorrect paramters: " + << method_call->ToString(); + return; + } + + Delegate::ConfirmationCallback callback = base::Bind( + &BluetoothProfileServiceProviderImpl::OnConfirmation, + weak_ptr_factory_.GetWeakPtr(), method_call, response_sender); + + delegate_->RequestDisconnection(device_path, callback); + } + + // Called by dbus:: when the request failed before a reply was returned + // from the device. + void Cancel(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + DCHECK(OnOriginThread()); + DCHECK(delegate_); + + delegate_->Cancel(); + + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + } + + // Called by dbus:: when a method is exported. + void OnExported(const std::string& interface_name, + const std::string& method_name, + bool success) { + LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "." + << method_name; + } + + // Called by the Delegate in response to a method requiring confirmation. + void OnConfirmation(dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender, + Delegate::Status status) { + DCHECK(OnOriginThread()); + + switch (status) { + case Delegate::SUCCESS: { + response_sender.Run(dbus::Response::FromMethodCall(method_call)); + break; + } + case Delegate::REJECTED: { + response_sender.Run(dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_profile::kErrorRejected, "rejected")); + break; + } + case Delegate::CANCELLED: { + response_sender.Run(dbus::ErrorResponse::FromMethodCall( + method_call, bluetooth_profile::kErrorCanceled, "canceled")); + break; + } + default: + NOTREACHED() << "Unexpected status code from delegate: " << status; + } + } + + // Origin thread (i.e. the UI thread in production). + base::PlatformThreadId origin_thread_id_; + + // D-Bus bus object is exported on, not owned by this object and must + // outlive it. + dbus::Bus* bus_; + + // All incoming method calls are passed on to the Delegate and a callback + // passed to generate the reply. |delegate_| is generally the object that + // owns this one, and must outlive it. + Delegate* delegate_; + + // D-Bus object path of object we are exporting, kept so we can unregister + // again in our destructor. + dbus::ObjectPath object_path_; + + // D-Bus object we are exporting, owned by this object. + scoped_refptr<dbus::ExportedObject> exported_object_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<BluetoothProfileServiceProviderImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothProfileServiceProviderImpl); +}; + +BluetoothProfileServiceProvider::BluetoothProfileServiceProvider() {} + +BluetoothProfileServiceProvider::~BluetoothProfileServiceProvider() {} + +// static +BluetoothProfileServiceProvider* BluetoothProfileServiceProvider::Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate) { + if (!bluez::BluezDBusManager::Get()->IsUsingStub()) { + return new BluetoothProfileServiceProviderImpl(bus, object_path, delegate); + } else { + return new FakeBluetoothProfileServiceProvider(object_path, delegate); + } +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluetooth_profile_service_provider.h b/device/bluetooth/dbus/bluetooth_profile_service_provider.h new file mode 100644 index 0000000..f2db22c --- /dev/null +++ b/device/bluetooth/dbus/bluetooth_profile_service_provider.h @@ -0,0 +1,120 @@ +// Copyright 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/memory/scoped_ptr.h" +#include "dbus/bus.h" +#include "dbus/file_descriptor.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" + +namespace bluez { + +// BluetoothProfileServiceProvider is used to provide a D-Bus object that the +// Bluetooth daemon can communicate with to connect application profiles. +// +// Instantiate with a chosen D-Bus object path and delegate object, and pass +// the D-Bus object path as the |agent_path| argument to the +// chromeos::BluetoothProfileManagerClient::RegisterProfile() method. +// +// When an incoming profile connection occurs, or after initiating a connection +// using the chromeos::BluetoothDeviceClient::ConnectProfile() method, the +// Bluetooth daemon will make calls to this profile object and they will be +// passed on to your Delegate object for handling. Responses should be returned +// using the callbacks supplied to those methods. +class DEVICE_BLUETOOTH_EXPORT BluetoothProfileServiceProvider { + public: + // Interface for reacting to profile requests. + class Delegate { + public: + virtual ~Delegate() {} + + // Possible status values that may be returned to callbacks on a new + // connection or a requested disconnection. Success indicates acceptance, + // reject indicates the user rejected or denied the request; cancelled + // means the user cancelled the request without confirming either way. + enum Status { SUCCESS, REJECTED, CANCELLED }; + + // Connection-specific options. + struct DEVICE_BLUETOOTH_EXPORT Options { + Options() {} + ~Options() {} + + // Profile version. + uint16 version; + + // Profile features. + uint16 features; + }; + + // The ConfirmationCallback is used for methods which require confirmation; + // it should be called with one argument, the |status| of the request + // (success, rejected or cancelled). + typedef base::Callback<void(Status)> ConfirmationCallback; + + // This method will be called when the profile is unregistered from the + // Bluetooth daemon, generally at shutdown or at the applications' request. + // It may be used to perform cleanup tasks. This corresponds to the + // org.bluez.Profile1.Release method and is renamed to avoid a conflict + // with base::Refcounted<T>. + virtual void Released() = 0; + + // This method will be called when a profile connection to the device + // with object path |device_path| is established. |callback| must be called + // to confirm the connection, or indicate rejection or cancellation. + // + // A file descriptor for the connection socket is provided in |fd|, and + // details about the specific implementation of the profile in |options|. + // + // IMPORTANT: Ownership of the file descriptor object |fd| is passed to + // the delegate by this call. The delegate is responsible for checking the + // validity of |fd| on a thread where I/O is permitted before taking the + // value. If the value is not taken, the file descriptor is closed. + // + // Ownership of |options| is NOT passed so information out of it must be + // copied if required. + virtual void NewConnection(const dbus::ObjectPath& device_path, + scoped_ptr<dbus::FileDescriptor> fd, + const Options& options, + const ConfirmationCallback& callback) = 0; + + // This method will be called when a profile connection to the device + // with object path |device_path| is disconnected. Any file descriptors + // owned by the service should be cleaned up and |callback| called to + // confirm, or indicate rejection or cancellation of the disconnection. + virtual void RequestDisconnection(const dbus::ObjectPath& device_path, + const ConfirmationCallback& callback) = 0; + + // This method will be called by the Bluetooth daemon to indicate that + // a profile request failed before a reply was returned from the device. + virtual void Cancel() = 0; + }; + + virtual ~BluetoothProfileServiceProvider(); + + // Creates the instance where |bus| is the D-Bus bus connection to export + // the object onto, |object_path| is the object path that it should have + // and |delegate| is the object to which all method calls will be passed + // and responses generated from. + static BluetoothProfileServiceProvider* Create( + dbus::Bus* bus, + const dbus::ObjectPath& object_path, + Delegate* delegate); + + protected: + BluetoothProfileServiceProvider(); + + private: + DISALLOW_COPY_AND_ASSIGN(BluetoothProfileServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/bluez_dbus_client.h b/device/bluetooth/dbus/bluez_dbus_client.h new file mode 100644 index 0000000..3dd0985 --- /dev/null +++ b/device/bluetooth/dbus/bluez_dbus_client.h @@ -0,0 +1,37 @@ +// Copyright 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_CLIENT_H_ + +#include "base/basictypes.h" + +namespace dbus { +class Bus; +} // namespace dbus + +namespace bluez { + +// Interface for all Bluez DBus clients handled by BluezDBusManager. It +// restricts +// access to the Init function to BluezDBusManager only to prevent +// incorrect calls. Stub clients may lift that restriction however. +class BluezDBusClient { + protected: + virtual ~BluezDBusClient() {} + + // This function is called by DBusThreadManager. Only in unit tests, which + // don't use DBusThreadManager, this function can be called through Stub + // implementations (they change Init's member visibility to public). + virtual void Init(dbus::Bus* bus) = 0; + + private: + friend class BluezDBusManager; + + DISALLOW_ASSIGN(BluezDBusClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_CLIENT_H_ diff --git a/device/bluetooth/dbus/bluez_dbus_manager.cc b/device/bluetooth/dbus/bluez_dbus_manager.cc new file mode 100644 index 0000000..376261d --- /dev/null +++ b/device/bluetooth/dbus/bluez_dbus_manager.cc @@ -0,0 +1,250 @@ +// 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 "device/bluetooth/dbus/bluez_dbus_manager.h" + +#include "base/command_line.h" +#include "base/sys_info.h" +#include "base/threading/thread.h" +#include "dbus/bus.h" +#include "dbus/dbus_statistics.h" +#include "device/bluetooth/dbus/bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_device_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h" +#include "device/bluetooth/dbus/bluetooth_input_client.h" +#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h" +#include "device/bluetooth/dbus/bluetooth_media_client.h" +#include "device/bluetooth/dbus/bluetooth_media_transport_client.h" +#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" + +namespace bluez { + +static BluezDBusManager* g_bluez_dbus_manager = nullptr; +static bool g_using_bluez_dbus_manager_for_testing = false; + +BluezDBusManager::BluezDBusManager( + dbus::Bus* bus, + scoped_ptr<BluetoothDBusClientBundle> client_bundle) + : bus_(bus), client_bundle_(client_bundle.Pass()) {} + +BluezDBusManager::~BluezDBusManager() { + // Delete all D-Bus clients before shutting down the system bus. + client_bundle_.reset(); +} + +dbus::Bus* bluez::BluezDBusManager::GetSystemBus() { + return bus_; +} + +BluetoothAdapterClient* bluez::BluezDBusManager::GetBluetoothAdapterClient() { + return client_bundle_->bluetooth_adapter_client(); +} + +BluetoothLEAdvertisingManagerClient* +bluez::BluezDBusManager::GetBluetoothLEAdvertisingManagerClient() { + return client_bundle_->bluetooth_le_advertising_manager_client(); +} + +BluetoothAgentManagerClient* +bluez::BluezDBusManager::GetBluetoothAgentManagerClient() { + return client_bundle_->bluetooth_agent_manager_client(); +} + +BluetoothDeviceClient* bluez::BluezDBusManager::GetBluetoothDeviceClient() { + return client_bundle_->bluetooth_device_client(); +} + +BluetoothGattCharacteristicClient* +bluez::BluezDBusManager::GetBluetoothGattCharacteristicClient() { + return client_bundle_->bluetooth_gatt_characteristic_client(); +} + +BluetoothGattDescriptorClient* +bluez::BluezDBusManager::GetBluetoothGattDescriptorClient() { + return client_bundle_->bluetooth_gatt_descriptor_client(); +} + +BluetoothGattManagerClient* +bluez::BluezDBusManager::GetBluetoothGattManagerClient() { + return client_bundle_->bluetooth_gatt_manager_client(); +} + +BluetoothGattServiceClient* +bluez::BluezDBusManager::GetBluetoothGattServiceClient() { + return client_bundle_->bluetooth_gatt_service_client(); +} + +BluetoothInputClient* bluez::BluezDBusManager::GetBluetoothInputClient() { + return client_bundle_->bluetooth_input_client(); +} + +BluetoothMediaClient* bluez::BluezDBusManager::GetBluetoothMediaClient() { + return client_bundle_->bluetooth_media_client(); +} + +BluetoothMediaTransportClient* +bluez::BluezDBusManager::GetBluetoothMediaTransportClient() { + return client_bundle_->bluetooth_media_transport_client(); +} + +BluetoothProfileManagerClient* +bluez::BluezDBusManager::GetBluetoothProfileManagerClient() { + return client_bundle_->bluetooth_profile_manager_client(); +} + +void BluezDBusManager::InitializeClients() { + GetBluetoothAdapterClient()->Init(GetSystemBus()); + GetBluetoothAgentManagerClient()->Init(GetSystemBus()); + GetBluetoothDeviceClient()->Init(GetSystemBus()); + GetBluetoothGattCharacteristicClient()->Init(GetSystemBus()); + GetBluetoothGattDescriptorClient()->Init(GetSystemBus()); + GetBluetoothGattManagerClient()->Init(GetSystemBus()); + GetBluetoothGattServiceClient()->Init(GetSystemBus()); + GetBluetoothInputClient()->Init(GetSystemBus()); + GetBluetoothLEAdvertisingManagerClient()->Init(GetSystemBus()); + GetBluetoothMediaClient()->Init(GetSystemBus()); + GetBluetoothMediaTransportClient()->Init(GetSystemBus()); + GetBluetoothProfileManagerClient()->Init(GetSystemBus()); + + // This must be called after the list of clients so they've each had a + // chance to register with their object g_dbus_thread_managers. + if (GetSystemBus()) + GetSystemBus()->GetManagedObjects(); +} + +// static +void BluezDBusManager::Initialize(dbus::Bus* bus, bool use_dbus_stub) { + // If we initialize BluezDBusManager twice we may also be shutting it down + // early; do not allow that. + if (g_using_bluez_dbus_manager_for_testing) + return; + + CHECK(!g_bluez_dbus_manager); + CreateGlobalInstance(bus, use_dbus_stub); +} + +// static +scoped_ptr<BluezDBusManagerSetter> +bluez::BluezDBusManager::GetSetterForTesting() { + if (!g_using_bluez_dbus_manager_for_testing) { + g_using_bluez_dbus_manager_for_testing = true; + CreateGlobalInstance(nullptr, true); + } + + return make_scoped_ptr(new BluezDBusManagerSetter()); +} + +// static +void BluezDBusManager::CreateGlobalInstance(dbus::Bus* bus, bool use_stubs) { + CHECK(!g_bluez_dbus_manager); + g_bluez_dbus_manager = new BluezDBusManager( + bus, make_scoped_ptr(new BluetoothDBusClientBundle(use_stubs))); + g_bluez_dbus_manager->InitializeClients(); +} + +// static +bool BluezDBusManager::IsInitialized() { + return g_bluez_dbus_manager != nullptr; +} + +// static +void BluezDBusManager::Shutdown() { + // Ensure that we only shutdown BluezDBusManager once. + CHECK(g_bluez_dbus_manager); + BluezDBusManager* dbus_manager = g_bluez_dbus_manager; + g_bluez_dbus_manager = nullptr; + g_using_bluez_dbus_manager_for_testing = false; + delete dbus_manager; + VLOG(1) << "BluezDBusManager Shutdown completed"; +} + +// static +BluezDBusManager* bluez::BluezDBusManager::Get() { + CHECK(g_bluez_dbus_manager) + << "bluez::BluezDBusManager::Get() called before Initialize()"; + return g_bluez_dbus_manager; +} + +BluezDBusManagerSetter::BluezDBusManagerSetter() {} + +BluezDBusManagerSetter::~BluezDBusManagerSetter() {} + +void BluezDBusManagerSetter::SetBluetoothAdapterClient( + scoped_ptr<BluetoothAdapterClient> client) { + bluez::BluezDBusManager::Get()->client_bundle_->bluetooth_adapter_client_ = + client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothLEAdvertisingManagerClient( + scoped_ptr<BluetoothLEAdvertisingManagerClient> client) { + bluez::BluezDBusManager::Get() + ->client_bundle_->bluetooth_le_advertising_manager_client_ = + client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothAgentManagerClient( + scoped_ptr<BluetoothAgentManagerClient> client) { + bluez::BluezDBusManager::Get() + ->client_bundle_->bluetooth_agent_manager_client_ = client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothDeviceClient( + scoped_ptr<BluetoothDeviceClient> client) { + bluez::BluezDBusManager::Get()->client_bundle_->bluetooth_device_client_ = + client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothGattCharacteristicClient( + scoped_ptr<BluetoothGattCharacteristicClient> client) { + bluez::BluezDBusManager::Get() + ->client_bundle_->bluetooth_gatt_characteristic_client_ = client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothGattDescriptorClient( + scoped_ptr<BluetoothGattDescriptorClient> client) { + bluez::BluezDBusManager::Get() + ->client_bundle_->bluetooth_gatt_descriptor_client_ = client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothGattManagerClient( + scoped_ptr<BluetoothGattManagerClient> client) { + bluez::BluezDBusManager::Get() + ->client_bundle_->bluetooth_gatt_manager_client_ = client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothGattServiceClient( + scoped_ptr<BluetoothGattServiceClient> client) { + bluez::BluezDBusManager::Get() + ->client_bundle_->bluetooth_gatt_service_client_ = client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothInputClient( + scoped_ptr<BluetoothInputClient> client) { + bluez::BluezDBusManager::Get()->client_bundle_->bluetooth_input_client_ = + client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothMediaClient( + scoped_ptr<BluetoothMediaClient> client) { + bluez::BluezDBusManager::Get()->client_bundle_->bluetooth_media_client_ = + client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothMediaTransportClient( + scoped_ptr<BluetoothMediaTransportClient> client) { + bluez::BluezDBusManager::Get() + ->client_bundle_->bluetooth_media_transport_client_ = client.Pass(); +} + +void BluezDBusManagerSetter::SetBluetoothProfileManagerClient( + scoped_ptr<BluetoothProfileManagerClient> client) { + bluez::BluezDBusManager::Get() + ->client_bundle_->bluetooth_profile_manager_client_ = client.Pass(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/bluez_dbus_manager.h b/device/bluetooth/dbus/bluez_dbus_manager.h new file mode 100644 index 0000000..d87fadc --- /dev/null +++ b/device/bluetooth/dbus/bluez_dbus_manager.h @@ -0,0 +1,158 @@ +// 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_MANAGER_H_ +#define DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_MANAGER_H_ + +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_dbus_client_bundle.h" + +namespace dbus { +class Bus; +class ObjectPath; +} // namespace dbus + +namespace bluez { + +// Style Note: Clients are sorted by names. +class BluetoothAdapterClient; +class BluetoothAgentManagerClient; +class BluetoothDeviceClient; +class BluetoothGattCharacteristicClient; +class BluetoothGattDescriptorClient; +class BluetoothGattManagerClient; +class BluetoothGattServiceClient; +class BluetoothInputClient; +class BluetoothLEAdvertisingManagerClient; +class BluetoothMediaClient; +class BluetoothMediaTransportClient; +class BluetoothProfileManagerClient; +class BluezDBusManagerSetter; + +// BluezDBusManager manages manages D-Bus connections and D-Bus clients, which +// depend on the D-Bus thread to ensure the right order of shutdowns for +// the D-Bus thread, the D-Bus connections, and the D-Bus clients. +// +// CALLBACKS IN D-BUS CLIENTS: +// +// D-Bus clients managed by BluezDBusManagerSetter are guaranteed to be deleted +// after the D-Bus thread so the clients don't need to worry if new +// incoming messages arrive from the D-Bus thread during shutdown of the +// clients. The UI message loop is not running during the shutdown hence +// the UI message loop won't post tasks to D-BUS clients during the +// shutdown. However, to be extra cautious, clients should use +// WeakPtrFactory when creating callbacks that run on UI thread. See +// session_manager_client.cc for examples. +// +class DEVICE_BLUETOOTH_EXPORT BluezDBusManager { + public: + // Sets the global instance. Must be called before any calls to Get(). + // We explicitly initialize and shut down the global object, rather than + // making it a Singleton, to ensure clean startup and shutdown. + // This will initialize real or stub DBusClients depending on command-line + // arguments and whether this process runs in a ChromeOS environment. + static void Initialize(dbus::Bus* bus, bool use_dbus_stub); + + // Returns a BluezDBusManagerSetter instance that allows tests to + // replace individual D-Bus clients with their own implementations. + // Also initializes the main BluezDBusManager for testing if necessary. + static scoped_ptr<BluezDBusManagerSetter> GetSetterForTesting(); + + // Returns true if BluezDBusManager has been initialized. Call this to + // avoid initializing + shutting down BluezDBusManager more than once. + static bool IsInitialized(); + + // Destroys the global instance. + static void Shutdown(); + + // Gets the global instance. Initialize() must be called first. + static BluezDBusManager* Get(); + + // Returns true if |client| is stubbed. + bool IsUsingStub() { return client_bundle_->IsUsingStub(); } + + // Returns various D-Bus bus instances, owned by BluezDBusManager. + dbus::Bus* GetSystemBus(); + + // All returned objects are owned by BluezDBusManager. Do not use these + // pointers after BluezDBusManager has been shut down. + BluetoothAdapterClient* GetBluetoothAdapterClient(); + BluetoothLEAdvertisingManagerClient* GetBluetoothLEAdvertisingManagerClient(); + BluetoothAgentManagerClient* GetBluetoothAgentManagerClient(); + BluetoothDeviceClient* GetBluetoothDeviceClient(); + BluetoothGattCharacteristicClient* GetBluetoothGattCharacteristicClient(); + BluetoothGattDescriptorClient* GetBluetoothGattDescriptorClient(); + BluetoothGattManagerClient* GetBluetoothGattManagerClient(); + BluetoothGattServiceClient* GetBluetoothGattServiceClient(); + BluetoothInputClient* GetBluetoothInputClient(); + BluetoothMediaClient* GetBluetoothMediaClient(); + BluetoothMediaTransportClient* GetBluetoothMediaTransportClient(); + BluetoothProfileManagerClient* GetBluetoothProfileManagerClient(); + + private: + friend class BluezDBusManagerSetter; + + // Creates a new BluezDBusManager using the DBusClients set in + // |client_bundle|. + explicit BluezDBusManager( + dbus::Bus* bus, + scoped_ptr<BluetoothDBusClientBundle> client_bundle); + ~BluezDBusManager(); + + // Creates a global instance of BluezDBusManager. Cannot be called more than + // once. + static void CreateGlobalInstance(dbus::Bus* bus, bool use_stubs); + + // Initializes all currently stored DBusClients with the system bus and + // performs additional setup. + void InitializeClients(); + + dbus::Bus* bus_; + scoped_ptr<BluetoothDBusClientBundle> client_bundle_; + + DISALLOW_COPY_AND_ASSIGN(BluezDBusManager); +}; + +class DEVICE_BLUETOOTH_EXPORT BluezDBusManagerSetter { + public: + ~BluezDBusManagerSetter(); + + void SetBluetoothAdapterClient(scoped_ptr<BluetoothAdapterClient> client); + void SetBluetoothLEAdvertisingManagerClient( + scoped_ptr<BluetoothLEAdvertisingManagerClient> client); + void SetBluetoothAgentManagerClient( + scoped_ptr<BluetoothAgentManagerClient> client); + void SetBluetoothDeviceClient(scoped_ptr<BluetoothDeviceClient> client); + void SetBluetoothGattCharacteristicClient( + scoped_ptr<BluetoothGattCharacteristicClient> client); + void SetBluetoothGattDescriptorClient( + scoped_ptr<BluetoothGattDescriptorClient> client); + void SetBluetoothGattManagerClient( + scoped_ptr<BluetoothGattManagerClient> client); + void SetBluetoothGattServiceClient( + scoped_ptr<BluetoothGattServiceClient> client); + void SetBluetoothInputClient(scoped_ptr<BluetoothInputClient> client); + void SetBluetoothMediaClient(scoped_ptr<BluetoothMediaClient> client); + void SetBluetoothMediaTransportClient( + scoped_ptr<BluetoothMediaTransportClient> client); + void SetBluetoothProfileManagerClient( + scoped_ptr<BluetoothProfileManagerClient> client); + + private: + friend class BluezDBusManager; + + BluezDBusManagerSetter(); + + DISALLOW_COPY_AND_ASSIGN(BluezDBusManagerSetter); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_BLUEZ_DBUS_MANAGER_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_adapter_client.cc b/device/bluetooth/dbus/fake_bluetooth_adapter_client.cc new file mode 100644 index 0000000..f928768 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_adapter_client.cc @@ -0,0 +1,296 @@ +// Copyright (c) 2013 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 "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" + +#include "base/location.h" +#include "base/logging.h" +#include "base/single_thread_task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_device_client.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +namespace { + +// Default interval for delayed tasks. +const int kSimulationIntervalMs = 750; + +} // namespace + +const char FakeBluetoothAdapterClient::kAdapterPath[] = "/fake/hci0"; +const char FakeBluetoothAdapterClient::kAdapterName[] = "Fake Adapter"; +const char FakeBluetoothAdapterClient::kAdapterAddress[] = "01:1A:2B:1A:2B:03"; + +const char FakeBluetoothAdapterClient::kSecondAdapterPath[] = "/fake/hci1"; +const char FakeBluetoothAdapterClient::kSecondAdapterName[] = + "Second Fake Adapter"; +const char FakeBluetoothAdapterClient::kSecondAdapterAddress[] = + "00:DE:51:10:01:00"; + +FakeBluetoothAdapterClient::Properties::Properties( + const PropertyChangedCallback& callback) + : BluetoothAdapterClient::Properties( + NULL, + bluetooth_adapter::kBluetoothAdapterInterface, + callback) {} + +FakeBluetoothAdapterClient::Properties::~Properties() {} + +void FakeBluetoothAdapterClient::Properties::Get( + dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) { + VLOG(1) << "Get " << property->name(); + callback.Run(false); +} + +void FakeBluetoothAdapterClient::Properties::GetAll() { + VLOG(1) << "GetAll"; +} + +void FakeBluetoothAdapterClient::Properties::Set( + dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) { + VLOG(1) << "Set " << property->name(); + if (property->name() == powered.name() || property->name() == alias.name() || + property->name() == discoverable.name() || + property->name() == discoverable_timeout.name()) { + callback.Run(true); + property->ReplaceValueWithSetValue(); + } else { + callback.Run(false); + } +} + +FakeBluetoothAdapterClient::FakeBluetoothAdapterClient() + : visible_(true), + second_visible_(false), + discovering_count_(0), + set_discovery_filter_should_fail_(false), + simulation_interval_ms_(kSimulationIntervalMs) { + properties_.reset(new Properties(base::Bind( + &FakeBluetoothAdapterClient::OnPropertyChanged, base::Unretained(this)))); + + properties_->address.ReplaceValue(kAdapterAddress); + properties_->name.ReplaceValue("Fake Adapter (Name)"); + properties_->alias.ReplaceValue(kAdapterName); + properties_->pairable.ReplaceValue(true); + + second_properties_.reset(new Properties(base::Bind( + &FakeBluetoothAdapterClient::OnPropertyChanged, base::Unretained(this)))); + + second_properties_->address.ReplaceValue(kSecondAdapterAddress); + second_properties_->name.ReplaceValue("Second Fake Adapter (Name)"); + second_properties_->alias.ReplaceValue(kSecondAdapterName); + second_properties_->pairable.ReplaceValue(true); +} + +FakeBluetoothAdapterClient::~FakeBluetoothAdapterClient() {} + +void FakeBluetoothAdapterClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothAdapterClient::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeBluetoothAdapterClient::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +std::vector<dbus::ObjectPath> FakeBluetoothAdapterClient::GetAdapters() { + std::vector<dbus::ObjectPath> object_paths; + if (visible_) + object_paths.push_back(dbus::ObjectPath(kAdapterPath)); + if (second_visible_) + object_paths.push_back(dbus::ObjectPath(kSecondAdapterPath)); + return object_paths; +} + +FakeBluetoothAdapterClient::Properties* +FakeBluetoothAdapterClient::GetProperties(const dbus::ObjectPath& object_path) { + if (object_path == dbus::ObjectPath(kAdapterPath)) + return properties_.get(); + else if (object_path == dbus::ObjectPath(kSecondAdapterPath)) + return second_properties_.get(); + else + return NULL; +} + +void FakeBluetoothAdapterClient::StartDiscovery( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (object_path != dbus::ObjectPath(kAdapterPath)) { + PostDelayedTask(base::Bind(error_callback, kNoResponseError, "")); + return; + } + + ++discovering_count_; + VLOG(1) << "StartDiscovery: " << object_path.value() << ", " + << "count is now " << discovering_count_; + PostDelayedTask(callback); + + if (discovering_count_ == 1) { + properties_->discovering.ReplaceValue(true); + + FakeBluetoothDeviceClient* device_client = + static_cast<FakeBluetoothDeviceClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()); + device_client->BeginDiscoverySimulation(dbus::ObjectPath(kAdapterPath)); + } +} + +void FakeBluetoothAdapterClient::StopDiscovery( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (object_path != dbus::ObjectPath(kAdapterPath)) { + PostDelayedTask(base::Bind(error_callback, kNoResponseError, "")); + return; + } + + if (!discovering_count_) { + LOG(WARNING) << "StopDiscovery called when not discovering"; + PostDelayedTask(base::Bind(error_callback, kNoResponseError, "")); + return; + } + + --discovering_count_; + VLOG(1) << "StopDiscovery: " << object_path.value() << ", " + << "count is now " << discovering_count_; + PostDelayedTask(callback); + + if (discovering_count_ == 0) { + FakeBluetoothDeviceClient* device_client = + static_cast<FakeBluetoothDeviceClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()); + device_client->EndDiscoverySimulation(dbus::ObjectPath(kAdapterPath)); + + if (simulation_interval_ms_ > 100) { + device_client->BeginIncomingPairingSimulation( + dbus::ObjectPath(kAdapterPath)); + } + + discovery_filter_.reset(); + properties_->discovering.ReplaceValue(false); + } +} + +void FakeBluetoothAdapterClient::RemoveDevice( + const dbus::ObjectPath& object_path, + const dbus::ObjectPath& device_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (object_path != dbus::ObjectPath(kAdapterPath)) { + error_callback.Run(kNoResponseError, ""); + return; + } + + VLOG(1) << "RemoveDevice: " << object_path.value() << " " + << device_path.value(); + callback.Run(); + + FakeBluetoothDeviceClient* device_client = + static_cast<FakeBluetoothDeviceClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient()); + device_client->RemoveDevice(dbus::ObjectPath(kAdapterPath), device_path); +} + +void FakeBluetoothAdapterClient::MakeSetDiscoveryFilterFail() { + set_discovery_filter_should_fail_ = true; +} + +void FakeBluetoothAdapterClient::SetDiscoveryFilter( + const dbus::ObjectPath& object_path, + const DiscoveryFilter& discovery_filter, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (object_path != dbus::ObjectPath(kAdapterPath)) { + PostDelayedTask(base::Bind(error_callback, kNoResponseError, "")); + return; + } + VLOG(1) << "SetDiscoveryFilter: " << object_path.value(); + + if (set_discovery_filter_should_fail_) { + PostDelayedTask(base::Bind(error_callback, kNoResponseError, "")); + set_discovery_filter_should_fail_ = false; + return; + } + + discovery_filter_.reset(new DiscoveryFilter()); + discovery_filter_->CopyFrom(discovery_filter); + PostDelayedTask(callback); +} + +void FakeBluetoothAdapterClient::SetSimulationIntervalMs(int interval_ms) { + simulation_interval_ms_ = interval_ms; +} + +BluetoothAdapterClient::DiscoveryFilter* +FakeBluetoothAdapterClient::GetDiscoveryFilter() { + return discovery_filter_.get(); +} + +void FakeBluetoothAdapterClient::SetVisible(bool visible) { + if (visible && !visible_) { + // Adapter becoming visible + visible_ = visible; + + FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, + AdapterAdded(dbus::ObjectPath(kAdapterPath))); + + } else if (visible_ && !visible) { + // Adapter becoming invisible + visible_ = visible; + + FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, + AdapterRemoved(dbus::ObjectPath(kAdapterPath))); + } +} + +void FakeBluetoothAdapterClient::SetSecondVisible(bool visible) { + if (visible && !second_visible_) { + // Second adapter becoming visible + second_visible_ = visible; + + FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, + AdapterAdded(dbus::ObjectPath(kSecondAdapterPath))); + + } else if (second_visible_ && !visible) { + // Second adapter becoming invisible + second_visible_ = visible; + + FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, + AdapterRemoved(dbus::ObjectPath(kSecondAdapterPath))); + } +} + +void FakeBluetoothAdapterClient::OnPropertyChanged( + const std::string& property_name) { + if (property_name == properties_->powered.name() && + !properties_->powered.value()) { + VLOG(1) << "Adapter powered off"; + + if (discovering_count_) { + discovering_count_ = 0; + properties_->discovering.ReplaceValue(false); + } + } + + FOR_EACH_OBSERVER( + BluetoothAdapterClient::Observer, observers_, + AdapterPropertyChanged(dbus::ObjectPath(kAdapterPath), property_name)); +} + +void FakeBluetoothAdapterClient::PostDelayedTask( + const base::Closure& callback) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, callback, + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_adapter_client.h b/device/bluetooth/dbus/fake_bluetooth_adapter_client.h new file mode 100644 index 0000000..0dced89 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_adapter_client.h @@ -0,0 +1,118 @@ +// Copyright (c) 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_ADAPTER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_ADAPTER_CLIENT_H_ + +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_adapter_client.h" + +namespace bluez { + +// FakeBluetoothAdapterClient simulates the behavior of the Bluetooth Daemon +// adapter objects and is used both in test cases in place of a mock and on +// the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothAdapterClient + : public BluetoothAdapterClient { + public: + struct Properties : public BluetoothAdapterClient::Properties { + explicit Properties(const PropertyChangedCallback& callback); + ~Properties() override; + + // dbus::PropertySet override + void Get(dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) override; + void GetAll() override; + void Set(dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) override; + }; + + FakeBluetoothAdapterClient(); + ~FakeBluetoothAdapterClient() override; + + // BluetoothAdapterClient overrides + void Init(dbus::Bus* bus) override; + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + std::vector<dbus::ObjectPath> GetAdapters() override; + Properties* GetProperties(const dbus::ObjectPath& object_path) override; + void StartDiscovery(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void StopDiscovery(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void RemoveDevice(const dbus::ObjectPath& object_path, + const dbus::ObjectPath& device_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void SetDiscoveryFilter(const dbus::ObjectPath& object_path, + const DiscoveryFilter& discovery_filter, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Sets the current simulation timeout interval. + void SetSimulationIntervalMs(int interval_ms); + + // Returns current discovery filter in use by this adapter. + DiscoveryFilter* GetDiscoveryFilter(); + + // Make SetDiscoveryFilter fail when called next time. + void MakeSetDiscoveryFilterFail(); + + // Mark the adapter and second adapter as visible or invisible. + void SetVisible(bool visible); + void SetSecondVisible(bool visible); + + // Object path, name and addresses of the adapters we emulate. + static const char kAdapterPath[]; + static const char kAdapterName[]; + static const char kAdapterAddress[]; + + static const char kSecondAdapterPath[]; + static const char kSecondAdapterName[]; + static const char kSecondAdapterAddress[]; + + private: + // Property callback passed when we create Properties* structures. + void OnPropertyChanged(const std::string& property_name); + + // Posts the delayed task represented by |callback| onto the current + // message loop to be executed after |simulation_interval_ms_| milliseconds. + void PostDelayedTask(const base::Closure& callback); + + // List of observers interested in event notifications from us. + base::ObserverList<Observer> observers_; + + // Static properties we return. + scoped_ptr<Properties> properties_; + scoped_ptr<Properties> second_properties_; + + // Whether the adapter and second adapter should be visible or not. + bool visible_; + bool second_visible_; + + // Number of times we've been asked to discover. + int discovering_count_; + + // Current discovery filter + scoped_ptr<DiscoveryFilter> discovery_filter_; + + // When set, next call to SetDiscoveryFilter would fail. + bool set_discovery_filter_should_fail_; + + // Current timeout interval used when posting delayed tasks. + int simulation_interval_ms_; +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_ADAPTER_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.cc new file mode 100644 index 0000000..5904441 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.cc @@ -0,0 +1,78 @@ +// Copyright (c) 2013 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 "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h" + +#include "base/logging.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +FakeBluetoothAgentManagerClient::FakeBluetoothAgentManagerClient() + : service_provider_(NULL) {} + +FakeBluetoothAgentManagerClient::~FakeBluetoothAgentManagerClient() {} + +void FakeBluetoothAgentManagerClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothAgentManagerClient::RegisterAgent( + const dbus::ObjectPath& agent_path, + const std::string& capability, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "RegisterAgent: " << agent_path.value(); + + if (service_provider_ == NULL) { + error_callback.Run(bluetooth_agent_manager::kErrorInvalidArguments, + "No agent created"); + } else if (service_provider_->object_path_ != agent_path) { + error_callback.Run(bluetooth_agent_manager::kErrorAlreadyExists, + "Agent already registered"); + } else { + callback.Run(); + } +} + +void FakeBluetoothAgentManagerClient::UnregisterAgent( + const dbus::ObjectPath& agent_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "UnregisterAgent: " << agent_path.value(); + if (service_provider_ == NULL) { + error_callback.Run(bluetooth_agent_manager::kErrorDoesNotExist, + "No agent registered"); + } else if (service_provider_->object_path_ != agent_path) { + error_callback.Run(bluetooth_agent_manager::kErrorDoesNotExist, + "Agent still registered"); + } else { + callback.Run(); + } +} + +void FakeBluetoothAgentManagerClient::RequestDefaultAgent( + const dbus::ObjectPath& agent_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "RequestDefaultAgent: " << agent_path.value(); + callback.Run(); +} + +void FakeBluetoothAgentManagerClient::RegisterAgentServiceProvider( + FakeBluetoothAgentServiceProvider* service_provider) { + service_provider_ = service_provider; +} + +void FakeBluetoothAgentManagerClient::UnregisterAgentServiceProvider( + FakeBluetoothAgentServiceProvider* service_provider) { + if (service_provider_ == service_provider) + service_provider_ = NULL; +} + +FakeBluetoothAgentServiceProvider* +FakeBluetoothAgentManagerClient::GetAgentServiceProvider() { + return service_provider_; +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h new file mode 100644 index 0000000..d5c83cf --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h @@ -0,0 +1,57 @@ +// Copyright (c) 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_MANAGER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_MANAGER_CLIENT_H_ + +#include "base/bind.h" +#include "base/callback.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_agent_manager_client.h" + +namespace bluez { + +class FakeBluetoothAgentServiceProvider; + +// FakeBluetoothAgentManagerClient simulates the behavior of the Bluetooth +// Daemon's agent manager object and is used both in test cases in place of a +// mock and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothAgentManagerClient + : public BluetoothAgentManagerClient { + public: + FakeBluetoothAgentManagerClient(); + ~FakeBluetoothAgentManagerClient() override; + + // BluetoothAgentManagerClient overrides + void Init(dbus::Bus* bus) override; + void RegisterAgent(const dbus::ObjectPath& agent_path, + const std::string& capability, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void UnregisterAgent(const dbus::ObjectPath& agent_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void RequestDefaultAgent(const dbus::ObjectPath& agent_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Register, unregister and retrieve pointers to agent service providers. + void RegisterAgentServiceProvider( + FakeBluetoothAgentServiceProvider* service_provider); + void UnregisterAgentServiceProvider( + FakeBluetoothAgentServiceProvider* service_provider); + FakeBluetoothAgentServiceProvider* GetAgentServiceProvider(); + + private: + // The single agent service provider we permit, owned by the application + // using it. + FakeBluetoothAgentServiceProvider* service_provider_; +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_MANAGER_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.cc new file mode 100644 index 0000000..777deb0 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.cc @@ -0,0 +1,102 @@ +// Copyright (c) 2013 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 "device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h" + +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h" + +namespace bluez { + +FakeBluetoothAgentServiceProvider::FakeBluetoothAgentServiceProvider( + const dbus::ObjectPath& object_path, + Delegate* delegate) + : object_path_(object_path), delegate_(delegate) { + VLOG(1) << "Creating Bluetooth Agent: " << object_path_.value(); + + FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client = + static_cast<FakeBluetoothAgentManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothAgentManagerClient()); + fake_bluetooth_agent_manager_client->RegisterAgentServiceProvider(this); +} + +FakeBluetoothAgentServiceProvider::~FakeBluetoothAgentServiceProvider() { + VLOG(1) << "Cleaning up Bluetooth Agent: " << object_path_.value(); + + FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client = + static_cast<FakeBluetoothAgentManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothAgentManagerClient()); + fake_bluetooth_agent_manager_client->UnregisterAgentServiceProvider(this); +} + +void FakeBluetoothAgentServiceProvider::Release() { + VLOG(1) << object_path_.value() << ": Release"; + delegate_->Released(); +} + +void FakeBluetoothAgentServiceProvider::RequestPinCode( + const dbus::ObjectPath& device_path, + const Delegate::PinCodeCallback& callback) { + VLOG(1) << object_path_.value() << ": RequestPinCode for " + << device_path.value(); + delegate_->RequestPinCode(device_path, callback); +} + +void FakeBluetoothAgentServiceProvider::DisplayPinCode( + const dbus::ObjectPath& device_path, + const std::string& pincode) { + VLOG(1) << object_path_.value() << ": DisplayPincode " << pincode << " for " + << device_path.value(); + delegate_->DisplayPinCode(device_path, pincode); +} + +void FakeBluetoothAgentServiceProvider::RequestPasskey( + const dbus::ObjectPath& device_path, + const Delegate::PasskeyCallback& callback) { + VLOG(1) << object_path_.value() << ": RequestPasskey for " + << device_path.value(); + delegate_->RequestPasskey(device_path, callback); +} + +void FakeBluetoothAgentServiceProvider::DisplayPasskey( + const dbus::ObjectPath& device_path, + uint32 passkey, + int16 entered) { + VLOG(1) << object_path_.value() << ": DisplayPasskey " << passkey << " (" + << entered << " entered) for " << device_path.value(); + delegate_->DisplayPasskey(device_path, passkey, entered); +} + +void FakeBluetoothAgentServiceProvider::RequestConfirmation( + const dbus::ObjectPath& device_path, + uint32 passkey, + const Delegate::ConfirmationCallback& callback) { + VLOG(1) << object_path_.value() << ": RequestConfirmation " << passkey + << " for " << device_path.value(); + delegate_->RequestConfirmation(device_path, passkey, callback); +} + +void FakeBluetoothAgentServiceProvider::RequestAuthorization( + const dbus::ObjectPath& device_path, + const Delegate::ConfirmationCallback& callback) { + VLOG(1) << object_path_.value() << ": RequestAuthorization for " + << device_path.value(); + delegate_->RequestAuthorization(device_path, callback); +} + +void FakeBluetoothAgentServiceProvider::AuthorizeService( + const dbus::ObjectPath& device_path, + const std::string& uuid, + const Delegate::ConfirmationCallback& callback) { + VLOG(1) << object_path_.value() << ": AuthorizeService " << uuid << " for " + << device_path.value(); + delegate_->AuthorizeService(device_path, uuid, callback); +} + +void FakeBluetoothAgentServiceProvider::Cancel() { + VLOG(1) << object_path_.value() << ": Cancel"; + delegate_->Cancel(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h new file mode 100644 index 0000000..e3c8cd4 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h @@ -0,0 +1,68 @@ +// Copyright (c) 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_ + +#include "base/bind.h" +#include "base/callback.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h" + +namespace bluez { + +class FakeBluetoothAgentManagerClient; + +// FakeBluetoothAgentServiceProvider simulates the behavior of a local +// Bluetooth agent object and is used both in test cases in place of a +// mock and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothAgentServiceProvider + : public BluetoothAgentServiceProvider { + public: + FakeBluetoothAgentServiceProvider(const dbus::ObjectPath& object_path, + Delegate* delegate); + ~FakeBluetoothAgentServiceProvider() override; + + // Each of these calls the equivalent BluetoothAgentServiceProvider::Delegate + // method on the object passed on construction. + virtual void Release(); + virtual void RequestPinCode(const dbus::ObjectPath& device_path, + const Delegate::PinCodeCallback& callback); + virtual void DisplayPinCode(const dbus::ObjectPath& device_path, + const std::string& pincode); + virtual void RequestPasskey(const dbus::ObjectPath& device_path, + const Delegate::PasskeyCallback& callback); + virtual void DisplayPasskey(const dbus::ObjectPath& device_path, + uint32 passkey, + int16 entered); + virtual void RequestConfirmation( + const dbus::ObjectPath& device_path, + uint32 passkey, + const Delegate::ConfirmationCallback& callback); + virtual void RequestAuthorization( + const dbus::ObjectPath& device_path, + const Delegate::ConfirmationCallback& callback); + virtual void AuthorizeService(const dbus::ObjectPath& device_path, + const std::string& uuid, + const Delegate::ConfirmationCallback& callback); + virtual void Cancel(); + + private: + friend class FakeBluetoothAgentManagerClient; + + // D-Bus object path we are faking. + dbus::ObjectPath object_path_; + + // All incoming method calls are passed on to the Delegate and a callback + // passed to generate the reply. |delegate_| is generally the object that + // owns this one, and must outlive it. + Delegate* delegate_; +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_AGENT_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_device_client.cc b/device/bluetooth/dbus/fake_bluetooth_device_client.cc new file mode 100644 index 0000000..83d31dd4 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_device_client.cc @@ -0,0 +1,1662 @@ +// Copyright (c) 2013 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 "device/bluetooth/dbus/fake_bluetooth_device_client.h" + +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> + +#include <algorithm> +#include <string> +#include <utility> + +#include "base/location.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/rand_util.h" +#include "base/single_thread_task_runner.h" +#include "base/stl_util.h" +#include "base/thread_task_runner_handle.h" +#include "base/threading/worker_pool.h" +#include "base/time/time.h" +#include "dbus/file_descriptor.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_agent_service_provider.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_input_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace { + +// Default interval between simulated events. +const int kSimulationIntervalMs = 750; + +// Minimum and maximum bounds for randomly generated RSSI values. +const int kMinRSSI = -90; +const int kMaxRSSI = -30; + +// The default value of connection info properties from GetConnInfo(). +const int kUnkownPower = 127; + +// This is meant to delay the removal of a pre defined device until the +// developer has time to see it. +const int kVanishingDevicePairTimeMultiplier = 4; + +// Meant to delay a pair request for an observable amount of time. +const int kIncomingSimulationPairTimeMultiplier = 45; + +// Meant to delay a request that asks for pair requests for an observable +// amount of time. +const int kIncomingSimulationStartPairTimeMultiplier = 30; + +// This allows the PIN code dialog to be shown for a long enough time to see +// the PIN code UI in detail. +const int kPinCodeDevicePairTimeMultiplier = 7; + +// This allows the pairing dialog to be shown for a long enough time to see +// its UI in detail. +const int kSimulateNormalPairTimeMultiplier = 3; + +void SimulatedProfileSocket(int fd) { + // Simulate a server-side socket of a profile; read data from the socket, + // write it back, and then close. + char buf[1024]; + ssize_t len; + ssize_t count; + + len = read(fd, buf, sizeof buf); + if (len < 0) { + close(fd); + return; + } + + count = len; + len = write(fd, buf, count); + if (len < 0) { + close(fd); + return; + } + + close(fd); +} + +void SimpleErrorCallback(const std::string& error_name, + const std::string& error_message) { + VLOG(1) << "Bluetooth Error: " << error_name << ": " << error_message; +} + +} // namespace + +namespace bluez { + +const char FakeBluetoothDeviceClient::kTestPinCode[] = "123456"; +const int FakeBluetoothDeviceClient::kTestPassKey = 123456; + +const char FakeBluetoothDeviceClient::kPairingMethodNone[] = "None"; +const char FakeBluetoothDeviceClient::kPairingMethodPinCode[] = "PIN Code"; +const char FakeBluetoothDeviceClient::kPairingMethodPassKey[] = "PassKey"; + +const char FakeBluetoothDeviceClient::kPairingActionConfirmation[] = + "Confirmation"; +const char FakeBluetoothDeviceClient::kPairingActionDisplay[] = "Display"; +const char FakeBluetoothDeviceClient::kPairingActionFail[] = "Fail"; +const char FakeBluetoothDeviceClient::kPairingActionRequest[] = "Request"; + +const char FakeBluetoothDeviceClient::kPairedDevicePath[] = "/fake/hci0/dev0"; +const char FakeBluetoothDeviceClient::kPairedDeviceAddress[] = + "00:11:22:33:44:55"; +const char FakeBluetoothDeviceClient::kPairedDeviceName[] = "Fake Device"; +const uint32 FakeBluetoothDeviceClient::kPairedDeviceClass = 0x000104; + +const char FakeBluetoothDeviceClient::kLegacyAutopairPath[] = "/fake/hci0/dev1"; +const char FakeBluetoothDeviceClient::kLegacyAutopairAddress[] = + "28:CF:DA:00:00:00"; +const char FakeBluetoothDeviceClient::kLegacyAutopairName[] = + "Bluetooth 2.0 Mouse"; +const uint32 FakeBluetoothDeviceClient::kLegacyAutopairClass = 0x002580; + +const char FakeBluetoothDeviceClient::kDisplayPinCodePath[] = "/fake/hci0/dev2"; +const char FakeBluetoothDeviceClient::kDisplayPinCodeAddress[] = + "28:37:37:00:00:00"; +const char FakeBluetoothDeviceClient::kDisplayPinCodeName[] = + "Bluetooth 2.0 Keyboard"; +const uint32 FakeBluetoothDeviceClient::kDisplayPinCodeClass = 0x002540; + +const char FakeBluetoothDeviceClient::kVanishingDevicePath[] = + "/fake/hci0/dev3"; +const char FakeBluetoothDeviceClient::kVanishingDeviceAddress[] = + "01:02:03:04:05:06"; +const char FakeBluetoothDeviceClient::kVanishingDeviceName[] = + "Vanishing Device"; +const uint32 FakeBluetoothDeviceClient::kVanishingDeviceClass = 0x000104; + +const char FakeBluetoothDeviceClient::kConnectUnpairablePath[] = + "/fake/hci0/dev4"; +const char FakeBluetoothDeviceClient::kConnectUnpairableAddress[] = + "7C:ED:8D:00:00:00"; +const char FakeBluetoothDeviceClient::kConnectUnpairableName[] = + "Unpairable Device"; +const uint32 FakeBluetoothDeviceClient::kConnectUnpairableClass = 0x002580; + +const char FakeBluetoothDeviceClient::kDisplayPasskeyPath[] = "/fake/hci0/dev5"; +const char FakeBluetoothDeviceClient::kDisplayPasskeyAddress[] = + "00:0F:F6:00:00:00"; +const char FakeBluetoothDeviceClient::kDisplayPasskeyName[] = + "Bluetooth 2.1+ Keyboard"; +const uint32 FakeBluetoothDeviceClient::kDisplayPasskeyClass = 0x002540; + +const char FakeBluetoothDeviceClient::kRequestPinCodePath[] = "/fake/hci0/dev6"; +const char FakeBluetoothDeviceClient::kRequestPinCodeAddress[] = + "00:24:BE:00:00:00"; +const char FakeBluetoothDeviceClient::kRequestPinCodeName[] = "PIN Device"; +const uint32 FakeBluetoothDeviceClient::kRequestPinCodeClass = 0x240408; + +const char FakeBluetoothDeviceClient::kConfirmPasskeyPath[] = "/fake/hci0/dev7"; +const char FakeBluetoothDeviceClient::kConfirmPasskeyAddress[] = + "20:7D:74:00:00:00"; +const char FakeBluetoothDeviceClient::kConfirmPasskeyName[] = "Phone"; +const uint32 FakeBluetoothDeviceClient::kConfirmPasskeyClass = 0x7a020c; + +const char FakeBluetoothDeviceClient::kRequestPasskeyPath[] = "/fake/hci0/dev8"; +const char FakeBluetoothDeviceClient::kRequestPasskeyAddress[] = + "20:7D:74:00:00:01"; +const char FakeBluetoothDeviceClient::kRequestPasskeyName[] = "Passkey Device"; +const uint32 FakeBluetoothDeviceClient::kRequestPasskeyClass = 0x7a020c; + +const char FakeBluetoothDeviceClient::kUnconnectableDevicePath[] = + "/fake/hci0/dev9"; +const char FakeBluetoothDeviceClient::kUnconnectableDeviceAddress[] = + "20:7D:74:00:00:02"; +const char FakeBluetoothDeviceClient::kUnconnectableDeviceName[] = + "Unconnectable Device"; +const uint32 FakeBluetoothDeviceClient::kUnconnectableDeviceClass = 0x7a020c; + +const char FakeBluetoothDeviceClient::kUnpairableDevicePath[] = + "/fake/hci0/devA"; +const char FakeBluetoothDeviceClient::kUnpairableDeviceAddress[] = + "20:7D:74:00:00:03"; +const char FakeBluetoothDeviceClient::kUnpairableDeviceName[] = + "Unpairable Device"; +const uint32 FakeBluetoothDeviceClient::kUnpairableDeviceClass = 0x002540; + +const char FakeBluetoothDeviceClient::kJustWorksPath[] = "/fake/hci0/devB"; +const char FakeBluetoothDeviceClient::kJustWorksAddress[] = "00:0C:8A:00:00:00"; +const char FakeBluetoothDeviceClient::kJustWorksName[] = "Just-Works Device"; +const uint32 FakeBluetoothDeviceClient::kJustWorksClass = 0x240428; + +const char FakeBluetoothDeviceClient::kLowEnergyPath[] = "/fake/hci0/devC"; +const char FakeBluetoothDeviceClient::kLowEnergyAddress[] = "00:1A:11:00:15:30"; +const char FakeBluetoothDeviceClient::kLowEnergyName[] = + "Bluetooth 4.0 Heart Rate Monitor"; +const uint32 FakeBluetoothDeviceClient::kLowEnergyClass = + 0x000918; // Major class "Health", Minor class "Heart/Pulse Rate Monitor." + +const char FakeBluetoothDeviceClient::kPairedUnconnectableDevicePath[] = + "/fake/hci0/devD"; +const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress[] = + "20:7D:74:00:00:04"; +const char FakeBluetoothDeviceClient::kPairedUnconnectableDeviceName[] = + "Paired Unconnectable Device"; +const uint32 FakeBluetoothDeviceClient::kPairedUnconnectableDeviceClass = + 0x000104; + +const char FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDevicePath[] = + "/fake/hci0/devE"; +const char + FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDeviceAddress[] = + "11:22:33:44:55:66"; +const char FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDeviceName[] = + "Connected Pairable Device"; +const uint32 FakeBluetoothDeviceClient::kConnectedTrustedNotPairedDeviceClass = + 0x7a020c; + +FakeBluetoothDeviceClient::Properties::Properties( + const PropertyChangedCallback& callback) + : BluetoothDeviceClient::Properties( + NULL, + bluetooth_device::kBluetoothDeviceInterface, + callback) {} + +FakeBluetoothDeviceClient::Properties::~Properties() {} + +void FakeBluetoothDeviceClient::Properties::Get( + dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) { + VLOG(1) << "Get " << property->name(); + callback.Run(false); +} + +void FakeBluetoothDeviceClient::Properties::GetAll() { + VLOG(1) << "GetAll"; +} + +void FakeBluetoothDeviceClient::Properties::Set( + dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) { + VLOG(1) << "Set " << property->name(); + if (property->name() == trusted.name()) { + callback.Run(true); + property->ReplaceValueWithSetValue(); + } else { + callback.Run(false); + } +} + +FakeBluetoothDeviceClient::SimulatedPairingOptions::SimulatedPairingOptions() {} + +FakeBluetoothDeviceClient::SimulatedPairingOptions::~SimulatedPairingOptions() { +} + +FakeBluetoothDeviceClient::IncomingDeviceProperties:: + IncomingDeviceProperties() {} + +FakeBluetoothDeviceClient::IncomingDeviceProperties:: + ~IncomingDeviceProperties() {} + +FakeBluetoothDeviceClient::FakeBluetoothDeviceClient() + : simulation_interval_ms_(kSimulationIntervalMs), + discovery_simulation_step_(0), + incoming_pairing_simulation_step_(0), + pairing_cancelled_(false), + connection_rssi_(kUnkownPower), + transmit_power_(kUnkownPower), + max_transmit_power_(kUnkownPower) { + scoped_ptr<Properties> properties(new Properties( + base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged, + base::Unretained(this), dbus::ObjectPath(kPairedDevicePath)))); + properties->address.ReplaceValue(kPairedDeviceAddress); + properties->bluetooth_class.ReplaceValue(kPairedDeviceClass); + properties->name.ReplaceValue("Fake Device (Name)"); + properties->alias.ReplaceValue(kPairedDeviceName); + properties->paired.ReplaceValue(true); + properties->trusted.ReplaceValue(true); + properties->adapter.ReplaceValue( + dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); + + std::vector<std::string> uuids; + uuids.push_back("00001800-0000-1000-8000-00805f9b34fb"); + uuids.push_back("00001801-0000-1000-8000-00805f9b34fb"); + properties->uuids.ReplaceValue(uuids); + + properties->modalias.ReplaceValue("usb:v05ACp030Dd0306"); + + properties_map_.insert(dbus::ObjectPath(kPairedDevicePath), + properties.Pass()); + device_list_.push_back(dbus::ObjectPath(kPairedDevicePath)); + + properties.reset(new Properties(base::Bind( + &FakeBluetoothDeviceClient::OnPropertyChanged, base::Unretained(this), + dbus::ObjectPath(kPairedUnconnectableDevicePath)))); + properties->address.ReplaceValue(kPairedUnconnectableDeviceAddress); + properties->bluetooth_class.ReplaceValue(kPairedUnconnectableDeviceClass); + properties->name.ReplaceValue("Fake Device 2 (Unconnectable)"); + properties->alias.ReplaceValue(kPairedUnconnectableDeviceName); + properties->paired.ReplaceValue(true); + properties->trusted.ReplaceValue(true); + properties->adapter.ReplaceValue( + dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)); + + properties->uuids.ReplaceValue(uuids); + + properties->modalias.ReplaceValue("usb:v05ACp030Dd0306"); + + properties_map_.insert(dbus::ObjectPath(kPairedUnconnectableDevicePath), + properties.Pass()); + device_list_.push_back(dbus::ObjectPath(kPairedUnconnectableDevicePath)); +} + +FakeBluetoothDeviceClient::~FakeBluetoothDeviceClient() {} + +void FakeBluetoothDeviceClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothDeviceClient::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeBluetoothDeviceClient::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +std::vector<dbus::ObjectPath> FakeBluetoothDeviceClient::GetDevicesForAdapter( + const dbus::ObjectPath& adapter_path) { + if (adapter_path == + dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)) + return device_list_; + else + return std::vector<dbus::ObjectPath>(); +} + +FakeBluetoothDeviceClient::Properties* FakeBluetoothDeviceClient::GetProperties( + const dbus::ObjectPath& object_path) { + PropertiesMap::const_iterator iter = properties_map_.find(object_path); + if (iter != properties_map_.end()) + return iter->second; + return NULL; +} + +FakeBluetoothDeviceClient::SimulatedPairingOptions* +FakeBluetoothDeviceClient::GetPairingOptions( + const dbus::ObjectPath& object_path) { + PairingOptionsMap::const_iterator iter = + pairing_options_map_.find(object_path); + if (iter != pairing_options_map_.end()) + return iter->second; + return iter != pairing_options_map_.end() ? iter->second : nullptr; +} + +void FakeBluetoothDeviceClient::Connect(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "Connect: " << object_path.value(); + Properties* properties = GetProperties(object_path); + + if (properties->connected.value() == true) { + // Already connected. + callback.Run(); + return; + } + + if (properties->paired.value() != true && + object_path != dbus::ObjectPath(kConnectUnpairablePath) && + object_path != dbus::ObjectPath(kLowEnergyPath)) { + // Must be paired. + error_callback.Run(bluetooth_device::kErrorFailed, "Not paired"); + return; + } else if (properties->paired.value() == true && + (object_path == dbus::ObjectPath(kUnconnectableDevicePath) || + object_path == + dbus::ObjectPath(kPairedUnconnectableDevicePath))) { + // Must not be paired + error_callback.Run(bluetooth_device::kErrorFailed, + "Connection fails while paired"); + return; + } + + // The device can be connected. + properties->connected.ReplaceValue(true); + callback.Run(); + + // Expose GATT services if connected to LE device. + if (object_path == dbus::ObjectPath(kLowEnergyPath)) { + FakeBluetoothGattServiceClient* gatt_service_client = + static_cast<FakeBluetoothGattServiceClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient()); + gatt_service_client->ExposeHeartRateService( + dbus::ObjectPath(kLowEnergyPath)); + properties->gatt_services.ReplaceValue(gatt_service_client->GetServices()); + } + + AddInputDeviceIfNeeded(object_path, properties); +} + +void FakeBluetoothDeviceClient::Disconnect( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "Disconnect: " << object_path.value(); + Properties* properties = GetProperties(object_path); + + if (!properties->connected.value()) { + error_callback.Run("org.bluez.Error.NotConnected", "Not Connected"); + return; + } + + // Hide the Heart Rate Service if disconnected from LE device. + if (object_path == dbus::ObjectPath(kLowEnergyPath)) { + FakeBluetoothGattServiceClient* gatt_service_client = + static_cast<FakeBluetoothGattServiceClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient()); + gatt_service_client->HideHeartRateService(); + } + + callback.Run(); + properties->connected.ReplaceValue(false); +} + +void FakeBluetoothDeviceClient::ConnectProfile( + const dbus::ObjectPath& object_path, + const std::string& uuid, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "ConnectProfile: " << object_path.value() << " " << uuid; + + FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client = + static_cast<FakeBluetoothProfileManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothProfileManagerClient()); + FakeBluetoothProfileServiceProvider* profile_service_provider = + fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid); + if (profile_service_provider == NULL) { + error_callback.Run(kNoResponseError, "Missing profile"); + return; + } + + if (object_path == dbus::ObjectPath(kPairedUnconnectableDevicePath)) { + error_callback.Run(bluetooth_device::kErrorFailed, "unconnectable"); + return; + } + + // Make a socket pair of a compatible type with the type used by Bluetooth; + // spin up a thread to simulate the server side and wrap the client side in + // a D-Bus file descriptor object. + int socket_type = SOCK_STREAM; + if (uuid == FakeBluetoothProfileManagerClient::kL2capUuid) + socket_type = SOCK_SEQPACKET; + + int fds[2]; + if (socketpair(AF_UNIX, socket_type, 0, fds) < 0) { + error_callback.Run(kNoResponseError, "socketpair call failed"); + return; + } + + int args; + args = fcntl(fds[1], F_GETFL, NULL); + if (args < 0) { + error_callback.Run(kNoResponseError, "failed to get socket flags"); + return; + } + + args |= O_NONBLOCK; + if (fcntl(fds[1], F_SETFL, args) < 0) { + error_callback.Run(kNoResponseError, "failed to set socket non-blocking"); + return; + } + + base::WorkerPool::GetTaskRunner(false) + ->PostTask(FROM_HERE, base::Bind(&SimulatedProfileSocket, fds[0])); + + scoped_ptr<dbus::FileDescriptor> fd(new dbus::FileDescriptor(fds[1])); + + // Post the new connection to the service provider. + BluetoothProfileServiceProvider::Delegate::Options options; + + profile_service_provider->NewConnection( + object_path, fd.Pass(), options, + base::Bind(&FakeBluetoothDeviceClient::ConnectionCallback, + base::Unretained(this), object_path, callback, + error_callback)); +} + +void FakeBluetoothDeviceClient::DisconnectProfile( + const dbus::ObjectPath& object_path, + const std::string& uuid, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "DisconnectProfile: " << object_path.value() << " " << uuid; + + FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client = + static_cast<FakeBluetoothProfileManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothProfileManagerClient()); + FakeBluetoothProfileServiceProvider* profile_service_provider = + fake_bluetooth_profile_manager_client->GetProfileServiceProvider(uuid); + if (profile_service_provider == NULL) { + error_callback.Run(kNoResponseError, "Missing profile"); + return; + } + + profile_service_provider->RequestDisconnection( + object_path, base::Bind(&FakeBluetoothDeviceClient::DisconnectionCallback, + base::Unretained(this), object_path, callback, + error_callback)); +} + +void FakeBluetoothDeviceClient::Pair(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "Pair: " << object_path.value(); + Properties* properties = GetProperties(object_path); + + if (properties->paired.value() == true) { + // Already paired. + callback.Run(); + return; + } + + SimulatePairing(object_path, false, callback, error_callback); +} + +void FakeBluetoothDeviceClient::CancelPairing( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "CancelPairing: " << object_path.value(); + pairing_cancelled_ = true; + callback.Run(); +} + +void FakeBluetoothDeviceClient::GetConnInfo( + const dbus::ObjectPath& object_path, + const ConnInfoCallback& callback, + const ErrorCallback& error_callback) { + Properties* properties = GetProperties(object_path); + if (!properties->connected.value()) { + error_callback.Run("org.bluez.Error.NotConnected", "Not Connected"); + return; + } + + callback.Run(connection_rssi_, transmit_power_, max_transmit_power_); +} + +void FakeBluetoothDeviceClient::BeginDiscoverySimulation( + const dbus::ObjectPath& adapter_path) { + VLOG(1) << "starting discovery simulation"; + + discovery_simulation_step_ = 1; + + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer, + base::Unretained(this)), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); +} + +void FakeBluetoothDeviceClient::EndDiscoverySimulation( + const dbus::ObjectPath& adapter_path) { + VLOG(1) << "stopping discovery simulation"; + discovery_simulation_step_ = 0; +} + +void FakeBluetoothDeviceClient::BeginIncomingPairingSimulation( + const dbus::ObjectPath& adapter_path) { + VLOG(1) << "starting incoming pairing simulation"; + + incoming_pairing_simulation_step_ = 1; + + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer, + base::Unretained(this)), + base::TimeDelta::FromMilliseconds( + kIncomingSimulationStartPairTimeMultiplier * + simulation_interval_ms_)); +} + +void FakeBluetoothDeviceClient::EndIncomingPairingSimulation( + const dbus::ObjectPath& adapter_path) { + VLOG(1) << "stopping incoming pairing simulation"; + incoming_pairing_simulation_step_ = 0; +} + +void FakeBluetoothDeviceClient::SetSimulationIntervalMs(int interval_ms) { + simulation_interval_ms_ = interval_ms; +} + +void FakeBluetoothDeviceClient::CreateDevice( + const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path) { + if (std::find(device_list_.begin(), device_list_.end(), device_path) != + device_list_.end()) + return; + + scoped_ptr<Properties> properties( + new Properties(base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged, + base::Unretained(this), device_path))); + properties->adapter.ReplaceValue(adapter_path); + + if (device_path == dbus::ObjectPath(kLegacyAutopairPath)) { + properties->address.ReplaceValue(kLegacyAutopairAddress); + properties->bluetooth_class.ReplaceValue(kLegacyAutopairClass); + properties->name.ReplaceValue("LegacyAutopair"); + properties->alias.ReplaceValue(kLegacyAutopairName); + + std::vector<std::string> uuids; + uuids.push_back("00001124-0000-1000-8000-00805f9b34fb"); + properties->uuids.ReplaceValue(uuids); + + } else if (device_path == dbus::ObjectPath(kDisplayPinCodePath)) { + properties->address.ReplaceValue(kDisplayPinCodeAddress); + properties->bluetooth_class.ReplaceValue(kDisplayPinCodeClass); + properties->name.ReplaceValue("DisplayPinCode"); + properties->alias.ReplaceValue(kDisplayPinCodeName); + + std::vector<std::string> uuids; + uuids.push_back("00001124-0000-1000-8000-00805f9b34fb"); + properties->uuids.ReplaceValue(uuids); + + } else if (device_path == dbus::ObjectPath(kVanishingDevicePath)) { + properties->address.ReplaceValue(kVanishingDeviceAddress); + properties->bluetooth_class.ReplaceValue(kVanishingDeviceClass); + properties->name.ReplaceValue("VanishingDevice"); + properties->alias.ReplaceValue(kVanishingDeviceName); + + } else if (device_path == dbus::ObjectPath(kConnectUnpairablePath)) { + properties->address.ReplaceValue(kConnectUnpairableAddress); + properties->bluetooth_class.ReplaceValue(kConnectUnpairableClass); + properties->name.ReplaceValue("ConnectUnpairable"); + properties->alias.ReplaceValue(kConnectUnpairableName); + + std::vector<std::string> uuids; + uuids.push_back("00001124-0000-1000-8000-00805f9b34fb"); + properties->uuids.ReplaceValue(uuids); + + } else if (device_path == dbus::ObjectPath(kDisplayPasskeyPath)) { + properties->address.ReplaceValue(kDisplayPasskeyAddress); + properties->bluetooth_class.ReplaceValue(kDisplayPasskeyClass); + properties->name.ReplaceValue("DisplayPasskey"); + properties->alias.ReplaceValue(kDisplayPasskeyName); + + std::vector<std::string> uuids; + uuids.push_back("00001124-0000-1000-8000-00805f9b34fb"); + properties->uuids.ReplaceValue(uuids); + + } else if (device_path == dbus::ObjectPath(kRequestPinCodePath)) { + properties->address.ReplaceValue(kRequestPinCodeAddress); + properties->bluetooth_class.ReplaceValue(kRequestPinCodeClass); + properties->name.ReplaceValue("RequestPinCode"); + properties->alias.ReplaceValue(kRequestPinCodeName); + + } else if (device_path == dbus::ObjectPath(kConfirmPasskeyPath)) { + properties->address.ReplaceValue(kConfirmPasskeyAddress); + properties->bluetooth_class.ReplaceValue(kConfirmPasskeyClass); + properties->name.ReplaceValue("ConfirmPasskey"); + properties->alias.ReplaceValue(kConfirmPasskeyName); + + } else if (device_path == dbus::ObjectPath(kRequestPasskeyPath)) { + properties->address.ReplaceValue(kRequestPasskeyAddress); + properties->bluetooth_class.ReplaceValue(kRequestPasskeyClass); + properties->name.ReplaceValue("RequestPasskey"); + properties->alias.ReplaceValue(kRequestPasskeyName); + + } else if (device_path == dbus::ObjectPath(kUnconnectableDevicePath)) { + properties->address.ReplaceValue(kUnconnectableDeviceAddress); + properties->bluetooth_class.ReplaceValue(kUnconnectableDeviceClass); + properties->name.ReplaceValue("UnconnectableDevice"); + properties->alias.ReplaceValue(kUnconnectableDeviceName); + + } else if (device_path == dbus::ObjectPath(kUnpairableDevicePath)) { + properties->address.ReplaceValue(kUnpairableDeviceAddress); + properties->bluetooth_class.ReplaceValue(kUnpairableDeviceClass); + properties->name.ReplaceValue("Fake Unpairable Device"); + properties->alias.ReplaceValue(kUnpairableDeviceName); + + } else if (device_path == dbus::ObjectPath(kJustWorksPath)) { + properties->address.ReplaceValue(kJustWorksAddress); + properties->bluetooth_class.ReplaceValue(kJustWorksClass); + properties->name.ReplaceValue("JustWorks"); + properties->alias.ReplaceValue(kJustWorksName); + + } else if (device_path == dbus::ObjectPath(kLowEnergyPath)) { + properties->address.ReplaceValue(kLowEnergyAddress); + properties->bluetooth_class.ReplaceValue(kLowEnergyClass); + properties->name.ReplaceValue("Heart Rate Monitor"); + properties->alias.ReplaceValue(kLowEnergyName); + + std::vector<std::string> uuids; + uuids.push_back(FakeBluetoothGattServiceClient::kHeartRateServiceUUID); + properties->uuids.ReplaceValue(uuids); + } else if (device_path == + dbus::ObjectPath(kConnectedTrustedNotPairedDevicePath)) { + properties->address.ReplaceValue(kConnectedTrustedNotPairedDeviceAddress); + properties->bluetooth_class.ReplaceValue( + kConnectedTrustedNotPairedDeviceClass); + properties->trusted.ReplaceValue(true); + properties->connected.ReplaceValue(true); + properties->paired.ReplaceValue(false); + properties->name.ReplaceValue("Connected Pairable Device"); + properties->alias.ReplaceValue(kConnectedTrustedNotPairedDeviceName); + } else { + NOTREACHED(); + } + + properties_map_.insert(device_path, properties.Pass()); + device_list_.push_back(device_path); + FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, + DeviceAdded(device_path)); +} + +void FakeBluetoothDeviceClient::CreateDeviceWithProperties( + const dbus::ObjectPath& adapter_path, + const IncomingDeviceProperties& props) { + dbus::ObjectPath device_path(props.device_path); + if (std::find(device_list_.begin(), device_list_.end(), device_path) != + device_list_.end()) + return; + + scoped_ptr<Properties> properties( + new Properties(base::Bind(&FakeBluetoothDeviceClient::OnPropertyChanged, + base::Unretained(this), device_path))); + properties->adapter.ReplaceValue(adapter_path); + properties->name.ReplaceValue(props.device_name); + properties->alias.ReplaceValue(props.device_alias); + properties->address.ReplaceValue(props.device_address); + properties->bluetooth_class.ReplaceValue(props.device_class); + properties->trusted.ReplaceValue(props.is_trusted); + + if (props.is_trusted) + properties->paired.ReplaceValue(true); + + scoped_ptr<SimulatedPairingOptions> options(new SimulatedPairingOptions); + options->pairing_method = props.pairing_method; + options->pairing_auth_token = props.pairing_auth_token; + options->pairing_action = props.pairing_action; + options->incoming = props.incoming; + + properties_map_.insert(device_path, properties.Pass()); + device_list_.push_back(device_path); + pairing_options_map_.insert(device_path, options.Pass()); + FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, + DeviceAdded(device_path)); +} + +scoped_ptr<base::ListValue> +FakeBluetoothDeviceClient::GetBluetoothDevicesAsDictionaries() const { + scoped_ptr<base::ListValue> predefined_devices(new base::ListValue); + scoped_ptr<base::DictionaryValue> pairedDevice(new base::DictionaryValue); + pairedDevice->SetString("path", kPairedDevicePath); + pairedDevice->SetString("address", kPairedDeviceAddress); + pairedDevice->SetString("name", kPairedDeviceName); + pairedDevice->SetString("alias", kPairedDeviceName); + pairedDevice->SetString("pairingMethod", ""); + pairedDevice->SetString("pairingAuthToken", ""); + pairedDevice->SetString("pairingAction", ""); + pairedDevice->SetInteger("classValue", kPairedDeviceClass); + pairedDevice->SetBoolean("discoverable", true); + pairedDevice->SetBoolean("isTrusted", true); + pairedDevice->SetBoolean("paired", true); + pairedDevice->SetBoolean("incoming", false); + predefined_devices->Append(pairedDevice.Pass()); + + scoped_ptr<base::DictionaryValue> legacyDevice(new base::DictionaryValue); + legacyDevice->SetString("path", kLegacyAutopairPath); + legacyDevice->SetString("address", kLegacyAutopairAddress); + legacyDevice->SetString("name", kLegacyAutopairName); + legacyDevice->SetString("alias", kLegacyAutopairName); + legacyDevice->SetString("pairingMethod", ""); + legacyDevice->SetString("pairingAuthToken", ""); + legacyDevice->SetString("pairingAction", ""); + legacyDevice->SetInteger("classValue", kLegacyAutopairClass); + legacyDevice->SetBoolean("isTrusted", true); + legacyDevice->SetBoolean("discoverable", false); + legacyDevice->SetBoolean("paired", false); + legacyDevice->SetBoolean("incoming", false); + predefined_devices->Append(legacyDevice.Pass()); + + scoped_ptr<base::DictionaryValue> pin(new base::DictionaryValue); + pin->SetString("path", kDisplayPinCodePath); + pin->SetString("address", kDisplayPinCodeAddress); + pin->SetString("name", kDisplayPinCodeName); + pin->SetString("alias", kDisplayPinCodeName); + pin->SetString("pairingMethod", kPairingMethodPinCode); + pin->SetString("pairingAuthToken", kTestPinCode); + pin->SetString("pairingAction", kPairingActionDisplay); + pin->SetInteger("classValue", kDisplayPinCodeClass); + pin->SetBoolean("isTrusted", false); + pin->SetBoolean("discoverable", false); + pin->SetBoolean("paired", false); + pin->SetBoolean("incoming", false); + predefined_devices->Append(pin.Pass()); + + scoped_ptr<base::DictionaryValue> vanishing(new base::DictionaryValue); + vanishing->SetString("path", kVanishingDevicePath); + vanishing->SetString("address", kVanishingDeviceAddress); + vanishing->SetString("name", kVanishingDeviceName); + vanishing->SetString("alias", kVanishingDeviceName); + vanishing->SetString("pairingMethod", ""); + vanishing->SetString("pairingAuthToken", ""); + vanishing->SetString("pairingAction", ""); + vanishing->SetInteger("classValue", kVanishingDeviceClass); + vanishing->SetBoolean("isTrusted", false); + vanishing->SetBoolean("discoverable", false); + vanishing->SetBoolean("paired", false); + vanishing->SetBoolean("incoming", false); + predefined_devices->Append(vanishing.Pass()); + + scoped_ptr<base::DictionaryValue> connect_unpairable( + new base::DictionaryValue); + connect_unpairable->SetString("path", kConnectUnpairablePath); + connect_unpairable->SetString("address", kConnectUnpairableAddress); + connect_unpairable->SetString("name", kConnectUnpairableName); + connect_unpairable->SetString("pairingMethod", ""); + connect_unpairable->SetString("pairingAuthToken", ""); + connect_unpairable->SetString("pairingAction", ""); + connect_unpairable->SetString("alias", kConnectUnpairableName); + connect_unpairable->SetInteger("classValue", kConnectUnpairableClass); + connect_unpairable->SetBoolean("isTrusted", false); + connect_unpairable->SetBoolean("discoverable", false); + connect_unpairable->SetBoolean("paired", false); + connect_unpairable->SetBoolean("incoming", false); + predefined_devices->Append(connect_unpairable.Pass()); + + scoped_ptr<base::DictionaryValue> passkey(new base::DictionaryValue); + passkey->SetString("path", kDisplayPasskeyPath); + passkey->SetString("address", kDisplayPasskeyAddress); + passkey->SetString("name", kDisplayPasskeyName); + passkey->SetString("alias", kDisplayPasskeyName); + passkey->SetString("pairingMethod", kPairingMethodPassKey); + passkey->SetInteger("pairingAuthToken", kTestPassKey); + passkey->SetString("pairingAction", kPairingActionDisplay); + passkey->SetInteger("classValue", kDisplayPasskeyClass); + passkey->SetBoolean("isTrusted", false); + passkey->SetBoolean("discoverable", false); + passkey->SetBoolean("paired", false); + passkey->SetBoolean("incoming", false); + predefined_devices->Append(passkey.Pass()); + + scoped_ptr<base::DictionaryValue> request_pin(new base::DictionaryValue); + request_pin->SetString("path", kRequestPinCodePath); + request_pin->SetString("address", kRequestPinCodeAddress); + request_pin->SetString("name", kRequestPinCodeName); + request_pin->SetString("alias", kRequestPinCodeName); + request_pin->SetString("pairingMethod", ""); + request_pin->SetString("pairingAuthToken", ""); + request_pin->SetString("pairingAction", kPairingActionRequest); + request_pin->SetInteger("classValue", kRequestPinCodeClass); + request_pin->SetBoolean("isTrusted", false); + request_pin->SetBoolean("discoverable", false); + request_pin->SetBoolean("paired", false); + request_pin->SetBoolean("incoming", false); + predefined_devices->Append(request_pin.Pass()); + + scoped_ptr<base::DictionaryValue> confirm(new base::DictionaryValue); + confirm->SetString("path", kConfirmPasskeyPath); + confirm->SetString("address", kConfirmPasskeyAddress); + confirm->SetString("name", kConfirmPasskeyName); + confirm->SetString("alias", kConfirmPasskeyName); + confirm->SetString("pairingMethod", ""); + confirm->SetInteger("pairingAuthToken", kTestPassKey); + confirm->SetString("pairingAction", kPairingActionConfirmation); + confirm->SetInteger("classValue", kConfirmPasskeyClass); + confirm->SetBoolean("isTrusted", false); + confirm->SetBoolean("discoverable", false); + confirm->SetBoolean("paired", false); + confirm->SetBoolean("incoming", false); + predefined_devices->Append(confirm.Pass()); + + scoped_ptr<base::DictionaryValue> request_passkey(new base::DictionaryValue); + request_passkey->SetString("path", kRequestPasskeyPath); + request_passkey->SetString("address", kRequestPasskeyAddress); + request_passkey->SetString("name", kRequestPasskeyName); + request_passkey->SetString("alias", kRequestPasskeyName); + request_passkey->SetString("pairingMethod", kPairingMethodPassKey); + request_passkey->SetString("pairingAction", kPairingActionRequest); + request_passkey->SetInteger("pairingAuthToken", kTestPassKey); + request_passkey->SetInteger("classValue", kRequestPasskeyClass); + request_passkey->SetBoolean("isTrusted", false); + request_passkey->SetBoolean("discoverable", false); + request_passkey->SetBoolean("paired", false); + request_passkey->SetBoolean("incoming", false); + predefined_devices->Append(request_passkey.Pass()); + + scoped_ptr<base::DictionaryValue> unconnectable(new base::DictionaryValue); + unconnectable->SetString("path", kUnconnectableDevicePath); + unconnectable->SetString("address", kUnconnectableDeviceAddress); + unconnectable->SetString("name", kUnconnectableDeviceName); + unconnectable->SetString("alias", kUnconnectableDeviceName); + unconnectable->SetString("pairingMethod", ""); + unconnectable->SetString("pairingAuthToken", ""); + unconnectable->SetString("pairingAction", ""); + unconnectable->SetInteger("classValue", kUnconnectableDeviceClass); + unconnectable->SetBoolean("isTrusted", true); + unconnectable->SetBoolean("discoverable", false); + unconnectable->SetBoolean("paired", false); + unconnectable->SetBoolean("incoming", false); + predefined_devices->Append(unconnectable.Pass()); + + scoped_ptr<base::DictionaryValue> unpairable(new base::DictionaryValue); + unpairable->SetString("path", kUnpairableDevicePath); + unpairable->SetString("address", kUnpairableDeviceAddress); + unpairable->SetString("name", kUnpairableDeviceName); + unpairable->SetString("alias", kUnpairableDeviceName); + unpairable->SetString("pairingMethod", ""); + unpairable->SetString("pairingAuthToken", ""); + unpairable->SetString("pairingAction", kPairingActionFail); + unpairable->SetInteger("classValue", kUnpairableDeviceClass); + unpairable->SetBoolean("isTrusted", false); + unpairable->SetBoolean("discoverable", false); + unpairable->SetBoolean("paired", false); + unpairable->SetBoolean("incoming", false); + predefined_devices->Append(unpairable.Pass()); + + scoped_ptr<base::DictionaryValue> just_works(new base::DictionaryValue); + just_works->SetString("path", kJustWorksPath); + just_works->SetString("address", kJustWorksAddress); + just_works->SetString("name", kJustWorksName); + just_works->SetString("alias", kJustWorksName); + just_works->SetString("pairingMethod", ""); + just_works->SetString("pairingAuthToken", ""); + just_works->SetString("pairingAction", ""); + just_works->SetInteger("classValue", kJustWorksClass); + just_works->SetBoolean("isTrusted", false); + just_works->SetBoolean("discoverable", false); + just_works->SetBoolean("paired", false); + just_works->SetBoolean("incoming", false); + predefined_devices->Append(just_works.Pass()); + + scoped_ptr<base::DictionaryValue> low_energy(new base::DictionaryValue); + low_energy->SetString("path", kLowEnergyPath); + low_energy->SetString("address", kLowEnergyAddress); + low_energy->SetString("name", kLowEnergyName); + low_energy->SetString("alias", kLowEnergyName); + low_energy->SetString("pairingMethod", ""); + low_energy->SetString("pairingAuthToken", ""); + low_energy->SetString("pairingAction", ""); + low_energy->SetInteger("classValue", kLowEnergyClass); + low_energy->SetBoolean("isTrusted", false); + low_energy->SetBoolean("discoverable", false); + low_energy->SetBoolean("paireed", false); + low_energy->SetBoolean("incoming", false); + predefined_devices->Append(low_energy.Pass()); + + scoped_ptr<base::DictionaryValue> paired_unconnectable( + new base::DictionaryValue); + paired_unconnectable->SetString("path", kPairedUnconnectableDevicePath); + paired_unconnectable->SetString("address", kPairedUnconnectableDeviceAddress); + paired_unconnectable->SetString("name", kPairedUnconnectableDeviceName); + paired_unconnectable->SetString("pairingMethod", ""); + paired_unconnectable->SetString("pairingAuthToken", ""); + paired_unconnectable->SetString("pairingAction", ""); + paired_unconnectable->SetString("alias", kPairedUnconnectableDeviceName); + paired_unconnectable->SetInteger("classValue", + kPairedUnconnectableDeviceClass); + paired_unconnectable->SetBoolean("isTrusted", false); + paired_unconnectable->SetBoolean("discoverable", true); + paired_unconnectable->SetBoolean("paired", true); + paired_unconnectable->SetBoolean("incoming", false); + predefined_devices->Append(paired_unconnectable.Pass()); + + scoped_ptr<base::DictionaryValue> connected_trusted_not_paired( + new base::DictionaryValue); + connected_trusted_not_paired->SetString("path", + kConnectedTrustedNotPairedDevicePath); + connected_trusted_not_paired->SetString( + "address", kConnectedTrustedNotPairedDeviceAddress); + connected_trusted_not_paired->SetString("name", + kConnectedTrustedNotPairedDeviceName); + connected_trusted_not_paired->SetString("pairingMethod", ""); + connected_trusted_not_paired->SetString("pairingAuthToken", ""); + connected_trusted_not_paired->SetString("pairingAction", ""); + connected_trusted_not_paired->SetString("alias", + kConnectedTrustedNotPairedDeviceName); + connected_trusted_not_paired->SetInteger( + "classValue", kConnectedTrustedNotPairedDeviceClass); + connected_trusted_not_paired->SetBoolean("isTrusted", true); + connected_trusted_not_paired->SetBoolean("discoverable", true); + connected_trusted_not_paired->SetBoolean("paired", false); + connected_trusted_not_paired->SetBoolean("incoming", false); + predefined_devices->Append(connected_trusted_not_paired.Pass()); + + return predefined_devices.Pass(); +} + +void FakeBluetoothDeviceClient::RemoveDevice( + const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path) { + std::vector<dbus::ObjectPath>::iterator listiter = + std::find(device_list_.begin(), device_list_.end(), device_path); + if (listiter == device_list_.end()) + return; + + PropertiesMap::const_iterator iter = properties_map_.find(device_path); + Properties* properties = iter->second; + + VLOG(1) << "removing device: " << properties->alias.value(); + device_list_.erase(listiter); + + // Remove the Input interface if it exists. This should be called before the + // BluetoothDeviceClient::Observer::DeviceRemoved because it deletes the + // BluetoothDeviceChromeOS object, including the device_path referenced here. + FakeBluetoothInputClient* fake_bluetooth_input_client = + static_cast<FakeBluetoothInputClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothInputClient()); + fake_bluetooth_input_client->RemoveInputDevice(device_path); + + if (device_path == dbus::ObjectPath(kLowEnergyPath)) { + FakeBluetoothGattServiceClient* gatt_service_client = + static_cast<FakeBluetoothGattServiceClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattServiceClient()); + gatt_service_client->HideHeartRateService(); + } + + FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, + DeviceRemoved(device_path)); + + properties_map_.erase(iter); + PairingOptionsMap::const_iterator options_iter = + pairing_options_map_.find(device_path); + + if (options_iter != pairing_options_map_.end()) { + pairing_options_map_.erase(options_iter); + } +} + +void FakeBluetoothDeviceClient::OnPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) { + VLOG(2) << "Fake Bluetooth device property changed: " << object_path.value() + << ": " << property_name; + FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer, observers_, + DevicePropertyChanged(object_path, property_name)); +} + +void FakeBluetoothDeviceClient::DiscoverySimulationTimer() { + if (!discovery_simulation_step_) + return; + + // Timer fires every .75s, the numbers below are arbitrary to give a feel + // for a discovery process. + VLOG(1) << "discovery simulation, step " << discovery_simulation_step_; + if (discovery_simulation_step_ == 2) { + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kLegacyAutopairPath)); + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kLowEnergyPath)); + + } else if (discovery_simulation_step_ == 4) { + UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath), + base::RandInt(kMinRSSI, kMaxRSSI)); + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kDisplayPinCodePath)); + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kVanishingDevicePath)); + + } else if (discovery_simulation_step_ == 7) { + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kConnectUnpairablePath)); + UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath), + base::RandInt(kMinRSSI, kMaxRSSI)); + + } else if (discovery_simulation_step_ == 8) { + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kDisplayPasskeyPath)); + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kRequestPinCodePath)); + UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath), + base::RandInt(kMinRSSI, kMaxRSSI)); + + } else if (discovery_simulation_step_ == 10) { + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kConfirmPasskeyPath)); + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kRequestPasskeyPath)); + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kUnconnectableDevicePath)); + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kUnpairableDevicePath)); + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kJustWorksPath)); + UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath), + base::RandInt(kMinRSSI, kMaxRSSI)); + + } else if (discovery_simulation_step_ == 13) { + UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath), + base::RandInt(kMinRSSI, kMaxRSSI)); + RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kVanishingDevicePath)); + } else if (discovery_simulation_step_ == 14) { + UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath), + base::RandInt(kMinRSSI, kMaxRSSI)); + return; + } + + ++discovery_simulation_step_; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::DiscoverySimulationTimer, + base::Unretained(this)), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); +} + +void FakeBluetoothDeviceClient::IncomingPairingSimulationTimer() { + if (!incoming_pairing_simulation_step_) + return; + + VLOG(1) << "incoming pairing simulation, step " + << incoming_pairing_simulation_step_; + switch (incoming_pairing_simulation_step_) { + case 1: + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kConfirmPasskeyPath)); + SimulatePairing(dbus::ObjectPath(kConfirmPasskeyPath), true, + base::Bind(&base::DoNothing), + base::Bind(&SimpleErrorCallback)); + break; + case 2: + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kJustWorksPath)); + SimulatePairing(dbus::ObjectPath(kJustWorksPath), true, + base::Bind(&base::DoNothing), + base::Bind(&SimpleErrorCallback)); + break; + case 3: + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kDisplayPinCodePath)); + SimulatePairing(dbus::ObjectPath(kDisplayPinCodePath), true, + base::Bind(&base::DoNothing), + base::Bind(&SimpleErrorCallback)); + break; + case 4: + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kDisplayPasskeyPath)); + SimulatePairing(dbus::ObjectPath(kDisplayPasskeyPath), true, + base::Bind(&base::DoNothing), + base::Bind(&SimpleErrorCallback)); + break; + case 5: + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kRequestPinCodePath)); + SimulatePairing(dbus::ObjectPath(kRequestPinCodePath), true, + base::Bind(&base::DoNothing), + base::Bind(&SimpleErrorCallback)); + break; + case 6: + CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(kRequestPasskeyPath)); + SimulatePairing(dbus::ObjectPath(kRequestPasskeyPath), true, + base::Bind(&base::DoNothing), + base::Bind(&SimpleErrorCallback)); + break; + default: + return; + } + + ++incoming_pairing_simulation_step_; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::IncomingPairingSimulationTimer, + base::Unretained(this)), + base::TimeDelta::FromMilliseconds(kIncomingSimulationPairTimeMultiplier * + simulation_interval_ms_)); +} + +void FakeBluetoothDeviceClient::SimulatePairing( + const dbus::ObjectPath& object_path, + bool incoming_request, + const base::Closure& callback, + const ErrorCallback& error_callback) { + pairing_cancelled_ = false; + + FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client = + static_cast<FakeBluetoothAgentManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothAgentManagerClient()); + FakeBluetoothAgentServiceProvider* agent_service_provider = + fake_bluetooth_agent_manager_client->GetAgentServiceProvider(); + CHECK(agent_service_provider != NULL); + + // Grab the device's pairing properties. + PairingOptionsMap::const_iterator iter = + pairing_options_map_.find(object_path); + + // If the device with path |object_path| has simulated pairing properties + // defined, then pair it based on its |pairing_method|. + if (iter != pairing_options_map_.end()) { + if (iter->second->pairing_action == kPairingActionFail) { + // Fails the pairing with an org.bluez.Error.Failed error. + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + } else if (iter->second->pairing_method == kPairingMethodNone || + iter->second->pairing_method.empty()) { + if (!iter->second->incoming) { + // Simply pair and connect the device. + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, + base::Unretained(this), object_path, callback, + error_callback), + base::TimeDelta::FromMilliseconds( + kSimulateNormalPairTimeMultiplier * simulation_interval_ms_)); + } else { + agent_service_provider->RequestAuthorization( + object_path, + base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback, + base::Unretained(this), object_path, callback, + error_callback)); + } + } else if (iter->second->pairing_method == kPairingMethodPinCode) { + if (iter->second->pairing_action == kPairingActionDisplay) { + // Display a Pincode, and wait before acting as if the other end + // accepted it. + agent_service_provider->DisplayPinCode( + object_path, iter->second->pairing_auth_token); + + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, + base::Unretained(this), object_path, callback, + error_callback), + base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier * + simulation_interval_ms_)); + } else if (iter->second->pairing_action == kPairingActionRequest) { + // Request a pin code. + agent_service_provider->RequestPinCode( + object_path, base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback, + base::Unretained(this), object_path, + callback, error_callback)); + } else if (iter->second->pairing_action == kPairingActionConfirmation) { + error_callback.Run(kNoResponseError, "No confirm for pincode pairing."); + } + } else if (iter->second->pairing_method == kPairingMethodPassKey) { + // Display a passkey, and each interval act as if another key was entered + // for it. + if (iter->second->pairing_action == kPairingActionDisplay) { + agent_service_provider->DisplayPasskey( + object_path, std::stoi(iter->second->pairing_auth_token), 0); + + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress, + base::Unretained(this), 1, object_path, + callback, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + } else if (iter->second->pairing_action == kPairingActionRequest) { + agent_service_provider->RequestPasskey( + object_path, base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback, + base::Unretained(this), object_path, + callback, error_callback)); + } else if (iter->second->pairing_action == kPairingActionConfirmation) { + agent_service_provider->RequestConfirmation( + object_path, std::stoi(iter->second->pairing_auth_token), + base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback, + base::Unretained(this), object_path, callback, + error_callback)); + } + } + } else { + if (object_path == dbus::ObjectPath(kLegacyAutopairPath) || + object_path == dbus::ObjectPath(kConnectUnpairablePath) || + object_path == dbus::ObjectPath(kUnconnectableDevicePath) || + object_path == dbus::ObjectPath(kLowEnergyPath)) { + // No need to call anything on the pairing delegate, just wait 3 times + // the interval before acting as if the other end accepted it. + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, + base::Unretained(this), object_path, callback, + error_callback), + base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier * + simulation_interval_ms_)); + + } else if (object_path == dbus::ObjectPath(kDisplayPinCodePath)) { + // Display a Pincode, and wait before acting as if the other end accepted + // it. + agent_service_provider->DisplayPinCode(object_path, kTestPinCode); + + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, + base::Unretained(this), object_path, callback, + error_callback), + base::TimeDelta::FromMilliseconds(kPinCodeDevicePairTimeMultiplier * + simulation_interval_ms_)); + + } else if (object_path == dbus::ObjectPath(kVanishingDevicePath)) { + // The vanishing device simulates being too far away, and thus times out. + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::TimeoutSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(kVanishingDevicePairTimeMultiplier * + simulation_interval_ms_)); + + } else if (object_path == dbus::ObjectPath(kDisplayPasskeyPath)) { + // Display a passkey, and each interval act as if another key was entered + // for it. + agent_service_provider->DisplayPasskey(object_path, kTestPassKey, 0); + + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress, + base::Unretained(this), 1, object_path, + callback, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + + } else if (object_path == dbus::ObjectPath(kRequestPinCodePath)) { + // Request a Pincode. + agent_service_provider->RequestPinCode( + object_path, base::Bind(&FakeBluetoothDeviceClient::PinCodeCallback, + base::Unretained(this), object_path, callback, + error_callback)); + + } else if (object_path == dbus::ObjectPath(kConfirmPasskeyPath) || + object_path == + dbus::ObjectPath(kConnectedTrustedNotPairedDevicePath)) { + // Request confirmation of a Passkey. + agent_service_provider->RequestConfirmation( + object_path, kTestPassKey, + base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback, + base::Unretained(this), object_path, callback, + error_callback)); + + } else if (object_path == dbus::ObjectPath(kRequestPasskeyPath)) { + // Request a Passkey from the user. + agent_service_provider->RequestPasskey( + object_path, base::Bind(&FakeBluetoothDeviceClient::PasskeyCallback, + base::Unretained(this), object_path, callback, + error_callback)); + + } else if (object_path == dbus::ObjectPath(kUnpairableDevicePath)) { + // Fails the pairing with an org.bluez.Error.Failed error. + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::FailSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + + } else if (object_path == dbus::ObjectPath(kJustWorksPath)) { + if (incoming_request) { + agent_service_provider->RequestAuthorization( + object_path, + base::Bind(&FakeBluetoothDeviceClient::ConfirmationCallback, + base::Unretained(this), object_path, callback, + error_callback)); + + } else { + // No need to call anything on the pairing delegate, just wait before + // acting as if the other end accepted it. + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, + base::Unretained(this), object_path, callback, + error_callback), + base::TimeDelta::FromMilliseconds( + kSimulateNormalPairTimeMultiplier * simulation_interval_ms_)); + } + + } else { + error_callback.Run(kNoResponseError, "No pairing fake"); + } + } +} + +void FakeBluetoothDeviceClient::CompleteSimulatedPairing( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "CompleteSimulatedPairing: " << object_path.value(); + if (pairing_cancelled_) { + pairing_cancelled_ = false; + + error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled, + "Cancelled"); + } else { + Properties* properties = GetProperties(object_path); + + properties->paired.ReplaceValue(true); + callback.Run(); + + AddInputDeviceIfNeeded(object_path, properties); + } +} + +void FakeBluetoothDeviceClient::TimeoutSimulatedPairing( + const dbus::ObjectPath& object_path, + const ErrorCallback& error_callback) { + VLOG(1) << "TimeoutSimulatedPairing: " << object_path.value(); + + error_callback.Run(bluetooth_device::kErrorAuthenticationTimeout, + "Timed out"); +} + +void FakeBluetoothDeviceClient::CancelSimulatedPairing( + const dbus::ObjectPath& object_path, + const ErrorCallback& error_callback) { + VLOG(1) << "CancelSimulatedPairing: " << object_path.value(); + + error_callback.Run(bluetooth_device::kErrorAuthenticationCanceled, + "Canceled"); +} + +void FakeBluetoothDeviceClient::RejectSimulatedPairing( + const dbus::ObjectPath& object_path, + const ErrorCallback& error_callback) { + VLOG(1) << "RejectSimulatedPairing: " << object_path.value(); + + error_callback.Run(bluetooth_device::kErrorAuthenticationRejected, + "Rejected"); +} + +void FakeBluetoothDeviceClient::FailSimulatedPairing( + const dbus::ObjectPath& object_path, + const ErrorCallback& error_callback) { + VLOG(1) << "FailSimulatedPairing: " << object_path.value(); + + error_callback.Run(bluetooth_device::kErrorFailed, "Failed"); +} + +void FakeBluetoothDeviceClient::AddInputDeviceIfNeeded( + const dbus::ObjectPath& object_path, + Properties* properties) { + // If the paired device is a HID device based on it's bluetooth class, + // simulate the Input interface. + FakeBluetoothInputClient* fake_bluetooth_input_client = + static_cast<FakeBluetoothInputClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothInputClient()); + + if ((properties->bluetooth_class.value() & 0x001f03) == 0x000500) + fake_bluetooth_input_client->AddInputDevice(object_path); +} + +void FakeBluetoothDeviceClient::UpdateDeviceRSSI( + const dbus::ObjectPath& object_path, + int16 rssi) { + PropertiesMap::const_iterator iter = properties_map_.find(object_path); + if (iter == properties_map_.end()) { + VLOG(2) << "Fake device does not exist: " << object_path.value(); + return; + } + Properties* properties = iter->second; + DCHECK(properties); + properties->rssi.ReplaceValue(rssi); +} + +void FakeBluetoothDeviceClient::UpdateConnectionInfo( + uint16 connection_rssi, + uint16 transmit_power, + uint16 max_transmit_power) { + connection_rssi_ = connection_rssi; + transmit_power_ = transmit_power; + max_transmit_power_ = max_transmit_power; +} + +void FakeBluetoothDeviceClient::PinCodeCallback( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothAgentServiceProvider::Delegate::Status status, + const std::string& pincode) { + VLOG(1) << "PinCodeCallback: " << object_path.value(); + + if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) { + PairingOptionsMap::const_iterator iter = + pairing_options_map_.find(object_path); + + bool success = true; + + // If the device has pairing options defined + if (iter != pairing_options_map_.end()) { + success = iter->second->pairing_auth_token == pincode; + } + + if (success) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, + base::Unretained(this), object_path, callback, + error_callback), + base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier * + simulation_interval_ms_)); + } else { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + } + + } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + + } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + } +} + +void FakeBluetoothDeviceClient::PasskeyCallback( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothAgentServiceProvider::Delegate::Status status, + uint32 passkey) { + VLOG(1) << "PasskeyCallback: " << object_path.value(); + + if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) { + PairingOptionsMap::const_iterator iter = + pairing_options_map_.find(object_path); + bool success = true; + + if (iter != pairing_options_map_.end()) { + success = static_cast<uint32>( + std::stoi(iter->second->pairing_auth_token)) == passkey; + } + + if (success) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, + base::Unretained(this), object_path, callback, + error_callback), + base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier * + simulation_interval_ms_)); + } else { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + } + + } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + + } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + } +} + +void FakeBluetoothDeviceClient::ConfirmationCallback( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothAgentServiceProvider::Delegate::Status status) { + VLOG(1) << "ConfirmationCallback: " << object_path.value(); + + if (status == BluetoothAgentServiceProvider::Delegate::SUCCESS) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, + base::Unretained(this), object_path, callback, + error_callback), + base::TimeDelta::FromMilliseconds(kSimulateNormalPairTimeMultiplier * + simulation_interval_ms_)); + + } else if (status == BluetoothAgentServiceProvider::Delegate::CANCELLED) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CancelSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + + } else if (status == BluetoothAgentServiceProvider::Delegate::REJECTED) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::RejectSimulatedPairing, + base::Unretained(this), object_path, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + } +} + +void FakeBluetoothDeviceClient::SimulateKeypress( + uint16 entered, + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "SimulateKeypress " << entered << ": " << object_path.value(); + + FakeBluetoothAgentManagerClient* fake_bluetooth_agent_manager_client = + static_cast<FakeBluetoothAgentManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothAgentManagerClient()); + FakeBluetoothAgentServiceProvider* agent_service_provider = + fake_bluetooth_agent_manager_client->GetAgentServiceProvider(); + + // The agent service provider object could have been destroyed after the + // pairing is canceled. + if (!agent_service_provider) + return; + + agent_service_provider->DisplayPasskey(object_path, kTestPassKey, entered); + + if (entered < 7) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::Bind(&FakeBluetoothDeviceClient::SimulateKeypress, + base::Unretained(this), entered + 1, object_path, + callback, error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + + } else { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&FakeBluetoothDeviceClient::CompleteSimulatedPairing, + base::Unretained(this), object_path, callback, + error_callback), + base::TimeDelta::FromMilliseconds(simulation_interval_ms_)); + } +} + +void FakeBluetoothDeviceClient::ConnectionCallback( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothProfileServiceProvider::Delegate::Status status) { + VLOG(1) << "ConnectionCallback: " << object_path.value(); + + if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) { + callback.Run(); + } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) { + // TODO(keybuk): tear down this side of the connection + error_callback.Run(bluetooth_device::kErrorFailed, "Canceled"); + } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) { + // TODO(keybuk): tear down this side of the connection + error_callback.Run(bluetooth_device::kErrorFailed, "Rejected"); + } +} + +void FakeBluetoothDeviceClient::DisconnectionCallback( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothProfileServiceProvider::Delegate::Status status) { + VLOG(1) << "DisconnectionCallback: " << object_path.value(); + + if (status == BluetoothProfileServiceProvider::Delegate::SUCCESS) { + // TODO(keybuk): tear down this side of the connection + callback.Run(); + } else if (status == BluetoothProfileServiceProvider::Delegate::CANCELLED) { + error_callback.Run(bluetooth_device::kErrorFailed, "Canceled"); + } else if (status == BluetoothProfileServiceProvider::Delegate::REJECTED) { + error_callback.Run(bluetooth_device::kErrorFailed, "Rejected"); + } +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_device_client.h b/device/bluetooth/dbus/fake_bluetooth_device_client.h new file mode 100644 index 0000000..f8051b4 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_device_client.h @@ -0,0 +1,321 @@ +// Copyright (c) 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_DEVICE_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_DEVICE_CLIENT_H_ + +#include <map> +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/containers/scoped_ptr_map.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h" +#include "device/bluetooth/dbus/bluetooth_device_client.h" +#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" + +namespace bluez { + +// FakeBluetoothDeviceClient simulates the behavior of the Bluetooth Daemon +// device objects and is used both in test cases in place of a mock and on +// the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothDeviceClient + : public BluetoothDeviceClient { + public: + struct Properties : public BluetoothDeviceClient::Properties { + explicit Properties(const PropertyChangedCallback& callback); + ~Properties() override; + + // dbus::PropertySet override + void Get(dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) override; + void GetAll() override; + void Set(dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) override; + }; + + struct SimulatedPairingOptions { + SimulatedPairingOptions(); + ~SimulatedPairingOptions(); + + bool incoming = false; + std::string pairing_method; + std::string pairing_auth_token; + std::string pairing_action; + }; + + // Stores properties of a device that is about to be created. + struct IncomingDeviceProperties { + IncomingDeviceProperties(); + ~IncomingDeviceProperties(); + + std::string device_address; + std::string device_alias; + int device_class = 0; + std::string device_name; + std::string device_path; + bool is_trusted = true; + bool incoming = false; + std::string pairing_action; + std::string pairing_auth_token; + std::string pairing_method; + }; + + FakeBluetoothDeviceClient(); + ~FakeBluetoothDeviceClient() override; + + // BluetoothDeviceClient overrides + void Init(dbus::Bus* bus) override; + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + std::vector<dbus::ObjectPath> GetDevicesForAdapter( + const dbus::ObjectPath& adapter_path) override; + Properties* GetProperties(const dbus::ObjectPath& object_path) override; + void Connect(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void Disconnect(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void ConnectProfile(const dbus::ObjectPath& object_path, + const std::string& uuid, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void DisconnectProfile(const dbus::ObjectPath& object_path, + const std::string& uuid, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void Pair(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void CancelPairing(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void GetConnInfo(const dbus::ObjectPath& object_path, + const ConnInfoCallback& callback, + const ErrorCallback& error_callback) override; + + void SetSimulationIntervalMs(int interval_ms); + + // Simulates discovery of devices for the given adapter. + void BeginDiscoverySimulation(const dbus::ObjectPath& adapter_path); + void EndDiscoverySimulation(const dbus::ObjectPath& adapter_path); + + // Simulates incoming pairing of devices for the given adapter. + void BeginIncomingPairingSimulation(const dbus::ObjectPath& adapter_path); + void EndIncomingPairingSimulation(const dbus::ObjectPath& adapter_path); + + // Creates a device from the set we return for the given adapter. + void CreateDevice(const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path); + + // Creates a device with the given properties. + void CreateDeviceWithProperties(const dbus::ObjectPath& adapter_path, + const IncomingDeviceProperties& props); + + // Creates and returns a list of scoped_ptr<base::DictionaryValue> + // objects, which contain all the data from the constants for devices with + // predefined behavior. + scoped_ptr<base::ListValue> GetBluetoothDevicesAsDictionaries() const; + + SimulatedPairingOptions* GetPairingOptions( + const dbus::ObjectPath& object_path); + + // Removes a device from the set we return for the given adapter. + void RemoveDevice(const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path); + + // Simulates a pairing for the device with the given D-Bus object path, + // |object_path|. Set |incoming_request| to true if simulating an incoming + // pairing request, false for an outgoing one. On successful completion + // |callback| will be called, on failure, |error_callback| is called. + void SimulatePairing(const dbus::ObjectPath& object_path, + bool incoming_request, + const base::Closure& callback, + const ErrorCallback& error_callback); + + // Updates the connection properties of the fake device that will be returned + // by GetConnInfo. + void UpdateConnectionInfo(uint16 connection_rssi, + uint16 transmit_power, + uint16 max_transmit_power); + + static const char kTestPinCode[]; + static const int kTestPassKey; + + static const char kPairingMethodNone[]; + static const char kPairingMethodPinCode[]; + static const char kPairingMethodPassKey[]; + + static const char kPairingActionConfirmation[]; + static const char kPairingActionDisplay[]; + static const char kPairingActionFail[]; + static const char kPairingActionRequest[]; + + // Object paths, names, addresses and bluetooth classes of the devices + // we can emulate. + static const char kPairedDevicePath[]; + static const char kPairedDeviceName[]; + static const char kPairedDeviceAddress[]; + static const uint32 kPairedDeviceClass; + + static const char kLegacyAutopairPath[]; + static const char kLegacyAutopairName[]; + static const char kLegacyAutopairAddress[]; + static const uint32 kLegacyAutopairClass; + + static const char kDisplayPinCodePath[]; + static const char kDisplayPinCodeName[]; + static const char kDisplayPinCodeAddress[]; + static const uint32 kDisplayPinCodeClass; + + static const char kVanishingDevicePath[]; + static const char kVanishingDeviceName[]; + static const char kVanishingDeviceAddress[]; + static const uint32 kVanishingDeviceClass; + + static const char kConnectUnpairablePath[]; + static const char kConnectUnpairableName[]; + static const char kConnectUnpairableAddress[]; + static const uint32 kConnectUnpairableClass; + + static const char kDisplayPasskeyPath[]; + static const char kDisplayPasskeyName[]; + static const char kDisplayPasskeyAddress[]; + static const uint32 kDisplayPasskeyClass; + + static const char kRequestPinCodePath[]; + static const char kRequestPinCodeName[]; + static const char kRequestPinCodeAddress[]; + static const uint32 kRequestPinCodeClass; + + static const char kConfirmPasskeyPath[]; + static const char kConfirmPasskeyName[]; + static const char kConfirmPasskeyAddress[]; + static const uint32 kConfirmPasskeyClass; + + static const char kRequestPasskeyPath[]; + static const char kRequestPasskeyName[]; + static const char kRequestPasskeyAddress[]; + static const uint32 kRequestPasskeyClass; + + static const char kUnconnectableDevicePath[]; + static const char kUnconnectableDeviceName[]; + static const char kUnconnectableDeviceAddress[]; + static const uint32 kUnconnectableDeviceClass; + + static const char kUnpairableDevicePath[]; + static const char kUnpairableDeviceName[]; + static const char kUnpairableDeviceAddress[]; + static const uint32 kUnpairableDeviceClass; + + static const char kJustWorksPath[]; + static const char kJustWorksName[]; + static const char kJustWorksAddress[]; + static const uint32 kJustWorksClass; + + static const char kLowEnergyPath[]; + static const char kLowEnergyName[]; + static const char kLowEnergyAddress[]; + static const uint32 kLowEnergyClass; + + static const char kPairedUnconnectableDevicePath[]; + static const char kPairedUnconnectableDeviceName[]; + static const char kPairedUnconnectableDeviceAddress[]; + static const uint32 kPairedUnconnectableDeviceClass; + + static const char kConnectedTrustedNotPairedDevicePath[]; + static const char kConnectedTrustedNotPairedDeviceAddress[]; + static const char kConnectedTrustedNotPairedDeviceName[]; + static const uint32 kConnectedTrustedNotPairedDeviceClass; + + private: + // Property callback passed when we create Properties* structures. + void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name); + + void DiscoverySimulationTimer(); + void IncomingPairingSimulationTimer(); + + void CompleteSimulatedPairing(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback); + void TimeoutSimulatedPairing(const dbus::ObjectPath& object_path, + const ErrorCallback& error_callback); + void CancelSimulatedPairing(const dbus::ObjectPath& object_path, + const ErrorCallback& error_callback); + void RejectSimulatedPairing(const dbus::ObjectPath& object_path, + const ErrorCallback& error_callback); + void FailSimulatedPairing(const dbus::ObjectPath& object_path, + const ErrorCallback& error_callback); + void AddInputDeviceIfNeeded(const dbus::ObjectPath& object_path, + Properties* properties); + + // Updates the inquiry RSSI property of fake device with object path + // |object_path| to |rssi|, if the fake device exists. + void UpdateDeviceRSSI(const dbus::ObjectPath& object_path, int16 rssi); + + void PinCodeCallback(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothAgentServiceProvider::Delegate::Status status, + const std::string& pincode); + void PasskeyCallback(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothAgentServiceProvider::Delegate::Status status, + uint32 passkey); + void ConfirmationCallback( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothAgentServiceProvider::Delegate::Status status); + void SimulateKeypress(uint16 entered, + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback); + + void ConnectionCallback( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothProfileServiceProvider::Delegate::Status status); + void DisconnectionCallback( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback, + BluetoothProfileServiceProvider::Delegate::Status status); + + // List of observers interested in event notifications from us. + base::ObserverList<Observer> observers_; + + using PropertiesMap = + base::ScopedPtrMap<const dbus::ObjectPath, scoped_ptr<Properties>>; + PropertiesMap properties_map_; + std::vector<dbus::ObjectPath> device_list_; + + // Properties which are used to decied which method of pairing should + // be done on request. + using PairingOptionsMap = + base::ScopedPtrMap<const dbus::ObjectPath, + scoped_ptr<SimulatedPairingOptions>>; + PairingOptionsMap pairing_options_map_; + + int simulation_interval_ms_; + uint32_t discovery_simulation_step_; + uint32_t incoming_pairing_simulation_step_; + bool pairing_cancelled_; + + int16 connection_rssi_; + int16 transmit_power_; + int16 max_transmit_power_; +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_DEVICE_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc new file mode 100644 index 0000000..10f073a --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc @@ -0,0 +1,562 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/rand_util.h" +#include "base/single_thread_task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +namespace { + +const int kStartNotifyResponseIntervalMs = 200; +const int kHeartRateMeasurementNotificationIntervalMs = 2000; + +} // namespace + +FakeBluetoothGattCharacteristicClient::DelayedCallback::DelayedCallback( + base::Closure callback, + size_t delay) + : callback_(callback), delay_(delay) {} + +FakeBluetoothGattCharacteristicClient::DelayedCallback::~DelayedCallback() {} + +// static +const char FakeBluetoothGattCharacteristicClient:: + kHeartRateMeasurementPathComponent[] = "char0000"; +const char + FakeBluetoothGattCharacteristicClient::kBodySensorLocationPathComponent[] = + "char0001"; +const char FakeBluetoothGattCharacteristicClient:: + kHeartRateControlPointPathComponent[] = "char0002"; + +// static +const char FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID[] = + "00002a37-0000-1000-8000-00805f9b34fb"; +const char FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID[] = + "00002a38-0000-1000-8000-00805f9b34fb"; +const char FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID[] = + "00002a39-0000-1000-8000-00805f9b34fb"; + +FakeBluetoothGattCharacteristicClient::Properties::Properties( + const PropertyChangedCallback& callback) + : BluetoothGattCharacteristicClient::Properties( + NULL, + bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface, + callback) {} + +FakeBluetoothGattCharacteristicClient::Properties::~Properties() {} + +void FakeBluetoothGattCharacteristicClient::Properties::Get( + dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) { + VLOG(1) << "Get " << property->name(); + callback.Run(true); +} + +void FakeBluetoothGattCharacteristicClient::Properties::GetAll() { + VLOG(1) << "GetAll"; +} + +void FakeBluetoothGattCharacteristicClient::Properties::Set( + dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) { + VLOG(1) << "Set " << property->name(); + callback.Run(false); +} + +FakeBluetoothGattCharacteristicClient::FakeBluetoothGattCharacteristicClient() + : heart_rate_visible_(false), + authorized_(true), + authenticated_(true), + calories_burned_(0), + extra_requests_(0), + weak_ptr_factory_(this) {} + +FakeBluetoothGattCharacteristicClient:: + ~FakeBluetoothGattCharacteristicClient() { + for (const auto& it : action_extra_requests_) { + delete it.second; + } + action_extra_requests_.clear(); +} + +void FakeBluetoothGattCharacteristicClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothGattCharacteristicClient::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeBluetoothGattCharacteristicClient::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +std::vector<dbus::ObjectPath> +FakeBluetoothGattCharacteristicClient::GetCharacteristics() { + std::vector<dbus::ObjectPath> paths; + if (IsHeartRateVisible()) { + paths.push_back(dbus::ObjectPath(heart_rate_measurement_path_)); + paths.push_back(dbus::ObjectPath(body_sensor_location_path_)); + paths.push_back(dbus::ObjectPath(heart_rate_control_point_path_)); + } + return paths; +} + +FakeBluetoothGattCharacteristicClient::Properties* +FakeBluetoothGattCharacteristicClient::GetProperties( + const dbus::ObjectPath& object_path) { + if (object_path.value() == heart_rate_measurement_path_) { + DCHECK(heart_rate_measurement_properties_.get()); + return heart_rate_measurement_properties_.get(); + } + if (object_path.value() == body_sensor_location_path_) { + DCHECK(body_sensor_location_properties_.get()); + return body_sensor_location_properties_.get(); + } + if (object_path.value() == heart_rate_control_point_path_) { + DCHECK(heart_rate_control_point_properties_.get()); + return heart_rate_control_point_properties_.get(); + } + return NULL; +} + +void FakeBluetoothGattCharacteristicClient::ReadValue( + const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const ErrorCallback& error_callback) { + if (!authenticated_) { + error_callback.Run("org.bluez.Error.NotPaired", "Please login"); + return; + } + + if (!authorized_) { + error_callback.Run("org.bluez.Error.NotAuthorized", "Authorize first"); + return; + } + + if (object_path.value() == heart_rate_control_point_path_) { + error_callback.Run("org.bluez.Error.NotPermitted", + "Reads of this value are not allowed"); + return; + } + + if (object_path.value() == heart_rate_measurement_path_) { + error_callback.Run("org.bluez.Error.NotSupported", + "Action not supported on this characteristic"); + return; + } + + if (object_path.value() != body_sensor_location_path_) { + error_callback.Run(kUnknownCharacteristicError, ""); + return; + } + + if (action_extra_requests_.find("ReadValue") != + action_extra_requests_.end()) { + DelayedCallback* delayed = action_extra_requests_["ReadValue"]; + delayed->delay_--; + error_callback.Run("org.bluez.Error.InProgress", + "Another read is currenty in progress"); + if (delayed->delay_ == 0) { + delayed->callback_.Run(); + action_extra_requests_.erase("ReadValue"); + delete delayed; + } + return; + } + + base::Closure completed_callback; + if (!IsHeartRateVisible()) { + completed_callback = + base::Bind(error_callback, kUnknownCharacteristicError, ""); + } else { + std::vector<uint8> value = {0x06}; // Location is "foot". + completed_callback = base::Bind( + &FakeBluetoothGattCharacteristicClient::DelayedReadValueCallback, + weak_ptr_factory_.GetWeakPtr(), object_path, callback, value); + } + + if (extra_requests_ > 0) { + action_extra_requests_["ReadValue"] = + new DelayedCallback(completed_callback, extra_requests_); + return; + } + + completed_callback.Run(); +} + +void FakeBluetoothGattCharacteristicClient::WriteValue( + const dbus::ObjectPath& object_path, + const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (!authenticated_) { + error_callback.Run("org.bluez.Error.NotPaired", "Please login"); + return; + } + + if (!authorized_) { + error_callback.Run("org.bluez.Error.NotAuthorized", "Authorize first"); + return; + } + + if (!IsHeartRateVisible()) { + error_callback.Run(kUnknownCharacteristicError, ""); + return; + } + + if (object_path.value() == heart_rate_measurement_path_) { + error_callback.Run("org.bluez.Error.NotSupported", + "Action not supported on this characteristic"); + return; + } + + if (object_path.value() != heart_rate_control_point_path_) { + error_callback.Run("org.bluez.Error.NotPermitted", + "Writes of this value are not allowed"); + return; + } + + DCHECK(heart_rate_control_point_properties_.get()); + if (action_extra_requests_.find("WriteValue") != + action_extra_requests_.end()) { + DelayedCallback* delayed = action_extra_requests_["WriteValue"]; + delayed->delay_--; + error_callback.Run("org.bluez.Error.InProgress", + "Another write is in progress"); + if (delayed->delay_ == 0) { + delayed->callback_.Run(); + action_extra_requests_.erase("WriteValue"); + delete delayed; + } + return; + } + base::Closure completed_callback; + if (value.size() != 1) { + completed_callback = + base::Bind(error_callback, "org.bluez.Error.InvalidValueLength", + "Invalid length for write"); + } else if (value[0] > 1) { + completed_callback = base::Bind(error_callback, "org.bluez.Error.Failed", + "Invalid value given for write"); + } else if (value[0] == 1) { + // TODO(jamuraa): make this happen when the callback happens + calories_burned_ = 0; + completed_callback = callback; + } + + if (extra_requests_ > 0) { + action_extra_requests_["WriteValue"] = + new DelayedCallback(completed_callback, extra_requests_); + return; + } + completed_callback.Run(); +} + +void FakeBluetoothGattCharacteristicClient::StartNotify( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (!IsHeartRateVisible()) { + error_callback.Run(kUnknownCharacteristicError, ""); + return; + } + + if (object_path.value() != heart_rate_measurement_path_) { + error_callback.Run("org.bluez.Error.NotSupported", + "This characteristic does not support notifications"); + return; + } + + if (heart_rate_measurement_properties_->notifying.value()) { + error_callback.Run("org.bluez.Error.InProgress", + "Characteristic already notifying"); + return; + } + + heart_rate_measurement_properties_->notifying.ReplaceValue(true); + ScheduleHeartRateMeasurementValueChange(); + + // Respond asynchronously. + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, callback, + base::TimeDelta::FromMilliseconds(kStartNotifyResponseIntervalMs)); +} + +void FakeBluetoothGattCharacteristicClient::StopNotify( + const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (!IsHeartRateVisible()) { + error_callback.Run(kUnknownCharacteristicError, ""); + return; + } + + if (object_path.value() != heart_rate_measurement_path_) { + error_callback.Run("org.bluez.Error.NotSupported", + "This characteristic does not support notifications"); + return; + } + + if (!heart_rate_measurement_properties_->notifying.value()) { + error_callback.Run("org.bluez.Error.Failed", "Not notifying"); + return; + } + + heart_rate_measurement_properties_->notifying.ReplaceValue(false); + + callback.Run(); +} + +void FakeBluetoothGattCharacteristicClient::ExposeHeartRateCharacteristics( + const dbus::ObjectPath& service_path) { + if (IsHeartRateVisible()) { + VLOG(2) << "Fake Heart Rate characteristics are already visible."; + return; + } + + VLOG(2) << "Exposing fake Heart Rate characteristics."; + + std::vector<std::string> flags; + + // ==== Heart Rate Measurement Characteristic ==== + heart_rate_measurement_path_ = + service_path.value() + "/" + kHeartRateMeasurementPathComponent; + heart_rate_measurement_properties_.reset(new Properties( + base::Bind(&FakeBluetoothGattCharacteristicClient::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), + dbus::ObjectPath(heart_rate_measurement_path_)))); + heart_rate_measurement_properties_->uuid.ReplaceValue( + kHeartRateMeasurementUUID); + heart_rate_measurement_properties_->service.ReplaceValue(service_path); + flags.push_back(bluetooth_gatt_characteristic::kFlagNotify); + heart_rate_measurement_properties_->flags.ReplaceValue(flags); + + // ==== Body Sensor Location Characteristic ==== + body_sensor_location_path_ = + service_path.value() + "/" + kBodySensorLocationPathComponent; + body_sensor_location_properties_.reset(new Properties( + base::Bind(&FakeBluetoothGattCharacteristicClient::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), + dbus::ObjectPath(body_sensor_location_path_)))); + body_sensor_location_properties_->uuid.ReplaceValue(kBodySensorLocationUUID); + body_sensor_location_properties_->service.ReplaceValue(service_path); + flags.clear(); + flags.push_back(bluetooth_gatt_characteristic::kFlagRead); + body_sensor_location_properties_->flags.ReplaceValue(flags); + + // ==== Heart Rate Control Point Characteristic ==== + heart_rate_control_point_path_ = + service_path.value() + "/" + kHeartRateControlPointPathComponent; + heart_rate_control_point_properties_.reset(new Properties( + base::Bind(&FakeBluetoothGattCharacteristicClient::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), + dbus::ObjectPath(heart_rate_control_point_path_)))); + heart_rate_control_point_properties_->uuid.ReplaceValue( + kHeartRateControlPointUUID); + heart_rate_control_point_properties_->service.ReplaceValue(service_path); + flags.clear(); + flags.push_back(bluetooth_gatt_characteristic::kFlagWrite); + heart_rate_control_point_properties_->flags.ReplaceValue(flags); + + heart_rate_visible_ = true; + + NotifyCharacteristicAdded(dbus::ObjectPath(heart_rate_measurement_path_)); + NotifyCharacteristicAdded(dbus::ObjectPath(body_sensor_location_path_)); + NotifyCharacteristicAdded(dbus::ObjectPath(heart_rate_control_point_path_)); + + // Expose CCC descriptor for Heart Rate Measurement characteristic. + FakeBluetoothGattDescriptorClient* descriptor_client = + static_cast<FakeBluetoothGattDescriptorClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattDescriptorClient()); + dbus::ObjectPath ccc_path(descriptor_client->ExposeDescriptor( + dbus::ObjectPath(heart_rate_measurement_path_), + FakeBluetoothGattDescriptorClient:: + kClientCharacteristicConfigurationUUID)); + DCHECK(ccc_path.IsValid()); + heart_rate_measurement_ccc_desc_path_ = ccc_path.value(); + + std::vector<dbus::ObjectPath> desc_paths; + desc_paths.push_back(ccc_path); + + heart_rate_measurement_properties_->descriptors.ReplaceValue(desc_paths); +} + +void FakeBluetoothGattCharacteristicClient::HideHeartRateCharacteristics() { + VLOG(2) << "Hiding fake Heart Rate characteristics."; + + // Hide the descriptors. + FakeBluetoothGattDescriptorClient* descriptor_client = + static_cast<FakeBluetoothGattDescriptorClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattDescriptorClient()); + descriptor_client->HideDescriptor( + dbus::ObjectPath(heart_rate_measurement_ccc_desc_path_)); + + // Notify the observers before deleting the properties structures so that they + // can be accessed from the observer method. + NotifyCharacteristicRemoved(dbus::ObjectPath(heart_rate_measurement_path_)); + NotifyCharacteristicRemoved(dbus::ObjectPath(body_sensor_location_path_)); + NotifyCharacteristicRemoved(dbus::ObjectPath(heart_rate_control_point_path_)); + + heart_rate_measurement_properties_.reset(); + body_sensor_location_properties_.reset(); + heart_rate_control_point_properties_.reset(); + + heart_rate_measurement_path_.clear(); + body_sensor_location_path_.clear(); + heart_rate_control_point_path_.clear(); + heart_rate_visible_ = false; +} + +void FakeBluetoothGattCharacteristicClient::SetExtraProcessing( + size_t requests) { + extra_requests_ = requests; + if (extra_requests_ == 0) { + for (const auto& it : action_extra_requests_) { + it.second->callback_.Run(); + delete it.second; + } + action_extra_requests_.clear(); + return; + } + VLOG(2) << "Requests SLOW now, " << requests << " InProgress errors each."; +} + +size_t FakeBluetoothGattCharacteristicClient::GetExtraProcessing() const { + return extra_requests_; +} + +dbus::ObjectPath +FakeBluetoothGattCharacteristicClient::GetHeartRateMeasurementPath() const { + return dbus::ObjectPath(heart_rate_measurement_path_); +} + +dbus::ObjectPath +FakeBluetoothGattCharacteristicClient::GetBodySensorLocationPath() const { + return dbus::ObjectPath(body_sensor_location_path_); +} + +dbus::ObjectPath +FakeBluetoothGattCharacteristicClient::GetHeartRateControlPointPath() const { + return dbus::ObjectPath(heart_rate_control_point_path_); +} + +void FakeBluetoothGattCharacteristicClient::OnPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) { + VLOG(2) << "Characteristic property changed: " << object_path.value() << ": " + << property_name; + + FOR_EACH_OBSERVER( + BluetoothGattCharacteristicClient::Observer, observers_, + GattCharacteristicPropertyChanged(object_path, property_name)); +} + +void FakeBluetoothGattCharacteristicClient::NotifyCharacteristicAdded( + const dbus::ObjectPath& object_path) { + VLOG(2) << "GATT characteristic added: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_, + GattCharacteristicAdded(object_path)); +} + +void FakeBluetoothGattCharacteristicClient::NotifyCharacteristicRemoved( + const dbus::ObjectPath& object_path) { + VLOG(2) << "GATT characteristic removed: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_, + GattCharacteristicRemoved(object_path)); +} + +void FakeBluetoothGattCharacteristicClient:: + ScheduleHeartRateMeasurementValueChange() { + if (!IsHeartRateVisible()) + return; + + // Don't send updates if the characteristic is not notifying. + if (!heart_rate_measurement_properties_->notifying.value()) + return; + + VLOG(2) << "Updating heart rate value."; + std::vector<uint8> measurement = GetHeartRateMeasurementValue(); + heart_rate_measurement_properties_->value.ReplaceValue(measurement); + + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::Bind(&FakeBluetoothGattCharacteristicClient:: + ScheduleHeartRateMeasurementValueChange, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds( + kHeartRateMeasurementNotificationIntervalMs)); +} + +void FakeBluetoothGattCharacteristicClient::DelayedReadValueCallback( + const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const std::vector<uint8_t>& value) { + Properties* properties = GetProperties(object_path); + DCHECK(properties); + + properties->value.ReplaceValue(value); + callback.Run(value); +} + +std::vector<uint8> +FakeBluetoothGattCharacteristicClient::GetHeartRateMeasurementValue() { + // TODO(armansito): We should make sure to properly pack this struct to ensure + // correct byte alignment and endianness. It doesn't matter too much right now + // as this is a fake and GCC on Linux seems to do the right thing. + struct { + uint8 flags; + uint8 bpm; + uint16 energy_expanded; + uint16 rr_interval; + } value; + + // Flags in LSB: 0 11 1 1 000 + // | | | | | + // 8-bit bpm format -- | | | | + // Sensor contact supported -- | | | + // Energy expanded field present -- | | + // RR-Interval values present ------- | + // Reserved for future use ------------ + value.flags = 0x0; + value.flags |= (0x03 << 1); + value.flags |= (0x01 << 3); + value.flags |= (0x01 << 4); + + // Pick a value between 117 bpm and 153 bpm for heart rate. + value.bpm = static_cast<uint8>(base::RandInt(117, 153)); + + // Total calories burned in kJoules since the last reset. Increment this by 1 + // every time. It's fine if it overflows: it becomes 0 when the user resets + // the heart rate monitor (or pretend that he had a lot of cheeseburgers). + value.energy_expanded = calories_burned_++; + + // Include one RR-Interval value, in seconds. + value.rr_interval = 60 / value.bpm; + + // Return the bytes in an array. + uint8* bytes = reinterpret_cast<uint8*>(&value); + std::vector<uint8> return_value; + return_value.assign(bytes, bytes + sizeof(value)); + return return_value; +} + +bool FakeBluetoothGattCharacteristicClient::IsHeartRateVisible() const { + DCHECK(heart_rate_visible_ != heart_rate_measurement_path_.empty()); + DCHECK(heart_rate_visible_ != body_sensor_location_path_.empty()); + DCHECK(heart_rate_visible_ != heart_rate_control_point_path_.empty()); + DCHECK(heart_rate_visible_ == !!heart_rate_measurement_properties_.get()); + DCHECK(heart_rate_visible_ == !!body_sensor_location_properties_.get()); + DCHECK(heart_rate_visible_ == !!heart_rate_control_point_properties_.get()); + return heart_rate_visible_; +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h new file mode 100644 index 0000000..89fefcc --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h @@ -0,0 +1,194 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" + +namespace bluez { + +// FakeBluetoothGattCharacteristicClient simulates the behavior of the +// Bluetooth Daemon GATT characteristic objects and is used in test cases in +// place of a mock and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattCharacteristicClient + : public BluetoothGattCharacteristicClient { + public: + struct Properties : public BluetoothGattCharacteristicClient::Properties { + explicit Properties(const PropertyChangedCallback& callback); + ~Properties() override; + + // dbus::PropertySet override + void Get(dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) override; + void GetAll() override; + void Set(dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) override; + }; + + FakeBluetoothGattCharacteristicClient(); + ~FakeBluetoothGattCharacteristicClient() override; + + // DBusClient override. + void Init(dbus::Bus* bus) override; + + // BluetoothGattCharacteristicClient overrides. + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + std::vector<dbus::ObjectPath> GetCharacteristics() override; + Properties* GetProperties(const dbus::ObjectPath& object_path) override; + void ReadValue(const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const ErrorCallback& error_callback) override; + void WriteValue(const dbus::ObjectPath& object_path, + const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void StartNotify(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void StopNotify(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Makes the group of characteristics belonging to a particular GATT based + // profile available under the GATT service with object path |service_path|. + // Characteristic paths are hierarchical to service paths. + void ExposeHeartRateCharacteristics(const dbus::ObjectPath& service_path); + void HideHeartRateCharacteristics(); + + // Returns whether or not the heart rate characteristics are visible and + // performs the appropriate assertions. + bool IsHeartRateVisible() const; + + // Makes this characteristic client really slow. + // So slow, that it is guaranteed that |requests| requests will + // come in while the client is doing the previous request. + // Setting |requests| to zero will cause all delayed actions to + // complete immediately. + void SetExtraProcessing(size_t requests); + + size_t GetExtraProcessing() const; + + // Sets whether the client is authorized or not. + // Defaults to authorized. + void SetAuthorized(bool authorized) { authorized_ = authorized; } + + // Get the current Authorization state. + bool IsAuthorized() const { return authorized_; } + + // Whether the client is Authenticated + // Defaults to authenticated. + void SetAuthenticated(bool authenticated) { authenticated_ = authenticated; } + + // Get the current Authenticated state. + bool IsAuthenticated() const { return authenticated_; } + + // Returns the current object paths of exposed characteristics. If the + // characteristic is not visible, returns an invalid empty path. + dbus::ObjectPath GetHeartRateMeasurementPath() const; + dbus::ObjectPath GetBodySensorLocationPath() const; + dbus::ObjectPath GetHeartRateControlPointPath() const; + + // Object path components and UUIDs of GATT characteristics. + // Heart Rate Service: + static const char kHeartRateMeasurementPathComponent[]; + static const char kHeartRateMeasurementUUID[]; + static const char kBodySensorLocationPathComponent[]; + static const char kBodySensorLocationUUID[]; + static const char kHeartRateControlPointPathComponent[]; + static const char kHeartRateControlPointUUID[]; + + private: + // Property callback passed when we create Properties structures. + void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name); + + // Notifies observers. + void NotifyCharacteristicAdded(const dbus::ObjectPath& object_path); + void NotifyCharacteristicRemoved(const dbus::ObjectPath& object_path); + + // Schedules a heart rate measurement value change, if the heart rate + // characteristics are visible. + void ScheduleHeartRateMeasurementValueChange(); + + // Returns a random Heart Rate Measurement value. All the fields of the value + // are populated according to the the fake behavior. The measurement value + // is a random value within a reasonable range. + std::vector<uint8> GetHeartRateMeasurementValue(); + + // Callback that executes a delayed ReadValue action by updating the + // appropriate "Value" property and invoking the ValueCallback. + void DelayedReadValueCallback(const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const std::vector<uint8_t>& value); + + // If true, characteristics of the Heart Rate Service are visible. Use + // IsHeartRateVisible() to check the value. + bool heart_rate_visible_; + + // If true, the client is authorized to read and write. + bool authorized_; + + // If true, the client is authenticated. + bool authenticated_; + + // Total calories burned, used for the Heart Rate Measurement characteristic. + uint16 calories_burned_; + + // Static properties returned for simulated characteristics for the Heart + // Rate Service. These pointers are not NULL only if the characteristics are + // actually exposed. + scoped_ptr<Properties> heart_rate_measurement_properties_; + scoped_ptr<Properties> body_sensor_location_properties_; + scoped_ptr<Properties> heart_rate_control_point_properties_; + + // Object paths of the exposed characteristics. If a characteristic is not + // exposed, these will be empty. + std::string heart_rate_measurement_path_; + std::string heart_rate_measurement_ccc_desc_path_; + std::string body_sensor_location_path_; + std::string heart_rate_control_point_path_; + + // Number of extra requests that need to come in simulating slowness. + size_t extra_requests_; + + // Current countdowns for extra requests for various actions. + struct DelayedCallback { + public: + DelayedCallback(base::Closure callback, size_t delay); + ~DelayedCallback(); + + base::Closure callback_; + size_t delay_; + }; + + // Map of delayed callbacks. + std::map<std::string, DelayedCallback*> action_extra_requests_; + + // List of observers interested in event notifications from us. + base::ObserverList<Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<FakeBluetoothGattCharacteristicClient> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattCharacteristicClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc new file mode 100644 index 0000000..03f06d0 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.cc @@ -0,0 +1,105 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h" + +#include "base/logging.h" +#include "base/strings/string_util.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h" + +namespace bluez { + +FakeBluetoothGattCharacteristicServiceProvider:: + FakeBluetoothGattCharacteristicServiceProvider( + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& flags, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& service_path) + : object_path_(object_path), + uuid_(uuid), + service_path_(service_path), + delegate_(delegate) { + VLOG(1) << "Creating Bluetooth GATT characteristic: " << object_path_.value(); + + DCHECK(object_path_.IsValid()); + DCHECK(service_path_.IsValid()); + DCHECK(!uuid.empty()); + DCHECK(delegate_); + DCHECK(base::StartsWith(object_path_.value(), service_path_.value() + "/", + base::CompareCase::SENSITIVE)); + + // TODO(armansito): Do something with |flags| and |permissions|. + + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + fake_bluetooth_gatt_manager_client->RegisterCharacteristicServiceProvider( + this); +} + +FakeBluetoothGattCharacteristicServiceProvider:: + ~FakeBluetoothGattCharacteristicServiceProvider() { + VLOG(1) << "Cleaning up Bluetooth GATT characteristic: " + << object_path_.value(); + + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + fake_bluetooth_gatt_manager_client->UnregisterCharacteristicServiceProvider( + this); +} + +void FakeBluetoothGattCharacteristicServiceProvider::SendValueChanged( + const std::vector<uint8>& value) { + VLOG(1) << "Sent characteristic value changed: " << object_path_.value() + << " UUID: " << uuid_; +} + +void FakeBluetoothGattCharacteristicServiceProvider::GetValue( + const Delegate::ValueCallback& callback, + const Delegate::ErrorCallback& error_callback) { + VLOG(1) << "GATT characteristic value Get request: " << object_path_.value() + << " UUID: " << uuid_; + + // Check if this characteristic is registered. + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + if (!fake_bluetooth_gatt_manager_client->IsServiceRegistered(service_path_)) { + VLOG(1) << "GATT characteristic not registered."; + error_callback.Run(); + return; + } + + // Pass on to the delegate. + DCHECK(delegate_); + delegate_->GetCharacteristicValue(callback, error_callback); +} + +void FakeBluetoothGattCharacteristicServiceProvider::SetValue( + const std::vector<uint8>& value, + const base::Closure& callback, + const Delegate::ErrorCallback& error_callback) { + VLOG(1) << "GATT characteristic value Set request: " << object_path_.value() + << " UUID: " << uuid_; + + // Check if this characteristic is registered. + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + if (!fake_bluetooth_gatt_manager_client->IsServiceRegistered(service_path_)) { + VLOG(1) << "GATT characteristic not registered."; + error_callback.Run(); + return; + } + + // Pass on to the delegate. + DCHECK(delegate_); + delegate_->SetCharacteristicValue(value, callback, error_callback); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h new file mode 100644 index 0000000..675eba9 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h @@ -0,0 +1,67 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_ + +#include <string> +#include <vector> + +#include "base/macros.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h" + +namespace bluez { + +// FakeBluetoothGattCharacteristicServiceProvider simulates behavior of a local +// GATT characteristic object and is used both in test cases in place of a mock +// and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattCharacteristicServiceProvider + : public BluetoothGattCharacteristicServiceProvider { + public: + FakeBluetoothGattCharacteristicServiceProvider( + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& flags, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& service_path); + ~FakeBluetoothGattCharacteristicServiceProvider() override; + + // BluetoothGattCharacteristicServiceProvider override. + void SendValueChanged(const std::vector<uint8>& value) override; + + // Methods to simulate value get/set requests issued from a remote device. The + // methods do nothing, if the associated service was not registered with the + // GATT manager. + void GetValue(const Delegate::ValueCallback& callback, + const Delegate::ErrorCallback& error_callback); + void SetValue(const std::vector<uint8>& value, + const base::Closure& callback, + const Delegate::ErrorCallback& error_callback); + + const dbus::ObjectPath& object_path() const { return object_path_; } + const std::string& uuid() const { return uuid_; } + const dbus::ObjectPath& service_path() const { return service_path_; } + + private: + // D-Bus object path of the fake GATT characteristic. + dbus::ObjectPath object_path_; + + // 128-bit GATT characteristic UUID. + std::string uuid_; + + // Object path of the service that this characteristic belongs to. + dbus::ObjectPath service_path_; + + // The delegate that method calls are passed on to. + Delegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattCharacteristicServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_CHARACTERISTIC_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc new file mode 100644 index 0000000..dcaf1ec --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc @@ -0,0 +1,209 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +const char FakeBluetoothGattDescriptorClient:: + kClientCharacteristicConfigurationPathComponent[] = "desc0000"; +const char FakeBluetoothGattDescriptorClient:: + kClientCharacteristicConfigurationUUID[] = + "00002902-0000-1000-8000-00805f9b34fb"; + +FakeBluetoothGattDescriptorClient::Properties::Properties( + const PropertyChangedCallback& callback) + : BluetoothGattDescriptorClient::Properties( + NULL, + bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface, + callback) {} + +FakeBluetoothGattDescriptorClient::Properties::~Properties() {} + +void FakeBluetoothGattDescriptorClient::Properties::Get( + dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) { + VLOG(1) << "Get " << property->name(); + callback.Run(true); +} + +void FakeBluetoothGattDescriptorClient::Properties::GetAll() { + VLOG(1) << "GetAll"; +} + +void FakeBluetoothGattDescriptorClient::Properties::Set( + dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) { + VLOG(1) << "Set " << property->name(); + callback.Run(false); +} + +FakeBluetoothGattDescriptorClient::DescriptorData::DescriptorData() {} + +FakeBluetoothGattDescriptorClient::DescriptorData::~DescriptorData() {} + +FakeBluetoothGattDescriptorClient::FakeBluetoothGattDescriptorClient() + : weak_ptr_factory_(this) {} + +FakeBluetoothGattDescriptorClient::~FakeBluetoothGattDescriptorClient() { + for (PropertiesMap::iterator iter = properties_.begin(); + iter != properties_.end(); iter++) + delete iter->second; +} + +void FakeBluetoothGattDescriptorClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothGattDescriptorClient::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeBluetoothGattDescriptorClient::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +std::vector<dbus::ObjectPath> +FakeBluetoothGattDescriptorClient::GetDescriptors() { + std::vector<dbus::ObjectPath> descriptors; + for (PropertiesMap::const_iterator iter = properties_.begin(); + iter != properties_.end(); ++iter) { + descriptors.push_back(iter->first); + } + return descriptors; +} + +FakeBluetoothGattDescriptorClient::Properties* +FakeBluetoothGattDescriptorClient::GetProperties( + const dbus::ObjectPath& object_path) { + PropertiesMap::const_iterator iter = properties_.find(object_path); + if (iter == properties_.end()) + return NULL; + return iter->second->properties.get(); +} + +void FakeBluetoothGattDescriptorClient::ReadValue( + const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const ErrorCallback& error_callback) { + PropertiesMap::iterator iter = properties_.find(object_path); + if (iter == properties_.end()) { + error_callback.Run(kUnknownDescriptorError, ""); + return; + } + + // Assign the value of the descriptor as necessary + Properties* properties = iter->second->properties.get(); + if (properties->uuid.value() == kClientCharacteristicConfigurationUUID) { + BluetoothGattCharacteristicClient::Properties* chrc_props = + bluez::BluezDBusManager::Get() + ->GetBluetoothGattCharacteristicClient() + ->GetProperties(properties->characteristic.value()); + DCHECK(chrc_props); + + uint8_t value_byte = chrc_props->notifying.value() ? 0x01 : 0x00; + const std::vector<uint8_t>& cur_value = properties->value.value(); + + if (!cur_value.size() || cur_value[0] != value_byte) { + std::vector<uint8_t> value = {value_byte, 0x00}; + properties->value.ReplaceValue(value); + } + } + + callback.Run(iter->second->properties->value.value()); +} + +void FakeBluetoothGattDescriptorClient::WriteValue( + const dbus::ObjectPath& object_path, + const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (properties_.find(object_path) == properties_.end()) { + error_callback.Run(kUnknownDescriptorError, ""); + return; + } + + // Since the only fake descriptor is "Client Characteristic Configuration" + // and BlueZ doesn't allow writing to it, return failure. + error_callback.Run("org.bluez.Error.NotPermitted", + "Writing to the Client Characteristic Configuration " + "descriptor not allowed"); +} + +dbus::ObjectPath FakeBluetoothGattDescriptorClient::ExposeDescriptor( + const dbus::ObjectPath& characteristic_path, + const std::string& uuid) { + if (uuid != kClientCharacteristicConfigurationUUID) { + VLOG(2) << "Unsupported UUID: " << uuid; + return dbus::ObjectPath(); + } + + // CCC descriptor is the only one supported at the moment. + DCHECK(characteristic_path.IsValid()); + dbus::ObjectPath object_path(characteristic_path.value() + "/" + + kClientCharacteristicConfigurationPathComponent); + DCHECK(object_path.IsValid()); + PropertiesMap::const_iterator iter = properties_.find(object_path); + if (iter != properties_.end()) { + VLOG(1) << "Descriptor already exposed: " << object_path.value(); + return dbus::ObjectPath(); + } + + Properties* properties = new Properties( + base::Bind(&FakeBluetoothGattDescriptorClient::OnPropertyChanged, + weak_ptr_factory_.GetWeakPtr(), object_path)); + properties->uuid.ReplaceValue(uuid); + properties->characteristic.ReplaceValue(characteristic_path); + + DescriptorData* data = new DescriptorData(); + data->properties.reset(properties); + + properties_[object_path] = data; + + NotifyDescriptorAdded(object_path); + + return object_path; +} + +void FakeBluetoothGattDescriptorClient::HideDescriptor( + const dbus::ObjectPath& descriptor_path) { + PropertiesMap::iterator iter = properties_.find(descriptor_path); + if (iter == properties_.end()) { + VLOG(1) << "Descriptor not exposed: " << descriptor_path.value(); + return; + } + + NotifyDescriptorRemoved(descriptor_path); + + delete iter->second; + properties_.erase(iter); +} + +void FakeBluetoothGattDescriptorClient::OnPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) { + VLOG(2) << "Descriptor property changed: " << object_path.value() << ": " + << property_name; + + FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, + GattDescriptorPropertyChanged(object_path, property_name)); +} + +void FakeBluetoothGattDescriptorClient::NotifyDescriptorAdded( + const dbus::ObjectPath& object_path) { + FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, + GattDescriptorAdded(object_path)); +} + +void FakeBluetoothGattDescriptorClient::NotifyDescriptorRemoved( + const dbus::ObjectPath& object_path) { + FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, + GattDescriptorRemoved(object_path)); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h new file mode 100644 index 0000000..0e8e856 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h @@ -0,0 +1,104 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_ + +#include <map> +#include <string> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h" + +namespace bluez { + +// FakeBluetoothGattDescriptorClient simulates the behavior of the Bluetooth +// Daemon GATT characteristic descriptor objects and is used in test cases in +// place of a mock and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattDescriptorClient + : public BluetoothGattDescriptorClient { + public: + struct Properties : public BluetoothGattDescriptorClient::Properties { + explicit Properties(const PropertyChangedCallback& callback); + ~Properties() override; + + // dbus::PropertySet override + void Get(dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) override; + void GetAll() override; + void Set(dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) override; + }; + + FakeBluetoothGattDescriptorClient(); + ~FakeBluetoothGattDescriptorClient() override; + + // DBusClient override. + void Init(dbus::Bus* bus) override; + + // BluetoothGattDescriptorClient overrides. + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + std::vector<dbus::ObjectPath> GetDescriptors() override; + Properties* GetProperties(const dbus::ObjectPath& object_path) override; + void ReadValue(const dbus::ObjectPath& object_path, + const ValueCallback& callback, + const ErrorCallback& error_callback) override; + void WriteValue(const dbus::ObjectPath& object_path, + const std::vector<uint8>& value, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Makes the descriptor with the UUID |uuid| visible under the characteristic + // with object path |characteristic_path|. Descriptor object paths are + // hierarchical to their characteristics. |uuid| must belong to a descriptor + // for which there is a constant defined below, otherwise this method has no + // effect. Returns the object path of the created descriptor. In the no-op + // case, returns an invalid path. + dbus::ObjectPath ExposeDescriptor(const dbus::ObjectPath& characteristic_path, + const std::string& uuid); + void HideDescriptor(const dbus::ObjectPath& descriptor_path); + + // Object path components and UUIDs of GATT characteristic descriptors. + static const char kClientCharacteristicConfigurationPathComponent[]; + static const char kClientCharacteristicConfigurationUUID[]; + + private: + // Property callback passed when we create Properties structures. + void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name); + + // Notifies observers. + void NotifyDescriptorAdded(const dbus::ObjectPath& object_path); + void NotifyDescriptorRemoved(const dbus::ObjectPath& object_path); + + // Mapping from object paths to Properties structures. + struct DescriptorData { + DescriptorData(); + ~DescriptorData(); + + scoped_ptr<Properties> properties; + }; + typedef std::map<dbus::ObjectPath, DescriptorData*> PropertiesMap; + PropertiesMap properties_; + + // List of observers interested in event notifications from us. + base::ObserverList<Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<FakeBluetoothGattDescriptorClient> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattDescriptorClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc new file mode 100644 index 0000000..4376ce9 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.cc @@ -0,0 +1,121 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h" + +#include "base/logging.h" +#include "base/strings/string_util.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h" + +namespace bluez { + +FakeBluetoothGattDescriptorServiceProvider:: + FakeBluetoothGattDescriptorServiceProvider( + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& characteristic_path) + : object_path_(object_path), + uuid_(uuid), + characteristic_path_(characteristic_path), + delegate_(delegate) { + VLOG(1) << "Creating Bluetooth GATT descriptor: " << object_path_.value(); + + DCHECK(object_path_.IsValid()); + DCHECK(characteristic_path_.IsValid()); + DCHECK(!uuid.empty()); + DCHECK(delegate_); + DCHECK(base::StartsWith(object_path_.value(), + characteristic_path_.value() + "/", + base::CompareCase::SENSITIVE)); + + // TODO(armansito): Do something with |permissions|. + + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + fake_bluetooth_gatt_manager_client->RegisterDescriptorServiceProvider(this); +} + +FakeBluetoothGattDescriptorServiceProvider:: + ~FakeBluetoothGattDescriptorServiceProvider() { + VLOG(1) << "Cleaning up Bluetooth GATT descriptor: " << object_path_.value(); + + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + fake_bluetooth_gatt_manager_client->UnregisterDescriptorServiceProvider(this); +} + +void FakeBluetoothGattDescriptorServiceProvider::SendValueChanged( + const std::vector<uint8>& value) { + VLOG(1) << "Sent descriptor value changed: " << object_path_.value() + << " UUID: " << uuid_; +} + +void FakeBluetoothGattDescriptorServiceProvider::GetValue( + const Delegate::ValueCallback& callback, + const Delegate::ErrorCallback& error_callback) { + VLOG(1) << "GATT descriptor value Get request: " << object_path_.value() + << " UUID: " << uuid_; + + // Check if this descriptor is registered. + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + FakeBluetoothGattCharacteristicServiceProvider* characteristic = + fake_bluetooth_gatt_manager_client->GetCharacteristicServiceProvider( + characteristic_path_); + if (!characteristic) { + VLOG(1) << "GATT characteristic for descriptor does not exist: " + << characteristic_path_.value(); + return; + } + if (!fake_bluetooth_gatt_manager_client->IsServiceRegistered( + characteristic->service_path())) { + VLOG(1) << "GATT descriptor not registered."; + error_callback.Run(); + return; + } + + // Pass on to the delegate. + DCHECK(delegate_); + delegate_->GetDescriptorValue(callback, error_callback); +} + +void FakeBluetoothGattDescriptorServiceProvider::SetValue( + const std::vector<uint8>& value, + const base::Closure& callback, + const Delegate::ErrorCallback& error_callback) { + VLOG(1) << "GATT descriptor value Set request: " << object_path_.value() + << " UUID: " << uuid_; + + // Check if this descriptor is registered. + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + FakeBluetoothGattCharacteristicServiceProvider* characteristic = + fake_bluetooth_gatt_manager_client->GetCharacteristicServiceProvider( + characteristic_path_); + if (!characteristic) { + VLOG(1) << "GATT characteristic for descriptor does not exist: " + << characteristic_path_.value(); + return; + } + if (!fake_bluetooth_gatt_manager_client->IsServiceRegistered( + characteristic->service_path())) { + VLOG(1) << "GATT descriptor not registered."; + error_callback.Run(); + return; + } + + // Pass on to the delegate. + DCHECK(delegate_); + delegate_->SetDescriptorValue(value, callback, error_callback); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h new file mode 100644 index 0000000..7640acc --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h @@ -0,0 +1,68 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_ + +#include <string> +#include <vector> + +#include "base/macros.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h" + +namespace bluez { + +// FakeBluetoothGattDescriptorServiceProvider simulates behavior of a local +// GATT descriptor object and is used both in test cases in place of a mock +// and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattDescriptorServiceProvider + : public BluetoothGattDescriptorServiceProvider { + public: + FakeBluetoothGattDescriptorServiceProvider( + const dbus::ObjectPath& object_path, + Delegate* delegate, + const std::string& uuid, + const std::vector<std::string>& permissions, + const dbus::ObjectPath& characteristic_path); + ~FakeBluetoothGattDescriptorServiceProvider() override; + + // BluetoothGattDescriptorServiceProvider override. + void SendValueChanged(const std::vector<uint8>& value) override; + + // Methods to simulate value get/set requests issued from a remote device. The + // methods do nothing, if the associated service was not registered with the + // GATT manager. + void GetValue(const Delegate::ValueCallback& callback, + const Delegate::ErrorCallback& error_callback); + void SetValue(const std::vector<uint8>& value, + const base::Closure& callback, + const Delegate::ErrorCallback& error_callback); + + const dbus::ObjectPath& object_path() const { return object_path_; } + const std::string& uuid() const { return uuid_; } + const dbus::ObjectPath& characteristic_path() const { + return characteristic_path_; + } + + private: + // D-Bus object path of the fake GATT descriptor. + dbus::ObjectPath object_path_; + + // 128-bit GATT descriptor UUID. + std::string uuid_; + + // Object path of the characteristic that this descriptor belongs to. + dbus::ObjectPath characteristic_path_; + + // The delegate that method calls are passed on to. + Delegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattDescriptorServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_DESCRIPTOR_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc new file mode 100644 index 0000000..284a17c --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.cc @@ -0,0 +1,169 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h" + +#include "base/logging.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +FakeBluetoothGattManagerClient::FakeBluetoothGattManagerClient() {} + +FakeBluetoothGattManagerClient::~FakeBluetoothGattManagerClient() {} + +// DBusClient override. +void FakeBluetoothGattManagerClient::Init(dbus::Bus* bus) {} + +// BluetoothGattManagerClient overrides. +void FakeBluetoothGattManagerClient::RegisterService( + const dbus::ObjectPath& service_path, + const Options& options, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "Register GATT service: " << service_path.value(); + + // If a service provider wasn't created before, return error. + ServiceMap::iterator iter = service_map_.find(service_path); + if (iter == service_map_.end()) { + error_callback.Run(bluetooth_gatt_manager::kErrorInvalidArguments, + "GATT service doesn't exist: " + service_path.value()); + return; + } + + // Check to see if this GATT service was already registered. + ServiceProvider* provider = &iter->second; + if (provider->first) { + error_callback.Run( + bluetooth_gatt_manager::kErrorAlreadyExists, + "GATT service already registered: " + service_path.value()); + return; + } + + // Success! + provider->first = true; + callback.Run(); +} + +void FakeBluetoothGattManagerClient::UnregisterService( + const dbus::ObjectPath& service_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "Unregister GATT service: " << service_path.value(); + + // If a service provider wasn't created before, return error. + ServiceMap::iterator iter = service_map_.find(service_path); + if (iter == service_map_.end()) { + error_callback.Run(bluetooth_gatt_manager::kErrorInvalidArguments, + "GATT service doesn't exist: " + service_path.value()); + return; + } + + // Return error if the GATT service wasn't registered before. + ServiceProvider* provider = &iter->second; + if (!provider->first) { + error_callback.Run(bluetooth_gatt_manager::kErrorDoesNotExist, + "GATT service not registered: " + service_path.value()); + return; + } + + // Success! + provider->first = false; + callback.Run(); +} + +void FakeBluetoothGattManagerClient::RegisterServiceServiceProvider( + FakeBluetoothGattServiceServiceProvider* provider) { + // Ignore, if a service provider is already registered for the object path. + ServiceMap::iterator iter = service_map_.find(provider->object_path()); + if (iter != service_map_.end()) { + VLOG(1) << "GATT service service provider already registered for " + << "object path: " << provider->object_path().value(); + return; + } + service_map_[provider->object_path()] = std::make_pair(false, provider); +} + +void FakeBluetoothGattManagerClient::RegisterCharacteristicServiceProvider( + FakeBluetoothGattCharacteristicServiceProvider* provider) { + // Ignore, if a service provider is already registered for the object path. + CharacteristicMap::iterator iter = + characteristic_map_.find(provider->object_path()); + if (iter != characteristic_map_.end()) { + VLOG(1) << "GATT characteristic service provider already registered for " + << "object path: " << provider->object_path().value(); + return; + } + characteristic_map_[provider->object_path()] = provider; +} + +void FakeBluetoothGattManagerClient::RegisterDescriptorServiceProvider( + FakeBluetoothGattDescriptorServiceProvider* provider) { + // Ignore, if a service provider is already registered for the object path. + DescriptorMap::iterator iter = descriptor_map_.find(provider->object_path()); + if (iter != descriptor_map_.end()) { + VLOG(1) << "GATT descriptor service provider already registered for " + << "object path: " << provider->object_path().value(); + return; + } + descriptor_map_[provider->object_path()] = provider; +} + +void FakeBluetoothGattManagerClient::UnregisterServiceServiceProvider( + FakeBluetoothGattServiceServiceProvider* provider) { + ServiceMap::iterator iter = service_map_.find(provider->object_path()); + if (iter != service_map_.end() && iter->second.second == provider) + service_map_.erase(iter); +} + +void FakeBluetoothGattManagerClient::UnregisterCharacteristicServiceProvider( + FakeBluetoothGattCharacteristicServiceProvider* provider) { + characteristic_map_.erase(provider->object_path()); +} + +void FakeBluetoothGattManagerClient::UnregisterDescriptorServiceProvider( + FakeBluetoothGattDescriptorServiceProvider* provider) { + descriptor_map_.erase(provider->object_path()); +} + +FakeBluetoothGattServiceServiceProvider* +FakeBluetoothGattManagerClient::GetServiceServiceProvider( + const dbus::ObjectPath& object_path) const { + ServiceMap::const_iterator iter = service_map_.find(object_path); + if (iter == service_map_.end()) + return NULL; + return iter->second.second; +} + +FakeBluetoothGattCharacteristicServiceProvider* +FakeBluetoothGattManagerClient::GetCharacteristicServiceProvider( + const dbus::ObjectPath& object_path) const { + CharacteristicMap::const_iterator iter = + characteristic_map_.find(object_path); + if (iter == characteristic_map_.end()) + return NULL; + return iter->second; +} + +FakeBluetoothGattDescriptorServiceProvider* +FakeBluetoothGattManagerClient::GetDescriptorServiceProvider( + const dbus::ObjectPath& object_path) const { + DescriptorMap::const_iterator iter = descriptor_map_.find(object_path); + if (iter == descriptor_map_.end()) + return NULL; + return iter->second; +} + +bool FakeBluetoothGattManagerClient::IsServiceRegistered( + const dbus::ObjectPath& object_path) const { + ServiceMap::const_iterator iter = service_map_.find(object_path); + if (iter == service_map_.end()) + return false; + return iter->second.first; +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h new file mode 100644 index 0000000..65082ae --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h @@ -0,0 +1,101 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_ + +#include <map> +#include <string> +#include <utility> + +#include "base/callback.h" +#include "base/macros.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_gatt_manager_client.h" + +namespace bluez { + +class FakeBluetoothGattCharacteristicServiceProvider; +class FakeBluetoothGattDescriptorServiceProvider; +class FakeBluetoothGattServiceServiceProvider; + +// FakeBluetoothGattManagerClient simulates the behavior of the Bluetooth +// daemon's GATT manager object and is used both in test cases in place of a +// mock and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattManagerClient + : public BluetoothGattManagerClient { + public: + FakeBluetoothGattManagerClient(); + ~FakeBluetoothGattManagerClient() override; + + // DBusClient override. + void Init(dbus::Bus* bus) override; + + // BluetoothGattManagerClient overrides. + void RegisterService(const dbus::ObjectPath& service_path, + const Options& options, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void UnregisterService(const dbus::ObjectPath& service_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Register, unregister, and retrieve pointers to service, characteristic, and + // descriptor service providers. Automatically called from the service + // provider constructor and destructors. + void RegisterServiceServiceProvider( + FakeBluetoothGattServiceServiceProvider* provider); + void RegisterCharacteristicServiceProvider( + FakeBluetoothGattCharacteristicServiceProvider* provider); + void RegisterDescriptorServiceProvider( + FakeBluetoothGattDescriptorServiceProvider* provider); + + void UnregisterServiceServiceProvider( + FakeBluetoothGattServiceServiceProvider* provider); + void UnregisterCharacteristicServiceProvider( + FakeBluetoothGattCharacteristicServiceProvider* provider); + void UnregisterDescriptorServiceProvider( + FakeBluetoothGattDescriptorServiceProvider* provider); + + // Return a pointer to the service provider that corresponds to the object + // path |object_path| if it exists. + FakeBluetoothGattServiceServiceProvider* GetServiceServiceProvider( + const dbus::ObjectPath& object_path) const; + FakeBluetoothGattCharacteristicServiceProvider* + GetCharacteristicServiceProvider(const dbus::ObjectPath& object_path) const; + FakeBluetoothGattDescriptorServiceProvider* GetDescriptorServiceProvider( + const dbus::ObjectPath& object_path) const; + + // Returns true, if a GATT service with object path |object_path| was + // registered with the GATT manager using RegisterService. + bool IsServiceRegistered(const dbus::ObjectPath& object_path) const; + + private: + // Mappings for GATT service, characteristic, and descriptor service + // providers. The fake GATT manager stores references to all instances + // created so that they can be obtained by tests. + typedef std::map<dbus::ObjectPath, + FakeBluetoothGattCharacteristicServiceProvider*> + CharacteristicMap; + typedef std::map<dbus::ObjectPath, + FakeBluetoothGattDescriptorServiceProvider*> DescriptorMap; + + // The mapping for services is from object paths to pairs of boolean and + // service provider pointer, where the boolean denotes whether or not the + // service is already registered. + typedef std::pair<bool, FakeBluetoothGattServiceServiceProvider*> + ServiceProvider; + typedef std::map<dbus::ObjectPath, ServiceProvider> ServiceMap; + + ServiceMap service_map_; + CharacteristicMap characteristic_map_; + DescriptorMap descriptor_map_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattManagerClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_MANAGER_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc new file mode 100644 index 0000000..2e7aa0a --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc @@ -0,0 +1,189 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h" + +#include "base/bind.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +namespace { + +const int kExposeCharacteristicsDelayIntervalMs = 100; + +} // namespace + +// static +const char FakeBluetoothGattServiceClient::kHeartRateServicePathComponent[] = + "service0000"; +const char FakeBluetoothGattServiceClient::kHeartRateServiceUUID[] = + "0000180d-0000-1000-8000-00805f9b34fb"; + +FakeBluetoothGattServiceClient::Properties::Properties( + const PropertyChangedCallback& callback) + : BluetoothGattServiceClient::Properties( + NULL, + bluetooth_gatt_service::kBluetoothGattServiceInterface, + callback) {} + +FakeBluetoothGattServiceClient::Properties::~Properties() {} + +void FakeBluetoothGattServiceClient::Properties::Get( + dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) { + VLOG(1) << "Get " << property->name(); + callback.Run(false); +} + +void FakeBluetoothGattServiceClient::Properties::GetAll() { + VLOG(1) << "GetAll"; +} + +void FakeBluetoothGattServiceClient::Properties::Set( + dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) { + VLOG(1) << "Set " << property->name(); + callback.Run(false); +} + +FakeBluetoothGattServiceClient::FakeBluetoothGattServiceClient() + : weak_ptr_factory_(this) {} + +FakeBluetoothGattServiceClient::~FakeBluetoothGattServiceClient() {} + +void FakeBluetoothGattServiceClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothGattServiceClient::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeBluetoothGattServiceClient::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +std::vector<dbus::ObjectPath> FakeBluetoothGattServiceClient::GetServices() { + std::vector<dbus::ObjectPath> paths; + if (heart_rate_service_properties_.get()) { + DCHECK(!heart_rate_service_path_.empty()); + paths.push_back(dbus::ObjectPath(heart_rate_service_path_)); + } + return paths; +} + +FakeBluetoothGattServiceClient::Properties* +FakeBluetoothGattServiceClient::GetProperties( + const dbus::ObjectPath& object_path) { + if (object_path.value() == heart_rate_service_path_) + return heart_rate_service_properties_.get(); + return NULL; +} + +void FakeBluetoothGattServiceClient::ExposeHeartRateService( + const dbus::ObjectPath& device_path) { + if (IsHeartRateVisible()) { + DCHECK(!heart_rate_service_path_.empty()); + VLOG(1) << "Fake Heart Rate Service already exposed."; + return; + } + VLOG(2) << "Exposing fake Heart Rate Service."; + heart_rate_service_path_ = + device_path.value() + "/" + kHeartRateServicePathComponent; + heart_rate_service_properties_.reset(new Properties(base::Bind( + &FakeBluetoothGattServiceClient::OnPropertyChanged, + base::Unretained(this), dbus::ObjectPath(heart_rate_service_path_)))); + heart_rate_service_properties_->uuid.ReplaceValue(kHeartRateServiceUUID); + heart_rate_service_properties_->device.ReplaceValue(device_path); + heart_rate_service_properties_->primary.ReplaceValue(true); + + NotifyServiceAdded(dbus::ObjectPath(heart_rate_service_path_)); + + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind( + &FakeBluetoothGattServiceClient::ExposeHeartRateCharacteristics, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(kExposeCharacteristicsDelayIntervalMs)); +} + +void FakeBluetoothGattServiceClient::HideHeartRateService() { + if (!IsHeartRateVisible()) { + DCHECK(heart_rate_service_path_.empty()); + VLOG(1) << "Fake Heart Rate Service already hidden."; + return; + } + VLOG(2) << "Hiding fake Heart Rate Service."; + FakeBluetoothGattCharacteristicClient* char_client = + static_cast<FakeBluetoothGattCharacteristicClient*>( + bluez::BluezDBusManager::Get() + ->GetBluetoothGattCharacteristicClient()); + char_client->HideHeartRateCharacteristics(); + + // Notify observers before deleting the properties structure so that it + // can be accessed from the observer method. + NotifyServiceRemoved(dbus::ObjectPath(heart_rate_service_path_)); + + heart_rate_service_properties_.reset(); + heart_rate_service_path_.clear(); +} + +bool FakeBluetoothGattServiceClient::IsHeartRateVisible() const { + return !!heart_rate_service_properties_.get(); +} + +dbus::ObjectPath FakeBluetoothGattServiceClient::GetHeartRateServicePath() + const { + return dbus::ObjectPath(heart_rate_service_path_); +} + +void FakeBluetoothGattServiceClient::OnPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) { + VLOG(2) << "Fake GATT Service property changed: " << object_path.value() + << ": " << property_name; + FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_, + GattServicePropertyChanged(object_path, property_name)); +} + +void FakeBluetoothGattServiceClient::NotifyServiceAdded( + const dbus::ObjectPath& object_path) { + VLOG(2) << "GATT service added: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_, + GattServiceAdded(object_path)); +} + +void FakeBluetoothGattServiceClient::NotifyServiceRemoved( + const dbus::ObjectPath& object_path) { + VLOG(2) << "GATT service removed: " << object_path.value(); + FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_, + GattServiceRemoved(object_path)); +} + +void FakeBluetoothGattServiceClient::ExposeHeartRateCharacteristics() { + if (!IsHeartRateVisible()) { + VLOG(2) << "Heart Rate service not visible. Not exposing characteristics."; + return; + } + FakeBluetoothGattCharacteristicClient* char_client = + static_cast<FakeBluetoothGattCharacteristicClient*>( + bluez::BluezDBusManager::Get() + ->GetBluetoothGattCharacteristicClient()); + char_client->ExposeHeartRateCharacteristics( + dbus::ObjectPath(heart_rate_service_path_)); + + std::vector<dbus::ObjectPath> char_paths; + char_paths.push_back(char_client->GetHeartRateMeasurementPath()); + char_paths.push_back(char_client->GetBodySensorLocationPath()); + char_paths.push_back(char_client->GetHeartRateControlPointPath()); + + heart_rate_service_properties_->characteristics.ReplaceValue(char_paths); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h new file mode 100644 index 0000000..faebb42 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h @@ -0,0 +1,107 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_CLIENT_H_ + +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_gatt_service_client.h" + +namespace bluez { + +// FakeBluetoothGattServiceClient simulates the behavior of the Bluetooth Daemon +// GATT service objects and is used in test cases in place of a mock and on the +// Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattServiceClient + : public BluetoothGattServiceClient { + public: + struct Properties : public BluetoothGattServiceClient::Properties { + explicit Properties(const PropertyChangedCallback& callback); + ~Properties() override; + + // dbus::PropertySet override + void Get(dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) override; + void GetAll() override; + void Set(dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) override; + }; + + FakeBluetoothGattServiceClient(); + ~FakeBluetoothGattServiceClient() override; + + // DBusClient override. + void Init(dbus::Bus* bus) override; + + // BluetoothGattServiceClient overrides. + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + std::vector<dbus::ObjectPath> GetServices() override; + Properties* GetProperties(const dbus::ObjectPath& object_path) override; + + // Makes a service visible for device with object path |device_path|. Note + // that only one instance of a specific service is simulated at a time. Hence, + // this method will fail, if the service is already visible. + void ExposeHeartRateService(const dbus::ObjectPath& device_path); + void HideHeartRateService(); + + // Returns whether or not the Heart Rate Service is visible. + bool IsHeartRateVisible() const; + + // Returns the current object path of the visible Heart Rate service. If the + // service is not visible, returns an invalid empty path. + dbus::ObjectPath GetHeartRateServicePath() const; + + // Final object path components and the corresponding UUIDs of the GATT + // services that we emulate. Service paths are hierarchical to Bluetooth + // device paths, so if the path component is "service0000", and the device + // path is "/org/foo/device0", the service path is + // "/org/foo/device0/service0000". + static const char kHeartRateServicePathComponent[]; + static const char kHeartRateServiceUUID[]; + + private: + // Property callback passed when we create Properties structures. + void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name); + + // Notifies observers. + void NotifyServiceAdded(const dbus::ObjectPath& object_path); + void NotifyServiceRemoved(const dbus::ObjectPath& object_path); + + // Tells FakeBluetoothGattCharacteristicClient to expose GATT characteristics. + // This is scheduled from ExposeHeartRateService to simulate asynchronous + // retrieval of characteristics. If the Heart Rate Service is hidden at the + // time this method is called, then it does nothing. + void ExposeHeartRateCharacteristics(); + + // Static properties we return. As long as a service is exposed, this will be + // non-null. Otherwise it will be null. + scoped_ptr<Properties> heart_rate_service_properties_; + std::string heart_rate_service_path_; + + // List of observers interested in event notifications from us. + base::ObserverList<Observer> observers_; + + // Weak pointer factory for generating 'this' pointers that might live longer + // than we do. + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory<FakeBluetoothGattServiceClient> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattServiceClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc new file mode 100644 index 0000000..8d724058 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.cc @@ -0,0 +1,37 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h" + +#include "base/logging.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h" + +namespace bluez { + +FakeBluetoothGattServiceServiceProvider:: + FakeBluetoothGattServiceServiceProvider( + const dbus::ObjectPath& object_path, + const std::string& uuid, + const std::vector<dbus::ObjectPath>& includes) + : object_path_(object_path), uuid_(uuid), includes_(includes) { + VLOG(1) << "Creating Bluetooth GATT service: " << object_path_.value(); + + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + fake_bluetooth_gatt_manager_client->RegisterServiceServiceProvider(this); +} + +FakeBluetoothGattServiceServiceProvider:: + ~FakeBluetoothGattServiceServiceProvider() { + VLOG(1) << "Cleaning up Bluetooth GATT service: " << object_path_.value(); + + FakeBluetoothGattManagerClient* fake_bluetooth_gatt_manager_client = + static_cast<FakeBluetoothGattManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothGattManagerClient()); + fake_bluetooth_gatt_manager_client->UnregisterServiceServiceProvider(this); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h new file mode 100644 index 0000000..ca8b52e --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h @@ -0,0 +1,48 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_ + +#include <string> +#include <vector> + +#include "base/macros.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h" + +namespace bluez { + +// FakeBluetoothGattServiceServiceProvider simulates behavior of a local GATT +// service object and is used both in test cases in place of a mock and on the +// Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattServiceServiceProvider + : public BluetoothGattServiceServiceProvider { + public: + FakeBluetoothGattServiceServiceProvider( + const dbus::ObjectPath& object_path, + const std::string& uuid, + const std::vector<dbus::ObjectPath>& includes); + ~FakeBluetoothGattServiceServiceProvider() override; + + const dbus::ObjectPath& object_path() const { return object_path_; } + const std::string& uuid() const { return uuid_; } + + private: + // D-Bus object path of the fake GATT service. + dbus::ObjectPath object_path_; + + // 128-bit GATT service UUID. + std::string uuid_; + + // List of included GATT services. + std::vector<dbus::ObjectPath> includes_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattServiceServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_GATT_SERVICE_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_input_client.cc b/device/bluetooth/dbus/fake_bluetooth_input_client.cc new file mode 100644 index 0000000..849c3be --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_input_client.cc @@ -0,0 +1,123 @@ +// Copyright (c) 2013 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 "device/bluetooth/dbus/fake_bluetooth_input_client.h" + +#include <map> + +#include "base/logging.h" +#include "base/stl_util.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_manager.h" +#include "dbus/object_proxy.h" +#include "device/bluetooth/dbus/fake_bluetooth_device_client.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +FakeBluetoothInputClient::Properties::Properties( + const PropertyChangedCallback& callback) + : BluetoothInputClient::Properties( + NULL, + bluetooth_input::kBluetoothInputInterface, + callback) {} + +FakeBluetoothInputClient::Properties::~Properties() {} + +void FakeBluetoothInputClient::Properties::Get( + dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) { + VLOG(1) << "Get " << property->name(); + callback.Run(false); +} + +void FakeBluetoothInputClient::Properties::GetAll() { + VLOG(1) << "GetAll"; +} + +void FakeBluetoothInputClient::Properties::Set( + dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) { + VLOG(1) << "Set " << property->name(); + callback.Run(false); +} + +FakeBluetoothInputClient::FakeBluetoothInputClient() {} + +FakeBluetoothInputClient::~FakeBluetoothInputClient() { + // Clean up Properties structures + STLDeleteValues(&properties_map_); +} + +void FakeBluetoothInputClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothInputClient::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeBluetoothInputClient::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +FakeBluetoothInputClient::Properties* FakeBluetoothInputClient::GetProperties( + const dbus::ObjectPath& object_path) { + PropertiesMap::iterator iter = properties_map_.find(object_path); + if (iter != properties_map_.end()) + return iter->second; + return NULL; +} + +void FakeBluetoothInputClient::AddInputDevice( + const dbus::ObjectPath& object_path) { + if (properties_map_.find(object_path) != properties_map_.end()) + return; + + Properties* properties = + new Properties(base::Bind(&FakeBluetoothInputClient::OnPropertyChanged, + base::Unretained(this), object_path)); + + // The LegacyAutopair and DisplayPinCode devices represent a typical mouse + // and keyboard respectively, so mark them as ReconnectMode "any". The + // DisplayPasskey device represents a Bluetooth 2.1+ keyboard and the + // ConnectUnpairable device represents a pre-standardization mouse, so mark + // them as ReconnectMode "device". + if (object_path.value() == FakeBluetoothDeviceClient::kDisplayPasskeyPath || + object_path.value() == + FakeBluetoothDeviceClient::kConnectUnpairablePath) { + properties->reconnect_mode.ReplaceValue( + bluetooth_input::kDeviceReconnectModeProperty); + } else { + properties->reconnect_mode.ReplaceValue( + bluetooth_input::kAnyReconnectModeProperty); + } + + properties_map_[object_path] = properties; + + FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_, + InputAdded(object_path)); +} + +void FakeBluetoothInputClient::RemoveInputDevice( + const dbus::ObjectPath& object_path) { + PropertiesMap::iterator it = properties_map_.find(object_path); + + if (it == properties_map_.end()) + return; + + FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_, + InputRemoved(object_path)); + + delete it->second; + properties_map_.erase(it); +} + +void FakeBluetoothInputClient::OnPropertyChanged( + const dbus::ObjectPath& object_path, + const std::string& property_name) { + FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_, + InputPropertyChanged(object_path, property_name)); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_input_client.h b/device/bluetooth/dbus/fake_bluetooth_input_client.h new file mode 100644 index 0000000..81139db --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_input_client.h @@ -0,0 +1,66 @@ +// Copyright (c) 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_INPUT_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_INPUT_CLIENT_H_ + +#include "base/callback.h" +#include "base/macros.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_input_client.h" + +namespace bluez { + +// FakeBluetoothInputClient simulates the behavior of the Bluetooth Daemon +// input device objects and is used both in test cases in place of a mock and on +// the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothInputClient + : public BluetoothInputClient { + public: + struct Properties : public BluetoothInputClient::Properties { + explicit Properties(const PropertyChangedCallback& callback); + ~Properties() override; + + // dbus::PropertySet override + void Get(dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) override; + void GetAll() override; + void Set(dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) override; + }; + + FakeBluetoothInputClient(); + ~FakeBluetoothInputClient() override; + + // BluetoothInputClient overrides + void Init(dbus::Bus* bus) override; + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + Properties* GetProperties(const dbus::ObjectPath& object_path) override; + + // Simulate device addition/removal + void AddInputDevice(const dbus::ObjectPath& object_path); + void RemoveInputDevice(const dbus::ObjectPath& object_path); + + private: + // Property callback passed when we create Properties* structures. + void OnPropertyChanged(const dbus::ObjectPath& object_path, + const std::string& property_name); + + // Static properties we return. + typedef std::map<const dbus::ObjectPath, Properties*> PropertiesMap; + PropertiesMap properties_map_; + + // List of observers interested in event notifications from us. + base::ObserverList<Observer> observers_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothInputClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_INPUT_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.cc new file mode 100644 index 0000000..043df05 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.cc @@ -0,0 +1,46 @@ +// Copyright 2015 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 "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h" +#include "device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h" + +namespace bluez { + +FakeBluetoothLEAdvertisementServiceProvider:: + FakeBluetoothLEAdvertisementServiceProvider( + const dbus::ObjectPath& object_path, + Delegate* delegate) + : delegate_(delegate) { + object_path_ = object_path; + VLOG(1) << "Creating Bluetooth Advertisement: " << object_path_.value(); + + FakeBluetoothLEAdvertisingManagerClient* + fake_bluetooth_profile_manager_client = + static_cast<FakeBluetoothLEAdvertisingManagerClient*>( + bluez::BluezDBusManager::Get() + ->GetBluetoothLEAdvertisingManagerClient()); + fake_bluetooth_profile_manager_client->RegisterAdvertisementServiceProvider( + this); +} + +FakeBluetoothLEAdvertisementServiceProvider:: + ~FakeBluetoothLEAdvertisementServiceProvider() { + VLOG(1) << "Cleaning up Bluetooth Advertisement: " << object_path_.value(); + + FakeBluetoothLEAdvertisingManagerClient* + fake_bluetooth_profile_manager_client = + static_cast<FakeBluetoothLEAdvertisingManagerClient*>( + bluez::BluezDBusManager::Get() + ->GetBluetoothLEAdvertisingManagerClient()); + fake_bluetooth_profile_manager_client->UnregisterAdvertisementServiceProvider( + this); +} + +void FakeBluetoothLEAdvertisementServiceProvider::Release() { + VLOG(1) << object_path_.value() << ": Release"; + delegate_->Released(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h new file mode 100644 index 0000000..29c8133 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h @@ -0,0 +1,50 @@ +// Copyright 2015 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_ + +#include "base/bind.h" +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "dbus/file_descriptor.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h" + +namespace bluez { + +// FakeBluetoothAdvertisementServiceProvider simulates the behavior of a local +// Bluetooth agent object and is used both in test cases in place of a +// mock and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothLEAdvertisementServiceProvider + : public BluetoothLEAdvertisementServiceProvider { + public: + FakeBluetoothLEAdvertisementServiceProvider( + const dbus::ObjectPath& object_path, + Delegate* delegate); + ~FakeBluetoothLEAdvertisementServiceProvider() override; + + // Each of these calls the equivalent + // BluetoothAdvertisementServiceProvider::Delegate method on the object passed + // on construction. + void Release(); + + const dbus::ObjectPath& object_path() { return object_path_; } + + private: + friend class FakeBluetoothLEAdvertisingManagerClient; + + // All incoming method calls are passed on to the Delegate and a callback + // passed to generate the reply. |delegate_| is generally the object that + // owns this one, and must outlive it. + Delegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisementServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISEMENT_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc new file mode 100644 index 0000000..2fcccd1 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.cc @@ -0,0 +1,101 @@ +// Copyright 2015 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 "base/location.h" +#include "base/logging.h" +#include "base/single_thread_task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_proxy.h" +#include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h" +#include "device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +const char FakeBluetoothLEAdvertisingManagerClient::kAdvertisingManagerPath[] = + "/fake/hci0"; + +FakeBluetoothLEAdvertisingManagerClient:: + FakeBluetoothLEAdvertisingManagerClient() {} + +FakeBluetoothLEAdvertisingManagerClient:: + ~FakeBluetoothLEAdvertisingManagerClient() {} + +void FakeBluetoothLEAdvertisingManagerClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothLEAdvertisingManagerClient::AddObserver(Observer* observer) {} + +void FakeBluetoothLEAdvertisingManagerClient::RemoveObserver( + Observer* observer) {} + +void FakeBluetoothLEAdvertisingManagerClient::RegisterAdvertisement( + const dbus::ObjectPath& manager_object_path, + const dbus::ObjectPath& advertisement_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "RegisterAdvertisment: " << advertisement_object_path.value(); + + if (manager_object_path != dbus::ObjectPath(kAdvertisingManagerPath)) { + error_callback.Run(kNoResponseError, "Invalid Advertising Manager path."); + return; + } + + ServiceProviderMap::iterator iter = + service_provider_map_.find(advertisement_object_path); + if (iter == service_provider_map_.end()) { + error_callback.Run(bluetooth_advertising_manager::kErrorInvalidArguments, + "Advertisement object not registered"); + } else if (!currently_registered_.value().empty()) { + error_callback.Run(bluetooth_advertising_manager::kErrorFailed, + "Maximum advertisements reached"); + } else { + currently_registered_ = advertisement_object_path; + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + } +} + +void FakeBluetoothLEAdvertisingManagerClient::UnregisterAdvertisement( + const dbus::ObjectPath& manager_object_path, + const dbus::ObjectPath& advertisement_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "UnregisterAdvertisment: " << advertisement_object_path.value(); + + if (manager_object_path != dbus::ObjectPath(kAdvertisingManagerPath)) { + error_callback.Run(kNoResponseError, "Invalid Advertising Manager path."); + return; + } + + ServiceProviderMap::iterator iter = + service_provider_map_.find(advertisement_object_path); + if (iter == service_provider_map_.end()) { + error_callback.Run(bluetooth_advertising_manager::kErrorDoesNotExist, + "Advertisement not registered"); + } else if (advertisement_object_path != currently_registered_) { + error_callback.Run(bluetooth_advertising_manager::kErrorDoesNotExist, + "Does not exist"); + } else { + currently_registered_ = dbus::ObjectPath(""); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + } +} + +void FakeBluetoothLEAdvertisingManagerClient:: + RegisterAdvertisementServiceProvider( + FakeBluetoothLEAdvertisementServiceProvider* service_provider) { + service_provider_map_[service_provider->object_path_] = service_provider; +} + +void FakeBluetoothLEAdvertisingManagerClient:: + UnregisterAdvertisementServiceProvider( + FakeBluetoothLEAdvertisementServiceProvider* service_provider) { + ServiceProviderMap::iterator iter = + service_provider_map_.find(service_provider->object_path_); + if (iter != service_provider_map_.end() && iter->second == service_provider) + service_provider_map_.erase(iter); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h new file mode 100644 index 0000000..ae0d914 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h @@ -0,0 +1,80 @@ +// Copyright 2015 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_ + +#include <map> +#include <string> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/macros.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h" + +namespace bluez { + +class FakeBluetoothLEAdvertisementServiceProvider; + +// FakeBluetoothAdvertisementManagerClient simulates the behavior of the +// Bluetooth +// Daemon's profile manager object and is used both in test cases in place of a +// mock and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothLEAdvertisingManagerClient + : public BluetoothLEAdvertisingManagerClient { + public: + FakeBluetoothLEAdvertisingManagerClient(); + ~FakeBluetoothLEAdvertisingManagerClient() override; + + // DBusClient overrides: + void Init(dbus::Bus* bus) override; + + // BluetoothAdvertisingManagerClient overrides: + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + void RegisterAdvertisement(const dbus::ObjectPath& manager_object_path, + const dbus::ObjectPath& advertisement_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void UnregisterAdvertisement( + const dbus::ObjectPath& manager_object_path, + const dbus::ObjectPath& advertisement_object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Register, unregister and retrieve pointers to profile server providers. + void RegisterAdvertisementServiceProvider( + FakeBluetoothLEAdvertisementServiceProvider* service_provider); + void UnregisterAdvertisementServiceProvider( + FakeBluetoothLEAdvertisementServiceProvider* service_provider); + FakeBluetoothLEAdvertisementServiceProvider* GetAdvertisementServiceProvider( + const std::string& uuid); + + // Advertising manager path that we simulate. + static const char kAdvertisingManagerPath[]; + + private: + // Map of a D-Bus object path to the FakeBluetoothAdvertisementServiceProvider + // registered for it; maintained by RegisterAdvertisementServiceProvider() and + // UnregisterProfileServiceProvicer() called by the constructor and + // destructor of FakeBluetoothAdvertisementServiceProvider. + typedef std::map<dbus::ObjectPath, + FakeBluetoothLEAdvertisementServiceProvider*> + ServiceProviderMap; + ServiceProviderMap service_provider_map_; + + // Holds the currently registered advertisement. If there is no advertisement + // registered, this path is empty. + dbus::ObjectPath currently_registered_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisingManagerClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_LE_ADVERTISING_MANAGER_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_media_client.cc b/device/bluetooth/dbus/fake_bluetooth_media_client.cc new file mode 100644 index 0000000..246a140 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_media_client.cc @@ -0,0 +1,134 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_media_client.h" + +#include <string> + +#include "base/stl_util.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h" + +using dbus::ObjectPath; + +namespace { + +// Except for |kFailedError|, the other error is defined in BlueZ D-Bus Media +// API. +const char kFailedError[] = "org.chromium.Error.Failed"; +const char kInvalidArgumentsError[] = "org.chromium.Error.InvalidArguments"; + +} // namespace + +namespace bluez { + +// static +const uint8_t FakeBluetoothMediaClient::kDefaultCodec = 0x00; + +FakeBluetoothMediaClient::FakeBluetoothMediaClient() + : visible_(true), + object_path_(ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)) {} + +FakeBluetoothMediaClient::~FakeBluetoothMediaClient() {} + +void FakeBluetoothMediaClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothMediaClient::AddObserver( + BluetoothMediaClient::Observer* observer) { + DCHECK(observer); + observers_.AddObserver(observer); +} + +void FakeBluetoothMediaClient::RemoveObserver( + BluetoothMediaClient::Observer* observer) { + DCHECK(observer); + observers_.RemoveObserver(observer); +} + +void FakeBluetoothMediaClient::RegisterEndpoint( + const ObjectPath& object_path, + const ObjectPath& endpoint_path, + const EndpointProperties& properties, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (!visible_) + return; + + VLOG(1) << "RegisterEndpoint: " << endpoint_path.value(); + + // The media client and adapter client should have the same object path. + if (object_path != object_path_ || + properties.uuid != BluetoothMediaClient::kBluetoothAudioSinkUUID || + properties.codec != kDefaultCodec || properties.capabilities.empty()) { + error_callback.Run(kInvalidArgumentsError, ""); + return; + } + + callback.Run(); +} + +void FakeBluetoothMediaClient::UnregisterEndpoint( + const ObjectPath& object_path, + const ObjectPath& endpoint_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + // TODO(mcchou): Come up with some corresponding actions. + VLOG(1) << "UnregisterEndpoint: " << endpoint_path.value(); + + if (!ContainsKey(endpoints_, endpoint_path)) { + error_callback.Run(kFailedError, "Unknown media endpoint"); + return; + } + + SetEndpointRegistered(endpoints_[endpoint_path], false); + callback.Run(); +} + +void FakeBluetoothMediaClient::SetVisible(bool visible) { + visible_ = visible; + + if (visible_) + return; + + // If the media object becomes invisible, an update chain will unregister all + // endpoints and set the associated transport objects to be invalid. + // SetEndpointRegistered will remove the endpoint entry from |endpoints_|. + while (endpoints_.begin() != endpoints_.end()) + SetEndpointRegistered(endpoints_.begin()->second, false); + + // Notifies observers about the change on |visible_|. + FOR_EACH_OBSERVER(BluetoothMediaClient::Observer, observers_, + MediaRemoved(object_path_)); +} + +void FakeBluetoothMediaClient::SetEndpointRegistered( + FakeBluetoothMediaEndpointServiceProvider* endpoint, + bool registered) { + if (registered) { + endpoints_[endpoint->object_path()] = endpoint; + return; + } + + if (!IsRegistered(endpoint->object_path())) + return; + + // Once a media endpoint object becomes invalid, invalidate the associated + // transport. + FakeBluetoothMediaTransportClient* transport = + static_cast<FakeBluetoothMediaTransportClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient()); + transport->SetValid(endpoint, false); + + endpoints_.erase(endpoint->object_path()); + endpoint->Released(); +} + +bool FakeBluetoothMediaClient::IsRegistered( + const dbus::ObjectPath& endpoint_path) { + return ContainsKey(endpoints_, endpoint_path); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_media_client.h b/device/bluetooth/dbus/fake_bluetooth_media_client.h new file mode 100644 index 0000000..2049f43 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_media_client.h @@ -0,0 +1,78 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_CLIENT_H_ + +#include <map> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_media_client.h" + +namespace bluez { + +class FakeBluetoothMediaEndpointServiceProvider; + +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothMediaClient + : public BluetoothMediaClient { + public: + // The default codec is SBC(0x00). + static const uint8_t kDefaultCodec; + + FakeBluetoothMediaClient(); + ~FakeBluetoothMediaClient() override; + + // DBusClient override. + void Init(dbus::Bus* bus) override; + + // BluetoothMediaClient overrides. + void AddObserver(BluetoothMediaClient::Observer* observer) override; + void RemoveObserver(BluetoothMediaClient::Observer* observer) override; + void RegisterEndpoint(const dbus::ObjectPath& object_path, + const dbus::ObjectPath& endpoint_path, + const EndpointProperties& properties, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void UnregisterEndpoint(const dbus::ObjectPath& object_path, + const dbus::ObjectPath& endpoint_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Makes the media object visible/invisible to emulate the addition/removal + // events. + void SetVisible(bool visible); + + // Sets the registration state for a given media endpoint. + void SetEndpointRegistered( + FakeBluetoothMediaEndpointServiceProvider* endpoint, + bool registered); + + // Indicates whether the given endpoint path is registered or not. + bool IsRegistered(const dbus::ObjectPath& endpoint_path); + + private: + // Indicates whether the media object is visible or not. + bool visible_; + + // The path of the media object. + dbus::ObjectPath object_path_; + + // Map of registered endpoints. Each pair is composed of an endpoint path as + // key and a pointer to the endpoint as value. + std::map<dbus::ObjectPath, FakeBluetoothMediaEndpointServiceProvider*> + endpoints_; + + // List of observers interested in event notifications from us. + base::ObserverList<BluetoothMediaClient::Observer> observers_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothMediaClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.cc new file mode 100644 index 0000000..83a0822 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.cc @@ -0,0 +1,65 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h" + +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h" + +using dbus::ObjectPath; + +namespace bluez { + +FakeBluetoothMediaEndpointServiceProvider:: + FakeBluetoothMediaEndpointServiceProvider(const ObjectPath& object_path, + Delegate* delegate) + : visible_(false), object_path_(object_path), delegate_(delegate) { + VLOG(1) << "Create Bluetooth Media Endpoint: " << object_path_.value(); +} + +FakeBluetoothMediaEndpointServiceProvider:: + ~FakeBluetoothMediaEndpointServiceProvider() { + VLOG(1) << "Cleaning up Bluetooth Media Endpoint: " << object_path_.value(); +} + +void FakeBluetoothMediaEndpointServiceProvider::SetConfiguration( + const ObjectPath& transport_path, + const Delegate::TransportProperties& properties) { + VLOG(1) << object_path_.value() << ": SetConfiguration for " + << transport_path.value(); + + delegate_->SetConfiguration(transport_path, properties); +} + +void FakeBluetoothMediaEndpointServiceProvider::SelectConfiguration( + const std::vector<uint8_t>& capabilities, + const Delegate::SelectConfigurationCallback& callback) { + VLOG(1) << object_path_.value() << ": SelectConfiguration"; + + delegate_->SelectConfiguration(capabilities, callback); + + // Makes the transport object valid for the given endpoint path. + FakeBluetoothMediaTransportClient* transport = + static_cast<FakeBluetoothMediaTransportClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient()); + DCHECK(transport); + transport->SetValid(this, true); +} + +void FakeBluetoothMediaEndpointServiceProvider::ClearConfiguration( + const ObjectPath& transport_path) { + VLOG(1) << object_path_.value() << ": ClearConfiguration on " + << transport_path.value(); + + delegate_->ClearConfiguration(transport_path); +} + +void FakeBluetoothMediaEndpointServiceProvider::Released() { + VLOG(1) << object_path_.value() << ": Released"; + + delegate_->Released(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h new file mode 100644 index 0000000..2e6b18a --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h @@ -0,0 +1,58 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_ + +#include <vector> + +#include "base/logging.h" +#include "base/macros.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_media_endpoint_service_provider.h" +#include "testing/gtest/include/gtest/gtest_prod.h" + +namespace bluez { + +// FakeBluetoothMediaEndpointServiceProvider simulates the behavior of a local +// Bluetooth Media Endpoint object. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothMediaEndpointServiceProvider + : public BluetoothMediaEndpointServiceProvider { + public: + FakeBluetoothMediaEndpointServiceProvider(const dbus::ObjectPath& object_path, + Delegate* delegate); + ~FakeBluetoothMediaEndpointServiceProvider() override; + + // Each of these calls the equivalent BluetoothMediaEnpointServiceProvider:: + // Delegate method on the object passed on construction. + void SetConfiguration(const dbus::ObjectPath& transport_path, + const Delegate::TransportProperties& properties); + void SelectConfiguration( + const std::vector<uint8_t>& capabilities, + const Delegate::SelectConfigurationCallback& callback); + void ClearConfiguration(const dbus::ObjectPath& transport_path); + void Released(); + + // Gets the path of the media endpoint object. + const dbus::ObjectPath& object_path() const { return object_path_; } + + private: + // Indicates whether the endpoint object is visible or not. + bool visible_; + + // The path of the media endpoint object. + dbus::ObjectPath object_path_; + + // All incoming method calls are passed to |delegate_|. |callback| passed to + // |delegate_| will generate the response for those methods which have + // non-void return. + Delegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothMediaEndpointServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_ENDPOINT_SERVICE_PROVIDER_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc new file mode 100644 index 0000000..1a0a106 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc @@ -0,0 +1,328 @@ +// Copyright 2014 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 "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h" + +#include <unistd.h> +#include <sys/socket.h> + +#include <sstream> + +#include "base/bind.h" +#include "base/stl_util.h" +#include "dbus/file_descriptor.h" +#include "device/bluetooth/dbus/bluetooth_media_client.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_client.h" +#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h" + +using dbus::ObjectPath; + +namespace { + +// TODO(mcchou): Remove this constants once it is in cros_system_api. +const char kBluetoothMediaTransportInterface[] = "org.bluez.MediaTransport1"; +const char kNotImplemented[] = "org.bluez.NotImplemented"; +const char kNotAuthorized[] = "org.bluez.NotAuthorized"; +const char kFailed[] = "org.bluez.Failed"; +const char kNotAvailable[] = "org.bluez.NotAvailable"; + +const int kInvalidFd = -1; + +ObjectPath GenerateTransportPath() { + static unsigned int sequence_number = 0; + ++sequence_number; + std::stringstream path; + path << bluez::FakeBluetoothAdapterClient::kAdapterPath + << bluez::FakeBluetoothMediaTransportClient::kTransportDevicePath + << "/fd" << sequence_number; + return ObjectPath(path.str()); +} + +#define UINT8_VECTOR_FROM_ARRAY(array) \ + std::vector<uint8_t>(array, array + arraysize(array)) + +} // namespace + +namespace bluez { + +// static +const char FakeBluetoothMediaTransportClient::kTransportDevicePath[] = + "/fake_audio_source"; +const uint8_t FakeBluetoothMediaTransportClient::kTransportCodec = 0x00; +const uint8_t FakeBluetoothMediaTransportClient::kTransportConfiguration[] = { + 0x21, 0x15, 0x33, 0x2C}; +const uint8_t FakeBluetoothMediaTransportClient::kTransportConfigurationLength = + arraysize(FakeBluetoothMediaTransportClient::kTransportConfiguration); +const uint16_t FakeBluetoothMediaTransportClient::kTransportDelay = 5; +const uint16_t FakeBluetoothMediaTransportClient::kTransportVolume = 50; +const uint16_t FakeBluetoothMediaTransportClient::kDefaultReadMtu = 20; +const uint16_t FakeBluetoothMediaTransportClient::kDefaultWriteMtu = 25; + +FakeBluetoothMediaTransportClient::Properties::Properties( + const PropertyChangedCallback& callback) + : BluetoothMediaTransportClient::Properties( + nullptr, + kBluetoothMediaTransportInterface, + callback) {} + +FakeBluetoothMediaTransportClient::Properties::~Properties() {} + +void FakeBluetoothMediaTransportClient::Properties::Get( + dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) { + VLOG(1) << "Get " << property->name(); + callback.Run(false); +} + +void FakeBluetoothMediaTransportClient::Properties::GetAll() { + VLOG(1) << "GetAll called."; +} + +void FakeBluetoothMediaTransportClient::Properties::Set( + dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) { + VLOG(1) << "Set " << property->name(); + callback.Run(false); +} + +FakeBluetoothMediaTransportClient::Transport::Transport( + const ObjectPath& transport_path, + Properties* transport_properties) + : path(transport_path) { + properties.reset(transport_properties); +} + +FakeBluetoothMediaTransportClient::Transport::~Transport() {} + +FakeBluetoothMediaTransportClient::FakeBluetoothMediaTransportClient() {} + +FakeBluetoothMediaTransportClient::~FakeBluetoothMediaTransportClient() { + STLDeleteValues(&endpoint_to_transport_map_); +} + +// DBusClient override. +void FakeBluetoothMediaTransportClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothMediaTransportClient::AddObserver( + BluetoothMediaTransportClient::Observer* observer) { + observers_.AddObserver(observer); +} + +void FakeBluetoothMediaTransportClient::RemoveObserver( + BluetoothMediaTransportClient::Observer* observer) { + observers_.RemoveObserver(observer); +} + +FakeBluetoothMediaTransportClient::Properties* +FakeBluetoothMediaTransportClient::GetProperties( + const ObjectPath& object_path) { + const ObjectPath& endpoint_path = GetEndpointPath(object_path); + Transport* transport = GetTransport(endpoint_path); + if (!transport) + return nullptr; + return transport->properties.get(); +} + +void FakeBluetoothMediaTransportClient::Acquire( + const ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "Acquire - transport path: " << object_path.value(); + AcquireInternal(false, object_path, callback, error_callback); +} + +void FakeBluetoothMediaTransportClient::TryAcquire( + const ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "TryAcquire - transport path: " << object_path.value(); + AcquireInternal(true, object_path, callback, error_callback); +} + +void FakeBluetoothMediaTransportClient::Release( + const ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + error_callback.Run(kNotImplemented, ""); +} + +void FakeBluetoothMediaTransportClient::SetValid( + FakeBluetoothMediaEndpointServiceProvider* endpoint, + bool valid) { + FakeBluetoothMediaClient* media = static_cast<FakeBluetoothMediaClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothMediaClient()); + DCHECK(media); + + ObjectPath endpoint_path(endpoint->object_path()); + if (!media->IsRegistered(endpoint_path)) + return; + + if (valid) { + ObjectPath transport_path = GenerateTransportPath(); + VLOG(1) << "New transport, " << transport_path.value() + << " is created for endpoint " << endpoint_path.value(); + + // Sets the fake property set with default values. + scoped_ptr<Properties> properties(new Properties( + base::Bind(&FakeBluetoothMediaTransportClient::OnPropertyChanged, + base::Unretained(this)))); + properties->device.ReplaceValue(ObjectPath(kTransportDevicePath)); + properties->uuid.ReplaceValue( + BluetoothMediaClient::kBluetoothAudioSinkUUID); + properties->codec.ReplaceValue(kTransportCodec); + properties->configuration.ReplaceValue( + UINT8_VECTOR_FROM_ARRAY(kTransportConfiguration)); + properties->state.ReplaceValue(BluetoothMediaTransportClient::kStateIdle); + properties->delay.ReplaceValue(kTransportDelay); + properties->volume.ReplaceValue(kTransportVolume); + + endpoint_to_transport_map_[endpoint_path] = + new Transport(transport_path, properties.release()); + transport_to_endpoint_map_[transport_path] = endpoint_path; + return; + } + + Transport* transport = GetTransport(endpoint_path); + if (!transport) + return; + ObjectPath transport_path = transport->path; + + // Notifies observers about the state change of the transport. + FOR_EACH_OBSERVER(BluetoothMediaTransportClient::Observer, observers_, + MediaTransportRemoved(transport_path)); + + endpoint->ClearConfiguration(transport_path); + delete transport; + endpoint_to_transport_map_.erase(endpoint_path); + transport_to_endpoint_map_.erase(transport_path); +} + +void FakeBluetoothMediaTransportClient::SetState( + const ObjectPath& endpoint_path, + const std::string& state) { + VLOG(1) << "SetState - state: " << state; + + Transport* transport = GetTransport(endpoint_path); + if (!transport) + return; + + transport->properties->state.ReplaceValue(state); + FOR_EACH_OBSERVER( + BluetoothMediaTransportClient::Observer, observers_, + MediaTransportPropertyChanged( + transport->path, BluetoothMediaTransportClient::kStateProperty)); +} + +void FakeBluetoothMediaTransportClient::SetVolume( + const ObjectPath& endpoint_path, + const uint16_t& volume) { + Transport* transport = GetTransport(endpoint_path); + if (!transport) + return; + + transport->properties->volume.ReplaceValue(volume); + FOR_EACH_OBSERVER( + BluetoothMediaTransportClient::Observer, observers_, + MediaTransportPropertyChanged( + transport->path, BluetoothMediaTransportClient::kVolumeProperty)); +} + +void FakeBluetoothMediaTransportClient::WriteData( + const ObjectPath& endpoint_path, + const std::vector<char>& bytes) { + VLOG(1) << "WriteData - write " << bytes.size() << " bytes"; + + Transport* transport = GetTransport(endpoint_path); + + if (!transport || transport->properties->state.value() != "active") { + VLOG(1) << "WriteData - write operation rejected, since the state isn't " + "active for endpoint: " + << endpoint_path.value(); + return; + } + + if (!transport->input_fd.get()) { + VLOG(1) << "WriteData - invalid input file descriptor"; + return; + } + + ssize_t written_len = + write(transport->input_fd->GetPlatformFile(), bytes.data(), bytes.size()); + if (written_len < 0) { + VLOG(1) << "WriteData - failed to write to the socket"; + return; + } + + VLOG(1) << "WriteData - wrote " << written_len << " bytes to the socket"; +} + +ObjectPath FakeBluetoothMediaTransportClient::GetTransportPath( + const ObjectPath& endpoint_path) { + Transport* transport = GetTransport(endpoint_path); + return transport ? transport->path : ObjectPath(""); +} + +void FakeBluetoothMediaTransportClient::OnPropertyChanged( + const std::string& property_name) { + VLOG(1) << "Property " << property_name << " changed"; +} + +ObjectPath FakeBluetoothMediaTransportClient::GetEndpointPath( + const ObjectPath& transport_path) { + const auto& it = transport_to_endpoint_map_.find(transport_path); + return it != transport_to_endpoint_map_.end() ? it->second : ObjectPath(""); +} + +FakeBluetoothMediaTransportClient::Transport* +FakeBluetoothMediaTransportClient::GetTransport( + const ObjectPath& endpoint_path) { + const auto& it = endpoint_to_transport_map_.find(endpoint_path); + return (it != endpoint_to_transport_map_.end()) ? it->second : nullptr; +} + +FakeBluetoothMediaTransportClient::Transport* +FakeBluetoothMediaTransportClient::GetTransportByPath( + const dbus::ObjectPath& transport_path) { + return GetTransport(GetEndpointPath(transport_path)); +} + +void FakeBluetoothMediaTransportClient::AcquireInternal( + bool try_flag, + const ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback) { + const ObjectPath& endpoint_path = GetEndpointPath(object_path); + Transport* transport = GetTransport(endpoint_path); + if (!transport) { + error_callback.Run(kFailed, ""); + return; + } + + std::string state = transport->properties->state.value(); + if (state == "active") { + error_callback.Run(kNotAuthorized, ""); + return; + } + if (state != "pending") { + error_callback.Run(try_flag ? kNotAvailable : kFailed, ""); + return; + } + + int fds[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { + transport->input_fd.reset(); + error_callback.Run(kFailed, ""); + return; + } + DCHECK((fds[0] > kInvalidFd) && (fds[1] > kInvalidFd)); + transport->input_fd.reset(new base::File(fds[0])); + + dbus::FileDescriptor out_fd(fds[1]); + callback.Run(&out_fd, kDefaultReadMtu, kDefaultWriteMtu); + SetState(endpoint_path, "active"); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_media_transport_client.h b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.h new file mode 100644 index 0000000..8ad3bb9 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.h @@ -0,0 +1,149 @@ +// Copyright 2014 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/files/file.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_media_transport_client.h" + +namespace bluez { + +class FakeBluetoothMediaEndpointServiceProvider; + +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothMediaTransportClient + : public BluetoothMediaTransportClient { + public: + struct Properties : public BluetoothMediaTransportClient::Properties { + explicit Properties(const PropertyChangedCallback& callback); + ~Properties() override; + + void Get(dbus::PropertyBase* property, + dbus::PropertySet::GetCallback callback) override; + void GetAll() override; + void Set(dbus::PropertyBase* property, + dbus::PropertySet::SetCallback callback) override; + }; + + // The default path of the transport object. + static const char kTransportPath[]; + + // The default properties including device, codec, configuration, state, delay + // and volume, owned by a fake media transport object we emulate. + static const char kTransportDevicePath[]; + static const uint8_t kTransportCodec; + static const uint8_t kTransportConfiguration[]; + static const uint8_t kTransportConfigurationLength; + static const uint16_t kTransportDelay; + static const uint16_t kTransportVolume; + + // The default MTUs for read and write. + static const uint16_t kDefaultReadMtu; + static const uint16_t kDefaultWriteMtu; + + FakeBluetoothMediaTransportClient(); + ~FakeBluetoothMediaTransportClient() override; + + // DBusClient override. + void Init(dbus::Bus* bus) override; + + // BluetoothMediaTransportClient override. + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + Properties* GetProperties(const dbus::ObjectPath& object_path) override; + void Acquire(const dbus::ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback) override; + void TryAcquire(const dbus::ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback) override; + void Release(const dbus::ObjectPath& object_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Makes the transport valid/invalid for a given media endpoint. The transport + // object is assigned to the given endpoint if valid is true, false + // otherwise. + void SetValid(FakeBluetoothMediaEndpointServiceProvider* endpoint, + bool valid); + + // Set state/volume property to a certain value. + void SetState(const dbus::ObjectPath& endpoint_path, + const std::string& state); + void SetVolume(const dbus::ObjectPath& endpoint_path, const uint16_t& volume); + + // Writes bytes to the input file descriptor, |input_fd|, associated with a + // transport object which is bound to |endpoint_path|. + void WriteData(const dbus::ObjectPath& endpoint_path, + const std::vector<char>& bytes); + + // Retrieves the transport object path bound to |endpoint_path|. + dbus::ObjectPath GetTransportPath(const dbus::ObjectPath& endpoint_path); + + private: + // This class is used for simulating the scenario where each media endpoint + // has a corresponding transport path and properties. Once an endpoint is + // assigned with a transport path, an object of Transport is created. + struct Transport { + Transport(const dbus::ObjectPath& transport_path, + Properties* transport_properties); + ~Transport(); + + // An unique transport path. + dbus::ObjectPath path; + + // The property set bound with |path|. + scoped_ptr<Properties> properties; + + // This is the internal end of socketpair created for simulation purposes. + // |input_fd| will be initialized when Acquire/TryAcquire is called. + scoped_ptr<base::File> input_fd; + }; + + // Property callback passed while a Properties structure is created. + void OnPropertyChanged(const std::string& property_name); + + // Gets the endpoint path associated with the given transport_path. + dbus::ObjectPath GetEndpointPath(const dbus::ObjectPath& transport_path); + + // Retrieves the transport structure bound to |endpoint_path|. + Transport* GetTransport(const dbus::ObjectPath& endpoint_path); + + // Retrieves the transport structure with |transport_path|. + Transport* GetTransportByPath(const dbus::ObjectPath& transport_path); + + // Helper function used by Acquire and TryAcquire to set up the sockpair and + // invoke callback/error_callback. + void AcquireInternal(bool try_flag, + const dbus::ObjectPath& object_path, + const AcquireCallback& callback, + const ErrorCallback& error_callback); + + // Map of endpoints with valid transport. Each pair is composed of an endpoint + // path and a Transport structure containing a transport path and its + // properties. + std::map<dbus::ObjectPath, Transport*> endpoint_to_transport_map_; + + // Map of valid transports. Each pair is composed of a transport path as the + // key and an endpoint path as the value. This map is used to get the + // corresponding endpoint path when GetProperties() is called. + std::map<dbus::ObjectPath, dbus::ObjectPath> transport_to_endpoint_map_; + + base::ObserverList<BluetoothMediaTransportClient::Observer> observers_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothMediaTransportClient); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_MEDIA_TRANSPORT_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc new file mode 100644 index 0000000..96254a5 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.cc @@ -0,0 +1,111 @@ +// Copyright (c) 2013 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 "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h" + +#include "base/location.h" +#include "base/logging.h" +#include "base/single_thread_task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "dbus/bus.h" +#include "dbus/message.h" +#include "dbus/object_proxy.h" +#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +namespace bluez { + +const char FakeBluetoothProfileManagerClient::kL2capUuid[] = + "4d995052-33cc-4fdf-b446-75f32942a076"; +const char FakeBluetoothProfileManagerClient::kRfcommUuid[] = + "3f6d6dbf-a6ad-45fc-9653-47dc912ef70e"; +const char FakeBluetoothProfileManagerClient::kUnregisterableUuid[] = + "00000000-0000-0000-0000-000000000000"; + +FakeBluetoothProfileManagerClient::FakeBluetoothProfileManagerClient() {} + +FakeBluetoothProfileManagerClient::~FakeBluetoothProfileManagerClient() {} + +void FakeBluetoothProfileManagerClient::Init(dbus::Bus* bus) {} + +void FakeBluetoothProfileManagerClient::RegisterProfile( + const dbus::ObjectPath& profile_path, + const std::string& uuid, + const Options& options, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "RegisterProfile: " << profile_path.value() << ": " << uuid; + + if (uuid == kUnregisterableUuid) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(error_callback, + bluetooth_profile_manager::kErrorInvalidArguments, + "Can't register this UUID")); + return; + } + + // TODO(jamuraa): check options for channel & psm + + ServiceProviderMap::iterator iter = service_provider_map_.find(profile_path); + if (iter == service_provider_map_.end()) { + error_callback.Run(bluetooth_profile_manager::kErrorInvalidArguments, + "No profile created"); + } else { + ProfileMap::iterator piter = profile_map_.find(uuid); + if (piter != profile_map_.end()) { + error_callback.Run(bluetooth_profile_manager::kErrorAlreadyExists, + "Profile already registered"); + } else { + profile_map_[uuid] = profile_path; + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + } + } +} + +void FakeBluetoothProfileManagerClient::UnregisterProfile( + const dbus::ObjectPath& profile_path, + const base::Closure& callback, + const ErrorCallback& error_callback) { + VLOG(1) << "UnregisterProfile: " << profile_path.value(); + + ServiceProviderMap::iterator iter = service_provider_map_.find(profile_path); + if (iter == service_provider_map_.end()) { + error_callback.Run(bluetooth_profile_manager::kErrorInvalidArguments, + "Profile not registered"); + } else { + for (ProfileMap::iterator piter = profile_map_.begin(); + piter != profile_map_.end(); ++piter) { + if (piter->second == profile_path) { + profile_map_.erase(piter); + break; + } + } + + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); + } +} + +void FakeBluetoothProfileManagerClient::RegisterProfileServiceProvider( + FakeBluetoothProfileServiceProvider* service_provider) { + service_provider_map_[service_provider->object_path_] = service_provider; +} + +void FakeBluetoothProfileManagerClient::UnregisterProfileServiceProvider( + FakeBluetoothProfileServiceProvider* service_provider) { + ServiceProviderMap::iterator iter = + service_provider_map_.find(service_provider->object_path_); + if (iter != service_provider_map_.end() && iter->second == service_provider) + service_provider_map_.erase(iter); +} + +FakeBluetoothProfileServiceProvider* +FakeBluetoothProfileManagerClient::GetProfileServiceProvider( + const std::string& uuid) { + ProfileMap::iterator iter = profile_map_.find(uuid); + if (iter == profile_map_.end()) + return nullptr; + return service_provider_map_[iter->second]; +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h new file mode 100644 index 0000000..8ed7826 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h @@ -0,0 +1,74 @@ +// Copyright (c) 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_ + +#include <map> +#include <string> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/observer_list.h" +#include "dbus/object_path.h" +#include "dbus/property.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_profile_manager_client.h" + +namespace bluez { + +class FakeBluetoothProfileServiceProvider; + +// FakeBluetoothProfileManagerClient simulates the behavior of the Bluetooth +// Daemon's profile manager object and is used both in test cases in place of a +// mock and on the Linux desktop. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothProfileManagerClient + : public BluetoothProfileManagerClient { + public: + FakeBluetoothProfileManagerClient(); + ~FakeBluetoothProfileManagerClient() override; + + // BluetoothProfileManagerClient overrides + void Init(dbus::Bus* bus) override; + void RegisterProfile(const dbus::ObjectPath& profile_path, + const std::string& uuid, + const Options& options, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + void UnregisterProfile(const dbus::ObjectPath& profile_path, + const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Register, unregister and retrieve pointers to profile server providers. + void RegisterProfileServiceProvider( + FakeBluetoothProfileServiceProvider* service_provider); + void UnregisterProfileServiceProvider( + FakeBluetoothProfileServiceProvider* service_provider); + FakeBluetoothProfileServiceProvider* GetProfileServiceProvider( + const std::string& uuid); + + // UUIDs recognised for testing. + static const char kL2capUuid[]; + static const char kRfcommUuid[]; + static const char kUnregisterableUuid[]; + + private: + // Map of a D-Bus object path to the FakeBluetoothProfileServiceProvider + // registered for it; maintained by RegisterProfileServiceProvider() and + // UnregisterProfileServiceProvicer() called by the constructor and + // destructor of FakeBluetoothProfileServiceProvider. + typedef std::map<dbus::ObjectPath, FakeBluetoothProfileServiceProvider*> + ServiceProviderMap; + ServiceProviderMap service_provider_map_; + + // Map of Profile UUID to the D-Bus object path of the service provider + // in |service_provider_map_|. Maintained by RegisterProfile() and + // UnregisterProfile() in response to BluetoothProfile methods. + typedef std::map<std::string, dbus::ObjectPath> ProfileMap; + ProfileMap profile_map_; +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_MANAGER_CLIENT_H_ diff --git a/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.cc b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.cc new file mode 100644 index 0000000..1089501 --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2013 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 "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h" + +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h" + +namespace bluez { + +FakeBluetoothProfileServiceProvider::FakeBluetoothProfileServiceProvider( + const dbus::ObjectPath& object_path, + Delegate* delegate) + : object_path_(object_path), delegate_(delegate) { + VLOG(1) << "Creating Bluetooth Profile: " << object_path_.value(); + + FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client = + static_cast<FakeBluetoothProfileManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothProfileManagerClient()); + fake_bluetooth_profile_manager_client->RegisterProfileServiceProvider(this); +} + +FakeBluetoothProfileServiceProvider::~FakeBluetoothProfileServiceProvider() { + VLOG(1) << "Cleaning up Bluetooth Profile: " << object_path_.value(); + + FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client = + static_cast<FakeBluetoothProfileManagerClient*>( + bluez::BluezDBusManager::Get()->GetBluetoothProfileManagerClient()); + fake_bluetooth_profile_manager_client->UnregisterProfileServiceProvider(this); +} + +void FakeBluetoothProfileServiceProvider::Released() { + VLOG(1) << object_path_.value() << ": Released"; + delegate_->Released(); +} + +void FakeBluetoothProfileServiceProvider::NewConnection( + const dbus::ObjectPath& device_path, + scoped_ptr<dbus::FileDescriptor> fd, + const Delegate::Options& options, + const Delegate::ConfirmationCallback& callback) { + VLOG(1) << object_path_.value() << ": NewConnection for " + << device_path.value(); + delegate_->NewConnection(device_path, fd.Pass(), options, callback); +} + +void FakeBluetoothProfileServiceProvider::RequestDisconnection( + const dbus::ObjectPath& device_path, + const Delegate::ConfirmationCallback& callback) { + VLOG(1) << object_path_.value() << ": RequestDisconnection for " + << device_path.value(); + delegate_->RequestDisconnection(device_path, callback); +} + +void FakeBluetoothProfileServiceProvider::Cancel() { + VLOG(1) << object_path_.value() << ": Cancel"; + delegate_->Cancel(); +} + +} // namespace bluez diff --git a/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h new file mode 100644 index 0000000..5d7af8d --- /dev/null +++ b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h @@ -0,0 +1,61 @@ +// Copyright (c) 2013 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. + +#ifndef DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_ +#define DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_ + +#include "base/bind.h" +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "dbus/file_descriptor.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_export.h" +#include "device/bluetooth/dbus/bluetooth_profile_service_provider.h" + +namespace bluez { + +// FakeBluetoothProfileServiceProvider simulates the behavior of a local +// Bluetooth agent object and is used both in test cases in place of a +// mock and on the Linux desktop. +// +// This class is only called from the dbus origin thread and is not thread-safe. +class DEVICE_BLUETOOTH_EXPORT FakeBluetoothProfileServiceProvider + : public BluetoothProfileServiceProvider { + public: + FakeBluetoothProfileServiceProvider(const dbus::ObjectPath& object_path, + Delegate* delegate); + ~FakeBluetoothProfileServiceProvider() override; + + // Each of these calls the equivalent + // BluetoothProfileServiceProvider::Delegate method on the object passed on + // construction. + void Released(); + void NewConnection(const dbus::ObjectPath& device_path, + scoped_ptr<dbus::FileDescriptor> fd, + const Delegate::Options& options, + const Delegate::ConfirmationCallback& callback); + void RequestDisconnection(const dbus::ObjectPath& device_path, + const Delegate::ConfirmationCallback& callback); + void Cancel(); + + const dbus::ObjectPath& object_path() const { return object_path_; } + + private: + friend class FakeBluetoothProfileManagerClient; + + // D-Bus object path we are faking. + dbus::ObjectPath object_path_; + + // All incoming method calls are passed on to the Delegate and a callback + // passed to generate the reply. |delegate_| is generally the object that + // owns this one, and must outlive it. + Delegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothProfileServiceProvider); +}; + +} // namespace bluez + +#endif // DEVICE_BLUETOOTH_DBUS_FAKE_BLUETOOTH_PROFILE_SERVICE_PROVIDER_H_ |