Commit f3f0784e authored by jamuraa's avatar jamuraa Committed by Commit bot

Manage profiles in BluetoothAdapter on ChromeOS

Profiles in bluez are not specific to a device.
When client code tries to connect to two different devices, only
one profile is created, managed by BluetoothAdapterChromeOS.

dbus messages are multiplexed based on the device desired using new
class BluetoothAdapterProfileChromeOS.

This is a resubmit with bugfixes after https://codereview.chromium.org/851123002/ was reverted by
https://codereview.chromium.org/868753006/

BUG=421207

Review URL: https://codereview.chromium.org/888913002

Cr-Commit-Position: refs/heads/master@{#314030}
parent c7569a39
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "chromeos/dbus/fake_bluetooth_profile_service_provider.h" #include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
#include "dbus/bus.h" #include "dbus/bus.h"
#include "dbus/message.h" #include "dbus/message.h"
...@@ -53,7 +54,7 @@ void FakeBluetoothProfileManagerClient::RegisterProfile( ...@@ -53,7 +54,7 @@ void FakeBluetoothProfileManagerClient::RegisterProfile(
"Profile already registered"); "Profile already registered");
} else { } else {
profile_map_[uuid] = profile_path; profile_map_[uuid] = profile_path;
callback.Run(); base::MessageLoop::current()->PostTask(FROM_HERE, callback);
} }
} }
} }
...@@ -77,7 +78,7 @@ void FakeBluetoothProfileManagerClient::UnregisterProfile( ...@@ -77,7 +78,7 @@ void FakeBluetoothProfileManagerClient::UnregisterProfile(
} }
} }
callback.Run(); base::MessageLoop::current()->PostTask(FROM_HERE, callback);
} }
} }
......
...@@ -39,6 +39,8 @@ class CHROMEOS_EXPORT FakeBluetoothProfileServiceProvider ...@@ -39,6 +39,8 @@ class CHROMEOS_EXPORT FakeBluetoothProfileServiceProvider
const Delegate::ConfirmationCallback& callback); const Delegate::ConfirmationCallback& callback);
virtual void Cancel(); virtual void Cancel();
const dbus::ObjectPath& object_path() { return object_path_; }
private: private:
friend class FakeBluetoothProfileManagerClient; friend class FakeBluetoothProfileManagerClient;
......
...@@ -27,6 +27,8 @@ component("bluetooth") { ...@@ -27,6 +27,8 @@ component("bluetooth") {
"bluetooth_adapter_factory.h", "bluetooth_adapter_factory.h",
"bluetooth_adapter_mac.h", "bluetooth_adapter_mac.h",
"bluetooth_adapter_mac.mm", "bluetooth_adapter_mac.mm",
"bluetooth_adapter_profile_chromeos.cc",
"bluetooth_adapter_profile_chromeos.h",
"bluetooth_adapter_win.cc", "bluetooth_adapter_win.cc",
"bluetooth_adapter_win.h", "bluetooth_adapter_win.h",
"bluetooth_audio_sink.cc", "bluetooth_audio_sink.cc",
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
'bluetooth_adapter_factory.h', 'bluetooth_adapter_factory.h',
'bluetooth_adapter_mac.h', 'bluetooth_adapter_mac.h',
'bluetooth_adapter_mac.mm', 'bluetooth_adapter_mac.mm',
"bluetooth_adapter_profile_chromeos.cc",
"bluetooth_adapter_profile_chromeos.h",
'bluetooth_adapter_win.cc', 'bluetooth_adapter_win.cc',
'bluetooth_adapter_win.h', 'bluetooth_adapter_win.h',
'bluetooth_audio_sink.cc', 'bluetooth_audio_sink.cc',
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "chromeos/dbus/bluetooth_device_client.h" #include "chromeos/dbus/bluetooth_device_client.h"
#include "chromeos/dbus/bluetooth_input_client.h" #include "chromeos/dbus/bluetooth_input_client.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
#include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_device_chromeos.h" #include "device/bluetooth/bluetooth_device_chromeos.h"
#include "device/bluetooth/bluetooth_pairing_chromeos.h" #include "device/bluetooth/bluetooth_pairing_chromeos.h"
...@@ -929,6 +930,76 @@ void BluetoothAdapterChromeOS::NotifyGattDescriptorValueChanged( ...@@ -929,6 +930,76 @@ void BluetoothAdapterChromeOS::NotifyGattDescriptorValueChanged(
GattDescriptorValueChanged(this, descriptor, value)); GattDescriptorValueChanged(this, descriptor, value));
} }
void BluetoothAdapterChromeOS::UseProfile(
const BluetoothUUID& uuid,
const dbus::ObjectPath& device_path,
const BluetoothProfileManagerClient::Options& options,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback) {
DCHECK(delegate);
if (profiles_.find(uuid) != profiles_.end()) {
// TODO(jamuraa) check that the options are the same and error when they are
// not.
SetProfileDelegate(uuid, device_path, delegate, success_callback,
error_callback);
return;
}
profiles_[uuid] = BluetoothAdapterProfileChromeOS::Register(
this, uuid, options,
base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfile, this, uuid,
device_path, delegate, success_callback, error_callback),
base::Bind(&BluetoothAdapterChromeOS::OnRegisterProfileError, this, uuid,
error_callback));
}
void BluetoothAdapterChromeOS::ReleaseProfile(const BluetoothUUID& uuid) {
if (profiles_.find(uuid) != profiles_.end()) {
delete profiles_[uuid];
profiles_.erase(uuid);
}
}
void BluetoothAdapterChromeOS::OnRegisterProfile(
const BluetoothUUID& uuid,
const dbus::ObjectPath& device_path,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback) {
SetProfileDelegate(uuid, device_path, delegate, success_callback,
error_callback);
}
bool BluetoothAdapterChromeOS::SetProfileDelegate(
const BluetoothUUID& uuid,
const dbus::ObjectPath& device_path,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback) {
if (profiles_[uuid]->SetDelegate(device_path, delegate)) {
success_callback.Run(profiles_[uuid]);
return true;
}
// Already set
error_callback.Run(bluetooth_agent_manager::kErrorAlreadyExists);
return false;
}
void BluetoothAdapterChromeOS::OnRegisterProfileError(
const BluetoothUUID& uuid,
const ErrorCompletionCallback& error_callback,
const std::string& error_name,
const std::string& error_message) {
LOG(WARNING) << object_path_.value()
<< ": Failed to register profile: " << error_name << ": "
<< error_message;
error_callback.Run(error_message);
delete profiles_[uuid];
profiles_.erase(uuid);
}
void BluetoothAdapterChromeOS::OnSetDiscoverable( void BluetoothAdapterChromeOS::OnSetDiscoverable(
const base::Closure& callback, const base::Closure& callback,
const ErrorCallback& error_callback, const ErrorCallback& error_callback,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ #ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ #define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_
#include <map>
#include <queue> #include <queue>
#include <string> #include <string>
#include <utility> #include <utility>
...@@ -16,6 +17,8 @@ ...@@ -16,6 +17,8 @@
#include "chromeos/dbus/bluetooth_agent_service_provider.h" #include "chromeos/dbus/bluetooth_agent_service_provider.h"
#include "chromeos/dbus/bluetooth_device_client.h" #include "chromeos/dbus/bluetooth_device_client.h"
#include "chromeos/dbus/bluetooth_input_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 "dbus/object_path.h"
#include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_audio_sink.h" #include "device/bluetooth/bluetooth_audio_sink.h"
...@@ -29,6 +32,7 @@ class BluetoothSocketThread; ...@@ -29,6 +32,7 @@ class BluetoothSocketThread;
namespace chromeos { namespace chromeos {
class BluetoothChromeOSTest; class BluetoothChromeOSTest;
class BluetoothAdapterProfileChromeOS;
class BluetoothDeviceChromeOS; class BluetoothDeviceChromeOS;
class BluetoothPairingChromeOS; class BluetoothPairingChromeOS;
class BluetoothRemoteGattCharacteristicChromeOS; class BluetoothRemoteGattCharacteristicChromeOS;
...@@ -44,6 +48,11 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS ...@@ -44,6 +48,11 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
public chromeos::BluetoothInputClient::Observer, public chromeos::BluetoothInputClient::Observer,
public chromeos::BluetoothAgentServiceProvider::Delegate { public chromeos::BluetoothAgentServiceProvider::Delegate {
public: public:
typedef base::Callback<void(const std::string& error_message)>
ErrorCompletionCallback;
typedef base::Callback<void(BluetoothAdapterProfileChromeOS* profile)>
ProfileRegisteredCallback;
static base::WeakPtr<BluetoothAdapter> CreateAdapter(); static base::WeakPtr<BluetoothAdapter> CreateAdapter();
// BluetoothAdapter: // BluetoothAdapter:
...@@ -115,6 +124,23 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS ...@@ -115,6 +124,23 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
// Returns the object path of the adapter. // Returns the object path of the adapter.
const dbus::ObjectPath& object_path() const { return object_path_; } const dbus::ObjectPath& object_path() const { return object_path_; }
// Request a profile on the adapter for a custom service with a
// specific UUID for the device at |device_path| to be sent to |delegate|.
// If |device_path| is the empty string, incoming connections will be
// assigned to |delegate|. When the profile is
// successfully registered, |success_callback| will be called with a pointer
// to the profile which is managed by BluetoothAdapterChromeOS. On failure,
// |error_callback| will be called.
void UseProfile(const device::BluetoothUUID& uuid,
const dbus::ObjectPath& device_path,
const BluetoothProfileManagerClient::Options& options,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback);
// Releases the profile associated with |uuid|
void ReleaseProfile(const device::BluetoothUUID& uuid);
protected: protected:
// BluetoothAdapter: // BluetoothAdapter:
void RemovePairingDelegateInternal( void RemovePairingDelegateInternal(
...@@ -235,6 +261,22 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS ...@@ -235,6 +261,22 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
const std::string& error_name, const std::string& error_name,
const std::string& error_message); const std::string& error_message);
// Called by dbus:: on completion of the D-Bus method to register a profile.
void OnRegisterProfile(const device::BluetoothUUID& uuid,
const dbus::ObjectPath& device_path,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback);
bool SetProfileDelegate(const device::BluetoothUUID& uuid,
const dbus::ObjectPath& device_path,
BluetoothProfileServiceProvider::Delegate* delegate,
const ProfileRegisteredCallback& success_callback,
const ErrorCompletionCallback& error_callback);
void OnRegisterProfileError(const device::BluetoothUUID& uuid,
const ErrorCompletionCallback& error_callback,
const std::string& error_name,
const std::string& error_message);
// Processes the queued discovery requests. For each DiscoveryCallbackPair in // Processes the queued discovery requests. For each DiscoveryCallbackPair in
// the queue, this method will try to add a new discovery session. This method // the queue, this method will try to add a new discovery session. This method
// is called whenever a pending D-Bus call to start or stop discovery has // is called whenever a pending D-Bus call to start or stop discovery has
...@@ -275,6 +317,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS ...@@ -275,6 +317,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
scoped_refptr<device::BluetoothSocketThread> socket_thread_; scoped_refptr<device::BluetoothSocketThread> socket_thread_;
// The profiles we have registered with the bluetooth daemon.
std::map<device::BluetoothUUID, BluetoothAdapterProfileChromeOS*> profiles_;
// Note: This should remain the last member so it'll be destroyed and // Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed. // invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<BluetoothAdapterChromeOS> weak_ptr_factory_; base::WeakPtrFactory<BluetoothAdapterChromeOS> weak_ptr_factory_;
......
// 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/bluetooth_adapter_profile_chromeos.h"
#include <string>
#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"
namespace chromeos {
// static
BluetoothAdapterProfileChromeOS* BluetoothAdapterProfileChromeOS::Register(
BluetoothAdapterChromeOS* adapter,
const device::BluetoothUUID& uuid,
const BluetoothProfileManagerClient::Options& options,
const base::Closure& success_callback,
const BluetoothProfileManagerClient::ErrorCallback& error_callback) {
DCHECK(adapter);
BluetoothAdapterProfileChromeOS* profile =
new BluetoothAdapterProfileChromeOS(adapter, uuid);
VLOG(1) << "Registering profile: " << profile->object_path().value();
DBusThreadManager::Get()->GetBluetoothProfileManagerClient()->RegisterProfile(
profile->object_path(), uuid.canonical_value(), options, success_callback,
error_callback);
return profile;
}
BluetoothAdapterProfileChromeOS::BluetoothAdapterProfileChromeOS(
BluetoothAdapterChromeOS* adapter,
const device::BluetoothUUID& uuid)
: uuid_(uuid), adapter_(adapter), weak_ptr_factory_(this) {
std::string uuid_path;
base::ReplaceChars(uuid.canonical_value(), ":-", "_", &uuid_path);
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));
DCHECK(profile_.get());
}
BluetoothAdapterProfileChromeOS::~BluetoothAdapterProfileChromeOS() {
profile_.reset();
}
bool BluetoothAdapterProfileChromeOS::SetDelegate(
const dbus::ObjectPath& device_path,
BluetoothProfileServiceProvider::Delegate* delegate) {
DCHECK(delegate);
VLOG(1) << "SetDelegate: " << object_path_.value() << " dev "
<< device_path.value();
if (delegates_.find(device_path.value()) != delegates_.end()) {
return false;
}
delegates_[device_path.value()] = delegate;
return true;
}
void BluetoothAdapterProfileChromeOS::RemoveDelegate(
const dbus::ObjectPath& device_path,
const base::Closure& unregistered_callback) {
VLOG(1) << object_path_.value() << " dev " << device_path.value()
<< ": RemoveDelegate";
if (delegates_.find(device_path.value()) == delegates_.end())
return;
delegates_.erase(device_path.value());
if (delegates_.size() != 0)
return;
VLOG(1) << device_path.value() << " No delegates left, unregistering.";
// No users left, release the profile.
DBusThreadManager::Get()
->GetBluetoothProfileManagerClient()
->UnregisterProfile(
object_path_, unregistered_callback,
base::Bind(&BluetoothAdapterProfileChromeOS::OnUnregisterProfileError,
weak_ptr_factory_.GetWeakPtr(), unregistered_callback));
}
void BluetoothAdapterProfileChromeOS::OnUnregisterProfileError(
const base::Closure& unregistered_callback,
const std::string& error_name,
const std::string& error_message) {
LOG(WARNING) << this->object_path().value()
<< ": Failed to unregister profile: " << error_name << ": "
<< error_message;
unregistered_callback.Run();
}
// BluetoothProfileServiceProvider::Delegate:
void BluetoothAdapterProfileChromeOS::Released() {
VLOG(1) << object_path_.value() << ": Release";
}
void BluetoothAdapterProfileChromeOS::NewConnection(
const dbus::ObjectPath& device_path,
scoped_ptr<dbus::FileDescriptor> fd,
const BluetoothProfileServiceProvider::Delegate::Options& options,
const ConfirmationCallback& callback) {
dbus::ObjectPath delegate_path = device_path;
if (delegates_.find(device_path.value()) == delegates_.end())
delegate_path = dbus::ObjectPath("");
if (delegates_.find(delegate_path.value()) == delegates_.end()) {
VLOG(1) << object_path_.value() << ": New connection for device "
<< device_path.value() << " which has no delegates!";
callback.Run(REJECTED);
return;
}
delegates_[delegate_path.value()]->NewConnection(device_path, fd.Pass(),
options, callback);
}
void BluetoothAdapterProfileChromeOS::RequestDisconnection(
const dbus::ObjectPath& device_path,
const ConfirmationCallback& callback) {
dbus::ObjectPath delegate_path = device_path;
if (delegates_.find(device_path.value()) == delegates_.end())
delegate_path = dbus::ObjectPath("");
if (delegates_.find(delegate_path.value()) == delegates_.end()) {
VLOG(1) << object_path_.value() << ": RequestDisconnection for device "
<< device_path.value() << " which has no delegates!";
return;
}
delegates_[delegate_path.value()]->RequestDisconnection(device_path,
callback);
}
void BluetoothAdapterProfileChromeOS::Cancel() {
// Cancel() should only go to a delegate accepting connections.
if (delegates_.find("") == delegates_.end()) {
VLOG(1) << object_path_.value() << ": Cancel with no delegate!";
return;
}
delegates_[""]->Cancel();
}
} // namespace chromeos
// 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_BLUETOOTH_ADAPTER_PROFILE_CHROMEOS_H_
#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"
namespace device {
class BluetoothUUID;
} // namespace device
namespace chromeos {
// The BluetoothAdapterProfileChromeOS class implements a multiplexing
// profile for custom Bluetooth services managed by a BluetoothAdapter.
// Maintains a list of delegates which may serve the profile.
// One delegate is allowed for each device.
class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterProfileChromeOS
: public chromeos::BluetoothProfileServiceProvider::Delegate {
public:
// Registers a profile with the BlueZ server for |uuid| with the
// options |options|. Returns a newly allocated pointer, or nullptr
// if there was a problem.
static BluetoothAdapterProfileChromeOS* Register(
BluetoothAdapterChromeOS* adapter,
const device::BluetoothUUID& uuid,
const BluetoothProfileManagerClient::Options& options,
const base::Closure& success_callback,
const BluetoothProfileManagerClient::ErrorCallback& error_callback);
~BluetoothAdapterProfileChromeOS() override;
// The object path of the profile.
const dbus::ObjectPath& object_path() const { return object_path_; }
// Add a delegate for a device associated with this profile.
// An empty |device_path| indicates a local listening service.
// 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);
// Remove the delegate for a device. |unregistered_callback| will be called
// if this unregisters the profile.
void RemoveDelegate(const dbus::ObjectPath& device_path,
const base::Closure& unregistered_callback);
// Returns the number of delegates for this profile.
size_t DelegateCount() const { return delegates_.size(); }
private:
BluetoothAdapterProfileChromeOS(BluetoothAdapterChromeOS* adapter,
const device::BluetoothUUID& uuid);
// BluetoothProfileServiceProvider::Delegate:
void Released() override;
void NewConnection(
const dbus::ObjectPath& device_path,
scoped_ptr<dbus::FileDescriptor> fd,
const BluetoothProfileServiceProvider::Delegate::Options& options,
const ConfirmationCallback& callback) override;
void RequestDisconnection(const dbus::ObjectPath& device_path,
const ConfirmationCallback& callback) override;
void Cancel() override;
// Called by dbus:: on completion of the D-Bus method to unregister a profile.
void OnUnregisterProfileError(const base::Closure& unregistered_callback,
const std::string& error_name,
const std::string& error_message);
// List of delegates which this profile is multiplexing to.
std::map<std::string, BluetoothProfileServiceProvider::Delegate*> delegates_;
// The UUID that this profile represents.
const device::BluetoothUUID& uuid_;
// Registered dbus object path for this profile.
dbus::ObjectPath object_path_;
// Profile dbus object for receiving profile method calls from BlueZ
scoped_ptr<BluetoothProfileServiceProvider> profile_;
// Adapter that owns this profile.
BluetoothAdapterChromeOS* adapter_;
// 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<BluetoothAdapterProfileChromeOS> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterProfileChromeOS);
};
} // namespace chromeos
#endif
...@@ -88,6 +88,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceChromeOS ...@@ -88,6 +88,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceChromeOS
// Returns the object path of the device. // Returns the object path of the device.
const dbus::ObjectPath& object_path() const { return object_path_; } const dbus::ObjectPath& object_path() const { return object_path_; }
// Returns the adapter which owns this device instance.
BluetoothAdapterChromeOS* adapter() const { return adapter_; }
protected: protected:
// BluetoothDevice override // BluetoothDevice override
std::string GetDeviceName() const override; std::string GetDeviceName() const override;
......
...@@ -26,6 +26,8 @@ class FileDescriptor; ...@@ -26,6 +26,8 @@ class FileDescriptor;
namespace chromeos { namespace chromeos {
class BluetoothDeviceChromeOS; class BluetoothDeviceChromeOS;
class BluetoothAdapterChromeOS;
class BluetoothAdapterProfileChromeOS;
// The BluetoothSocketChromeOS class implements BluetoothSocket for the // The BluetoothSocketChromeOS class implements BluetoothSocket for the
// Chrome OS platform. // Chrome OS platform.
...@@ -75,9 +77,6 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS ...@@ -75,9 +77,6 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS
void Accept(const AcceptCompletionCallback& success_callback, void Accept(const AcceptCompletionCallback& success_callback,
const ErrorCompletionCallback& error_callback) override; const ErrorCompletionCallback& error_callback) override;
// Returns the object path of the socket.
const dbus::ObjectPath& object_path() const { return object_path_; }
protected: protected:
~BluetoothSocketChromeOS() override; ~BluetoothSocketChromeOS() override;
...@@ -87,12 +86,13 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS ...@@ -87,12 +86,13 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS
scoped_refptr<device::BluetoothSocketThread> socket_thread); scoped_refptr<device::BluetoothSocketThread> socket_thread);
// Register the underlying profile client object with the Bluetooth Daemon. // Register the underlying profile client object with the Bluetooth Daemon.
void RegisterProfile(const base::Closure& success_callback, void RegisterProfile(BluetoothAdapterChromeOS* adapter,
const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback); const ErrorCompletionCallback& error_callback);
void OnRegisterProfile(const base::Closure& success_callback, void OnRegisterProfile(const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback); const ErrorCompletionCallback& error_callback,
BluetoothAdapterProfileChromeOS* profile);
void OnRegisterProfileError(const ErrorCompletionCallback& error_callback, void OnRegisterProfileError(const ErrorCompletionCallback& error_callback,
const std::string& error_name,
const std::string& error_message); const std::string& error_message);
// Called by dbus:: on completion of the ConnectProfile() method. // Called by dbus:: on completion of the ConnectProfile() method.
...@@ -107,9 +107,8 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS ...@@ -107,9 +107,8 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS
// Called by dbus:: on completion of the RegisterProfile() method call // Called by dbus:: on completion of the RegisterProfile() method call
// triggered as a result of the adapter becoming present again. // triggered as a result of the adapter becoming present again.
void OnInternalRegisterProfile(); void OnInternalRegisterProfile(BluetoothAdapterProfileChromeOS* profile);
void OnInternalRegisterProfileError(const std::string& error_name, void OnInternalRegisterProfileError(const std::string& error_message);
const std::string& error_message);
// BluetoothProfileServiceProvider::Delegate: // BluetoothProfileServiceProvider::Delegate:
void Released() override; void Released() override;
...@@ -151,13 +150,11 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS ...@@ -151,13 +150,11 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS
// Unregister the underlying profile client object from the Bluetooth Daemon. // Unregister the underlying profile client object from the Bluetooth Daemon.
void UnregisterProfile(); void UnregisterProfile();
void OnUnregisterProfile(const dbus::ObjectPath& object_path);
void OnUnregisterProfileError(const dbus::ObjectPath& object_path,
const std::string& error_name,
const std::string& error_message);
// Adapter the profile is registered against; this is only present when the // Releases the profile after the delegate is gone.
// socket is listening. void ReleaseProfile(BluetoothAdapterProfileChromeOS* profile);
// Adapter the profile is registered against
scoped_refptr<device::BluetoothAdapter> adapter_; scoped_refptr<device::BluetoothAdapter> adapter_;
// Address and D-Bus object path of the device being connected to, empty and // Address and D-Bus object path of the device being connected to, empty and
...@@ -171,12 +168,8 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS ...@@ -171,12 +168,8 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS
// Copy of the profile options used for registering the profile. // Copy of the profile options used for registering the profile.
scoped_ptr<BluetoothProfileManagerClient::Options> options_; scoped_ptr<BluetoothProfileManagerClient::Options> options_;
// Object path of the local profile D-Bus object. // The profile registered with the adapter for this socket.
dbus::ObjectPath object_path_; BluetoothAdapterProfileChromeOS* profile_;
// Local profile D-Bus object used for receiving profile delegate methods
// from BlueZ.
scoped_ptr<BluetoothProfileServiceProvider> profile_;
// Pending request to an Accept() call. // Pending request to an Accept() call.
struct AcceptRequest { struct AcceptRequest {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "chromeos/dbus/fake_bluetooth_gatt_service_client.h" #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
#include "chromeos/dbus/fake_bluetooth_input_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_manager_client.h"
#include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
#include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_chromeos.h" #include "device/bluetooth/bluetooth_adapter_chromeos.h"
#include "device/bluetooth/bluetooth_adapter_factory.h" #include "device/bluetooth/bluetooth_adapter_factory.h"
...@@ -144,6 +145,9 @@ class BluetoothSocketChromeOSTest : public testing::Test { ...@@ -144,6 +145,9 @@ class BluetoothSocketChromeOSTest : public testing::Test {
void CreateServiceSuccessCallback(scoped_refptr<BluetoothSocket> socket) { void CreateServiceSuccessCallback(scoped_refptr<BluetoothSocket> socket) {
++success_callback_count_; ++success_callback_count_;
last_socket_ = socket; last_socket_ = socket;
if (message_loop_.is_running())
message_loop_.Quit();
} }
void AcceptSuccessCallback(const BluetoothDevice* device, void AcceptSuccessCallback(const BluetoothDevice* device,
...@@ -187,7 +191,6 @@ TEST_F(BluetoothSocketChromeOSTest, Connect) { ...@@ -187,7 +191,6 @@ TEST_F(BluetoothSocketChromeOSTest, Connect) {
base::Unretained(this)), base::Unretained(this)),
base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback, base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
base::Unretained(this))); base::Unretained(this)));
message_loop_.Run(); message_loop_.Run();
EXPECT_EQ(1U, success_callback_count_); EXPECT_EQ(1U, success_callback_count_);
...@@ -297,6 +300,8 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) { ...@@ -297,6 +300,8 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) {
base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback, base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
base::Unretained(this))); base::Unretained(this)));
message_loop_.Run();
EXPECT_EQ(1U, success_callback_count_); EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_); EXPECT_EQ(0U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != NULL); EXPECT_TRUE(last_socket_.get() != NULL);
...@@ -325,6 +330,8 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) { ...@@ -325,6 +330,8 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) {
base::Bind(&base::DoNothing), base::Bind(&base::DoNothing),
base::Bind(&DoNothingDBusErrorCallback)); base::Bind(&DoNothingDBusErrorCallback));
message_loop_.RunUntilIdle();
server_socket->Accept( server_socket->Accept(
base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback, base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
base::Unretained(this)), base::Unretained(this)),
...@@ -363,6 +370,8 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) { ...@@ -363,6 +370,8 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) {
base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback, base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
base::Unretained(this))); base::Unretained(this)));
message_loop_.RunUntilIdle();
fake_bluetooth_device_client->ConnectProfile( fake_bluetooth_device_client->ConnectProfile(
static_cast<BluetoothDeviceChromeOS*>(device)->object_path(), static_cast<BluetoothDeviceChromeOS*>(device)->object_path(),
FakeBluetoothProfileManagerClient::kRfcommUuid, FakeBluetoothProfileManagerClient::kRfcommUuid,
...@@ -398,6 +407,8 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) { ...@@ -398,6 +407,8 @@ TEST_F(BluetoothSocketChromeOSTest, Listen) {
base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback, base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
base::Unretained(this))); base::Unretained(this)));
message_loop_.RunUntilIdle();
EXPECT_EQ(1U, success_callback_count_); EXPECT_EQ(1U, success_callback_count_);
} }
...@@ -416,6 +427,7 @@ TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) { ...@@ -416,6 +427,7 @@ TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) {
base::Unretained(this)), base::Unretained(this)),
base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback, base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
base::Unretained(this))); base::Unretained(this)));
message_loop_.Run();
EXPECT_EQ(1U, success_callback_count_); EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_); EXPECT_EQ(0U, error_callback_count_);
...@@ -439,6 +451,8 @@ TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) { ...@@ -439,6 +451,8 @@ TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) {
// Make the adapter visible. This should register a profile. // Make the adapter visible. This should register a profile.
fake_bluetooth_adapter_client->SetVisible(true); fake_bluetooth_adapter_client->SetVisible(true);
message_loop_.RunUntilIdle();
profile_service_provider = profile_service_provider =
fake_bluetooth_profile_manager_client->GetProfileServiceProvider( fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
FakeBluetoothProfileManagerClient::kRfcommUuid); FakeBluetoothProfileManagerClient::kRfcommUuid);
...@@ -449,6 +463,8 @@ TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) { ...@@ -449,6 +463,8 @@ TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) {
base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback, base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
base::Unretained(this))); base::Unretained(this)));
message_loop_.RunUntilIdle();
EXPECT_EQ(1U, success_callback_count_); EXPECT_EQ(1U, success_callback_count_);
} }
...@@ -465,6 +481,7 @@ TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) { ...@@ -465,6 +481,7 @@ TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) {
base::Unretained(this)), base::Unretained(this)),
base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback, base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
base::Unretained(this))); base::Unretained(this)));
message_loop_.Run();
EXPECT_EQ(1U, success_callback_count_); EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_); EXPECT_EQ(0U, error_callback_count_);
...@@ -488,14 +505,14 @@ TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) { ...@@ -488,14 +505,14 @@ TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) {
// Make the adapter invisible, and fiddle with the profile fake to unregister // Make the adapter invisible, and fiddle with the profile fake to unregister
// the profile since this doesn't happen automatically. // the profile since this doesn't happen automatically.
fake_bluetooth_adapter_client->SetVisible(false); fake_bluetooth_adapter_client->SetVisible(false);
fake_bluetooth_profile_manager_client->UnregisterProfile(
static_cast<BluetoothSocketChromeOS*>(socket.get())->object_path(), message_loop_.RunUntilIdle();
base::Bind(&base::DoNothing),
base::Bind(&DoNothingDBusErrorCallback));
// Then make the adapter visible again. This should re-register the profile. // Then make the adapter visible again. This should re-register the profile.
fake_bluetooth_adapter_client->SetVisible(true); fake_bluetooth_adapter_client->SetVisible(true);
message_loop_.RunUntilIdle();
profile_service_provider = profile_service_provider =
fake_bluetooth_profile_manager_client->GetProfileServiceProvider( fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
FakeBluetoothProfileManagerClient::kRfcommUuid); FakeBluetoothProfileManagerClient::kRfcommUuid);
...@@ -506,6 +523,8 @@ TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) { ...@@ -506,6 +523,8 @@ TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) {
base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback, base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
base::Unretained(this))); base::Unretained(this)));
message_loop_.RunUntilIdle();
EXPECT_EQ(1U, success_callback_count_); EXPECT_EQ(1U, success_callback_count_);
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
'battery/battery_status_service_unittest.cc', 'battery/battery_status_service_unittest.cc',
'bluetooth/bluetooth_adapter_mac_unittest.mm', 'bluetooth/bluetooth_adapter_mac_unittest.mm',
'bluetooth/bluetooth_adapter_unittest.cc', 'bluetooth/bluetooth_adapter_unittest.cc',
'bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc',
'bluetooth/bluetooth_adapter_win_unittest.cc', 'bluetooth/bluetooth_adapter_win_unittest.cc',
'bluetooth/bluetooth_device_unittest.cc', 'bluetooth/bluetooth_device_unittest.cc',
'bluetooth/bluetooth_device_win_unittest.cc', 'bluetooth/bluetooth_device_win_unittest.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment