Commit 891c3948 authored by keybuk@chromium.org's avatar keybuk@chromium.org

Bluetooth: Implement new socket API for Chrome OS

Remove the old BluetoothProfileChromeOS implementation and instead
extend BluetoothSocketChromeOS to handle making outgoing connections
and accepting incoming connections through the D-Bus API.

BUG=372493
TEST=device_unittests --gtest_filter=BluetoothSocketChromeOSTest.*

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270245 0039d316-1c4b-4281-b951-d872f2087c98
parent a9a8e2f5
......@@ -18,11 +18,7 @@ const char BluetoothProfileManagerClient::kNoResponseError[] =
"org.chromium.Error.NoResponse";
BluetoothProfileManagerClient::Options::Options()
: role(SYMMETRIC),
require_authentication(false),
require_authorization(false),
auto_connect(true) {
BluetoothProfileManagerClient::Options::Options() {
}
BluetoothProfileManagerClient::Options::~Options() {
......@@ -56,22 +52,24 @@ class BluetoothProfileManagerClientImpl
dbus::MessageWriter dict_writer(NULL);
// Always send Name, even if empty string.
array_writer.OpenDictEntry(&dict_writer);
dict_writer.AppendString(bluetooth_profile_manager::kNameOption);
dict_writer.AppendVariantOfString(options.name);
array_writer.CloseContainer(&dict_writer);
// 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);
}
// Don't send Service if not provided.
if (options.service.length()) {
// 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);
dict_writer.AppendVariantOfString(*(options.service));
array_writer.CloseContainer(&dict_writer);
}
// Don't send the default Role since there's no value for it.
// Send Role if not the default value.
if (options.role != SYMMETRIC) {
dbus::MessageWriter dict_writer(NULL);
array_writer.OpenDictEntry(&dict_writer);
......@@ -87,67 +85,75 @@ class BluetoothProfileManagerClientImpl
array_writer.CloseContainer(&dict_writer);
}
// Don't send Channel unless given.
if (options.channel) {
// 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);
dict_writer.AppendVariantOfUint16(*(options.channel));
array_writer.CloseContainer(&dict_writer);
}
// Don't send PSM unless given.
if (options.psm) {
// 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);
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);
}
// Always send RequireAuthentication, RequireAuthorization and AutoConnect.
array_writer.OpenDictEntry(&dict_writer);
dict_writer.AppendString(
bluetooth_profile_manager::kRequireAuthenticationOption);
dict_writer.AppendVariantOfBool(options.require_authentication);
array_writer.CloseContainer(&dict_writer);
array_writer.OpenDictEntry(&dict_writer);
dict_writer.AppendString(
bluetooth_profile_manager::kRequireAuthorizationOption);
dict_writer.AppendVariantOfBool(options.require_authorization);
array_writer.CloseContainer(&dict_writer);
array_writer.OpenDictEntry(&dict_writer);
dict_writer.AppendString(
bluetooth_profile_manager::kAutoConnectOption);
dict_writer.AppendVariantOfBool(options.auto_connect);
array_writer.CloseContainer(&dict_writer);
// Don't send ServiceRecord if not provided.
if (options.service_record.length()) {
// 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);
dict_writer.AppendVariantOfString(*(options.service_record));
array_writer.CloseContainer(&dict_writer);
}
// Don't send Version if not provided.
if (options.version) {
// 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);
dict_writer.AppendVariantOfUint16(*(options.version));
array_writer.CloseContainer(&dict_writer);
}
// Don't send Features if not provided.
if (options.features) {
// 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);
dict_writer.AppendVariantOfUint16(*(options.features));
array_writer.CloseContainer(&dict_writer);
}
......
......@@ -9,6 +9,7 @@
#include <vector>
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
......@@ -35,37 +36,37 @@ class CHROMEOS_EXPORT BluetoothProfileManagerClient : public DBusClient {
~Options();
// Human readable name for the profile.
std::string name;
scoped_ptr<std::string> name;
// Primary service class UUID (if different from the actual UUID)
std::string service;
scoped_ptr<std::string> service;
// Role.
enum ProfileRole role;
// RFCOMM channel number.
uint16 channel;
scoped_ptr<uint16> channel;
// PSM number.
uint16 psm;
scoped_ptr<uint16> psm;
// Pairing is required before connections will be established.
bool require_authentication;
scoped_ptr<bool> require_authentication;
// Request authorization before connections will be established.
bool require_authorization;
scoped_ptr<bool> require_authorization;
// Force connections when a remote device is connected.
bool auto_connect;
scoped_ptr<bool> auto_connect;
// Manual SDP record.
std::string service_record;
scoped_ptr<std::string> service_record;
// Profile version.
uint16 version;
scoped_ptr<uint16> version;
// Profile features.
uint16 features;
scoped_ptr<uint16> features;
};
virtual ~BluetoothProfileManagerClient();
......
......@@ -65,9 +65,9 @@ void FakeBluetoothProfileManagerClient::UnregisterProfile(
VLOG(1) << "UnregisterProfile: " << profile_path.value();
ServiceProviderMap::iterator iter = service_provider_map_.find(profile_path);
if (iter != service_provider_map_.end()) {
if (iter == service_provider_map_.end()) {
error_callback.Run(bluetooth_profile_manager::kErrorInvalidArguments,
"Profile still registered");
"Profile not registered");
} else {
for (ProfileMap::iterator piter = profile_map_.begin();
piter != profile_map_.end(); ++piter) {
......
......@@ -54,8 +54,6 @@
'bluetooth_pairing_chromeos.h',
'bluetooth_profile.cc',
'bluetooth_profile.h',
'bluetooth_profile_chromeos.cc',
'bluetooth_profile_chromeos.h',
'bluetooth_profile_mac.h',
'bluetooth_profile_mac.mm',
'bluetooth_profile_win.cc',
......
......@@ -243,8 +243,21 @@ void BluetoothAdapterChromeOS::CreateRfcommService(
bool insecure,
const CreateServiceCallback& callback,
const CreateServiceErrorCallback& error_callback) {
// TODO(keybuk): implement.
NOTIMPLEMENTED();
VLOG(1) << object_path_.value() << ": Creating RFCOMM service: "
<< uuid.canonical_value();
scoped_refptr<BluetoothSocketChromeOS> socket =
BluetoothSocketChromeOS::CreateBluetoothSocket(
ui_task_runner_,
socket_thread_,
NULL,
net::NetLog::Source());
socket->Listen(this,
BluetoothSocketChromeOS::kRfcomm,
uuid,
channel,
insecure,
base::Bind(callback, socket),
error_callback);
}
void BluetoothAdapterChromeOS::CreateL2capService(
......@@ -252,8 +265,21 @@ void BluetoothAdapterChromeOS::CreateL2capService(
int psm,
const CreateServiceCallback& callback,
const CreateServiceErrorCallback& error_callback) {
// TODO(keybuk): implement.
NOTIMPLEMENTED();
VLOG(1) << object_path_.value() << ": Creating L2CAP service: "
<< uuid.canonical_value();
scoped_refptr<BluetoothSocketChromeOS> socket =
BluetoothSocketChromeOS::CreateBluetoothSocket(
ui_task_runner_,
socket_thread_,
NULL,
net::NetLog::Source());
socket->Listen(this,
BluetoothSocketChromeOS::kL2cap,
uuid,
psm,
false,
base::Bind(callback, socket),
error_callback);
}
void BluetoothAdapterChromeOS::RemovePairingDelegateInternal(
......
......@@ -78,6 +78,18 @@ class BluetoothAdapterChromeOS
const CreateServiceCallback& callback,
const CreateServiceErrorCallback& error_callback) OVERRIDE;
// Locates the device object by object path (the devices map and
// BluetoothDevice methods are by address).
BluetoothDeviceChromeOS* GetDeviceWithPath(
const dbus::ObjectPath& object_path);
// Announce to observers a change in device state that is not reflected by
// its D-Bus properties.
void NotifyDeviceChanged(BluetoothDeviceChromeOS* device);
// Returns the object path of the adapter.
const dbus::ObjectPath& object_path() const { return object_path_; }
protected:
// BluetoothAdapter:
virtual void RemovePairingDelegateInternal(
......@@ -85,9 +97,6 @@ class BluetoothAdapterChromeOS
private:
friend class BluetoothChromeOSTest;
friend class BluetoothDeviceChromeOS;
friend class BluetoothProfileChromeOS;
friend class BluetoothProfileChromeOSTest;
// typedef for callback parameters that are passed to AddDiscoverySession
// and RemoveDiscoverySession. This is used to queue incoming requests while
......@@ -149,11 +158,6 @@ class BluetoothAdapterChromeOS
void OnRequestDefaultAgentError(const std::string& error_name,
const std::string& error_message);
// Internal method used to locate the device object by object path
// (the devices map and BluetoothDevice methods are by address)
BluetoothDeviceChromeOS* GetDeviceWithPath(
const dbus::ObjectPath& object_path);
// Internal method to obtain a BluetoothPairingChromeOS object for the device
// with path |object_path|. Returns the existing pairing object if the device
// already has one (usually an outgoing connection in progress) or a new
......@@ -178,10 +182,6 @@ class BluetoothAdapterChromeOS
void DiscoveringChanged(bool discovering);
void PresentChanged(bool present);
// Announce to observers a change in device state that is not reflected by
// its D-Bus properties.
void NotifyDeviceChanged(BluetoothDeviceChromeOS* device);
// Called by dbus:: on completion of the discoverable property change.
void OnSetDiscoverable(const base::Closure& callback,
const ErrorCallback& error_callback,
......
......@@ -19,7 +19,6 @@
#include "dbus/bus.h"
#include "device/bluetooth/bluetooth_adapter_chromeos.h"
#include "device/bluetooth/bluetooth_pairing_chromeos.h"
#include "device/bluetooth/bluetooth_profile_chromeos.h"
#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
#include "device/bluetooth/bluetooth_socket.h"
#include "device/bluetooth/bluetooth_socket_chromeos.h"
......@@ -426,7 +425,7 @@ void BluetoothDeviceChromeOS::Forget(const ErrorCallback& error_callback) {
VLOG(1) << object_path_.value() << ": Removing device";
DBusThreadManager::Get()->GetBluetoothAdapterClient()->
RemoveDevice(
adapter_->object_path_,
adapter_->object_path(),
object_path_,
base::Bind(&base::DoNothing),
base::Bind(&BluetoothDeviceChromeOS::OnForgetError,
......@@ -438,32 +437,25 @@ void BluetoothDeviceChromeOS::ConnectToProfile(
device::BluetoothProfile* profile,
const base::Closure& callback,
const ConnectToProfileErrorCallback& error_callback) {
BluetoothProfileChromeOS* profile_chromeos =
static_cast<BluetoothProfileChromeOS*>(profile);
VLOG(1) << object_path_.value() << ": Connecting profile: "
<< profile_chromeos->uuid().canonical_value();
DBusThreadManager::Get()->GetBluetoothDeviceClient()->
ConnectProfile(
object_path_,
profile_chromeos->uuid().canonical_value(),
base::Bind(
&BluetoothDeviceChromeOS::OnConnectProfile,
weak_ptr_factory_.GetWeakPtr(),
profile,
callback),
base::Bind(
&BluetoothDeviceChromeOS::OnConnectProfileError,
weak_ptr_factory_.GetWeakPtr(),
profile,
error_callback));
// TODO(keybuK): Remove.
error_callback.Run("Removed. Use chrome.bluetoothSocket.connect() instead.");
}
void BluetoothDeviceChromeOS::ConnectToService(
const BluetoothUUID& uuid,
const ConnectToServiceCallback& callback,
const ConnectToServiceErrorCallback& error_callback) {
// TODO(keybuk): implement
NOTIMPLEMENTED();
VLOG(1) << object_path_.value() << ": Connecting to service: "
<< uuid.canonical_value();
scoped_refptr<BluetoothSocketChromeOS> socket =
BluetoothSocketChromeOS::CreateBluetoothSocket(
ui_task_runner_,
socket_thread_,
NULL,
net::NetLog::Source());
socket->Connect(this, uuid,
base::Bind(callback, socket),
error_callback);
}
void BluetoothDeviceChromeOS::SetOutOfBandPairingData(
......@@ -729,27 +721,4 @@ void BluetoothDeviceChromeOS::OnForgetError(
error_callback.Run();
}
void BluetoothDeviceChromeOS::OnConnectProfile(
device::BluetoothProfile* profile,
const base::Closure& callback) {
BluetoothProfileChromeOS* profile_chromeos =
static_cast<BluetoothProfileChromeOS*>(profile);
VLOG(1) << object_path_.value() << ": Profile connected: "
<< profile_chromeos->uuid().canonical_value();
callback.Run();
}
void BluetoothDeviceChromeOS::OnConnectProfileError(
device::BluetoothProfile* profile,
const ConnectToProfileErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message) {
BluetoothProfileChromeOS* profile_chromeos =
static_cast<BluetoothProfileChromeOS*>(profile);
VLOG(1) << object_path_.value() << ": Profile connection failed: "
<< profile_chromeos->uuid().canonical_value() << ": "
<< error_name << ": " << error_message;
error_callback.Run(error_message);
}
} // namespace chromeos
......@@ -99,6 +99,9 @@ class BluetoothDeviceChromeOS
// Returns the current pairing object or NULL if no pairing is in progress.
BluetoothPairingChromeOS* GetPairing() const;
// Returns the object path of the device.
const dbus::ObjectPath& object_path() const { return object_path_; }
protected:
// BluetoothDevice override
virtual std::string GetDeviceName() const OVERRIDE;
......@@ -163,16 +166,6 @@ class BluetoothDeviceChromeOS
const std::string& error_name,
const std::string& error_message);
// Called by dbus:: on completion of the D-Bus method call to
// connect a peofile.
void OnConnectProfile(device::BluetoothProfile* profile,
const base::Closure& callback);
void OnConnectProfileError(
device::BluetoothProfile* profile,
const ConnectToProfileErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message);
// Called by dbus:: on completion of the D-Bus method call to start the
// connection monitor.
void OnStartConnectionMonitor(const base::Closure& callback);
......@@ -180,9 +173,6 @@ class BluetoothDeviceChromeOS
const std::string& error_name,
const std::string& error_message);
// Returns the object path of the device; used by BluetoothAdapterChromeOS
const dbus::ObjectPath& object_path() const { return object_path_; }
// The adapter that owns this device instance.
BluetoothAdapterChromeOS* adapter_;
......
......@@ -4,13 +4,7 @@
#include "device/bluetooth/bluetooth_profile.h"
#if defined(OS_CHROMEOS)
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "device/bluetooth/bluetooth_profile_chromeos.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#elif defined(OS_MACOSX)
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#elif defined(OS_WIN)
#include "device/bluetooth/bluetooth_profile_win.h"
......@@ -51,13 +45,7 @@ BluetoothProfile* CreateBluetoothProfileMac(
void BluetoothProfile::Register(const BluetoothUUID& uuid,
const Options& options,
const ProfileCallback& callback) {
#if defined(OS_CHROMEOS)
chromeos::BluetoothProfileChromeOS* profile = NULL;
profile = new chromeos::BluetoothProfileChromeOS(
base::ThreadTaskRunnerHandle::Get(),
device::BluetoothSocketThread::Get());
profile->Init(uuid, options, callback);
#elif defined(OS_MACOSX)
#if defined(OS_MACOSX)
BluetoothProfile* profile = NULL;
if (base::mac::IsOSLionOrLater())
......
This diff is collapsed.
// 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_BLUETOOTH_PROFILE_CHROMEOS_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_CHROMEOS_H_
#include <string>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.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_profile.h"
#include "device/bluetooth/bluetooth_uuid.h"
namespace dbus {
class FileDescriptor;
} // namespace dbus
namespace device {
class BluetoothSocketThread;
} // namespace device
namespace chromeos {
class BluetoothSocketChromeOS;
// The BluetoothProfileChromeOS class implements BluetoothProfile for the
// Chrome OS platform.
class CHROMEOS_EXPORT BluetoothProfileChromeOS
: public device::BluetoothProfile,
public device::BluetoothAdapter::Observer,
public BluetoothProfileServiceProvider::Delegate {
public:
// BluetoothProfile override.
virtual void Unregister() OVERRIDE;
virtual void SetConnectionCallback(
const ConnectionCallback& callback) OVERRIDE;
// Return the UUID of the profile.
const device::BluetoothUUID& uuid() const { return uuid_; }
private:
friend class BluetoothProfile;
BluetoothProfileChromeOS(
scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
scoped_refptr<device::BluetoothSocketThread> socket_thread);
virtual ~BluetoothProfileChromeOS();
// Called by BluetoothProfile::Register to initialize the profile object
// asynchronously. |uuid|, |options| and |callback| are the arguments to
// BluetoothProfile::Register.
void Init(const device::BluetoothUUID& uuid,
const device::BluetoothProfile::Options& options,
const ProfileCallback& callback);
// BluetoothProfileServiceProvider::Delegate override.
virtual void Released() OVERRIDE;
virtual void NewConnection(
const dbus::ObjectPath& device_path,
scoped_ptr<dbus::FileDescriptor> fd,
const BluetoothProfileServiceProvider::Delegate::Options& options,
const ConfirmationCallback& callback) OVERRIDE;
virtual void RequestDisconnection(
const dbus::ObjectPath& device_path,
const ConfirmationCallback& callback) OVERRIDE;
virtual void Cancel() OVERRIDE;
// device::BluetoothAdapter::Observer override.
virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter,
bool present) OVERRIDE;
// Called by dbus:: on completion of the D-Bus method call to register the
// profile object as a result of the adapter becoming present.
void OnInternalRegisterProfile();
void OnInternalRegisterProfileError(const std::string& error_name,
const std::string& error_message);
// Internal method run to get the adapter object during initialization.
void OnGetAdapter(const ProfileCallback& callback,
scoped_refptr<device::BluetoothAdapter> adapter);
// Called by dbus:: on completion of the D-Bus method call to register the
// profile object during initialization.
void OnRegisterProfile(const ProfileCallback& callback);
void OnRegisterProfileError(const ProfileCallback& callback,
const std::string& error_name,
const std::string& error_message);
// Called by dbus:: on completion of the D-Bus method call to unregister
// the profile object.
void OnUnregisterProfile();
void OnUnregisterProfileError(const std::string& error_name,
const std::string& error_message);
// Method run once the file descriptor has been validated in order to get
// the device object to be passed to the connection callback.
//
// The |fd| argument is moved compared to the NewConnection() call since it
// becomes the result of a PostTaskAndReplyWithResult() call.
void OnCheckValidity(
const dbus::ObjectPath& device_path,
const BluetoothProfileServiceProvider::Delegate::Options& options,
const ConfirmationCallback& callback,
scoped_ptr<dbus::FileDescriptor> fd);
// Methods run after the socket has been connected to a
// BluetoothSocketChromeOS instance on the I/O thread, these methods complete
// the incoming connection calling both the Bluetooth daemon callback
// |callback| to indicate success or failure and calling this object's
// new connection callback method.
void OnConnect(const dbus::ObjectPath& device_path,
scoped_refptr<BluetoothSocketChromeOS> socket,
const ConfirmationCallback& callback);
void OnConnectError(const ConfirmationCallback& callback,
const std::string& error_message);
// UUID of the profile passed during initialization.
device::BluetoothUUID uuid_;
// Copy of the profile options passed during initialization.
BluetoothProfileManagerClient::Options options_;
// Object path of the local profile D-Bus object.
dbus::ObjectPath object_path_;
// Local profile D-Bus object used for receiving profile delegate methods
// from BlueZ.
scoped_ptr<BluetoothProfileServiceProvider> profile_;
// Reference to the adapter object, the profile is re-registered when the
// adapter changes.
scoped_refptr<device::BluetoothAdapter> adapter_;
// Callback used on both outgoing and incoming connections to pass the
// connected socket to profile object owner.
ConnectionCallback connection_callback_;
// UI thread task runner and socket thread object used to create sockets.
scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
scoped_refptr<device::BluetoothSocketThread> socket_thread_;
// 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<BluetoothProfileChromeOS> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothProfileChromeOS);
};
} // namespace chromeos
#endif // DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_CHROMEOS_H_
......@@ -5,7 +5,16 @@
#ifndef DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_
#include <queue>
#include <string>
#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_socket.h"
#include "device/bluetooth/bluetooth_socket_net.h"
#include "device/bluetooth/bluetooth_uuid.h"
......@@ -16,10 +25,14 @@ class FileDescriptor;
namespace chromeos {
class BluetoothDeviceChromeOS;
// The BluetoothSocketChromeOS class implements BluetoothSocket for the
// Chrome OS platform.
class CHROMEOS_EXPORT BluetoothSocketChromeOS
: public device::BluetoothSocketNet {
: public device::BluetoothSocketNet,
public device::BluetoothAdapter::Observer,
public BluetoothProfileServiceProvider::Delegate {
public:
static scoped_refptr<BluetoothSocketChromeOS> CreateBluetoothSocket(
scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
......@@ -27,14 +40,42 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS
net::NetLog* net_log,
const net::NetLog::Source& source);
virtual void Connect(scoped_ptr<dbus::FileDescriptor> fd,
// Connects this socket to the service on |device| published as UUID |uuid|,
// the underlying protocol and PSM or Channel is obtained through service
// discovery. On a successful connection the socket properties will be updated
// and |success_callback| called. On failure |error_callback| will be called
// with a message explaining the cause of the failure.
virtual void Connect(const BluetoothDeviceChromeOS* device,
const device::BluetoothUUID& uuid,
const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback);
// Listens using this socket using a service published on |adapter|. The
// service is either RFCOMM or L2CAP depending on |socket_type| and published
// as UUID |uuid|. The |psm_or_channel| argument is interpreted according to
// |socket_type|. The |insecure| argument, if true, permits incoming
// connections from unpaired Bluetooth 1.0 and 2.0 devices.
// |success_callback| will be called if the service is successfully
// registered, |error_callback| on failure with a message explaining the
// cause.
enum SocketType { kRfcomm, kL2cap };
virtual void Listen(scoped_refptr<device::BluetoothAdapter> adapter,
SocketType socket_type,
const device::BluetoothUUID& uuid,
int psm_or_channel,
bool insecure,
const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback);
// BluetoothSocket:
virtual void Close() OVERRIDE;
virtual void Disconnect(const base::Closure& callback) OVERRIDE;
virtual void Accept(const AcceptCompletionCallback& success_callback,
const ErrorCompletionCallback& error_callback) OVERRIDE;
// Returns the object path of the socket.
const dbus::ObjectPath& object_path() const { return object_path_; }
protected:
virtual ~BluetoothSocketChromeOS();
......@@ -45,9 +86,122 @@ class CHROMEOS_EXPORT BluetoothSocketChromeOS
net::NetLog* net_log,
const net::NetLog::Source& source);
// Register the underlying profile client object with the Bluetooth Daemon.
void RegisterProfile(const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback);
void OnRegisterProfile(const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback);
void OnRegisterProfileError(const ErrorCompletionCallback& error_callback,
const std::string& error_name,
const std::string& error_message);
// Called by dbus:: on completion of the ConnectProfile() method.
void OnConnectProfile(const base::Closure& success_callback);
void OnConnectProfileError(const ErrorCompletionCallback& error_callback,
const std::string& error_name,
const std::string& error_message);
// BluetoothAdapter::Observer:
virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter,
bool present) OVERRIDE;
// Called by dbus:: on completion of the RegisterProfile() method call
// triggered as a result of the adapter becoming present again.
void OnInternalRegisterProfile();
void OnInternalRegisterProfileError(const std::string& error_name,
const std::string& error_message);
// BluetoothProfileServiceProvider::Delegate:
virtual void Released() OVERRIDE;
virtual void NewConnection(
const dbus::ObjectPath& device_path,
scoped_ptr<dbus::FileDescriptor> fd,
const BluetoothProfileServiceProvider::Delegate::Options& options,
const ConfirmationCallback& callback) OVERRIDE;
virtual void RequestDisconnection(
const dbus::ObjectPath& device_path,
const ConfirmationCallback& callback) OVERRIDE;
virtual void Cancel() OVERRIDE;
// Method run to accept a single incoming connection.
void AcceptConnectionRequest();
// Method run on the socket thread to validate the file descriptor of a new
// connection and set up the underlying net::TCPSocket() for it.
void DoNewConnection(
const dbus::ObjectPath& device_path,
scoped_ptr<dbus::FileDescriptor> fd,
const BluetoothProfileServiceProvider::Delegate::Options& options,
const ConfirmationCallback& callback);
// Method run on the UI thread after a new connection has been accepted and
// a socket allocated in |socket|. Takes care of calling the Accept()
// callback and |callback| with the right arguments based on |status|.
void OnNewConnection(scoped_refptr<BluetoothSocket> socket,
const ConfirmationCallback& callback,
Status status);
// Method run on the socket thread with a valid file descriptor |fd|, once
// complete calls |callback| on the UI thread with an appropriate argument
// indicating success or failure.
void DoConnect(scoped_ptr<dbus::FileDescriptor> fd,
const base::Closure& success_callback,
const ErrorCompletionCallback& error_callback);
const ConfirmationCallback& callback);
// Method run to clean-up a listening socket.
void DoCloseListening();
// Unregister the underlying profile client object from the Bluetooth Daemon.
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
// socket is listening.
scoped_refptr<device::BluetoothAdapter> adapter_;
// Address and D-Bus object path of the device being connected to, empty and
// ignored if the socket is listening.
std::string device_address_;
dbus::ObjectPath device_path_;
// UUID of the profile being connected to, or listening on.
device::BluetoothUUID uuid_;
// Copy of the profile options used for registering the profile.
scoped_ptr<BluetoothProfileManagerClient::Options> options_;
// Object path of the local profile D-Bus object.
dbus::ObjectPath object_path_;
// Local profile D-Bus object used for receiving profile delegate methods
// from BlueZ.
scoped_ptr<BluetoothProfileServiceProvider> profile_;
// Pending request to an Accept() call.
struct AcceptRequest {
AcceptRequest();
~AcceptRequest();
AcceptCompletionCallback success_callback;
ErrorCompletionCallback error_callback;
};
scoped_ptr<AcceptRequest> accept_request_;
// Queue of incoming connection requests.
struct ConnectionRequest {
ConnectionRequest();
~ConnectionRequest();
dbus::ObjectPath device_path;
scoped_ptr<dbus::FileDescriptor> fd;
BluetoothProfileServiceProvider::Delegate::Options options;
ConfirmationCallback callback;
bool accepting;
bool cancelled;
};
std::queue<linked_ptr<ConnectionRequest> > connection_request_queue_;
DISALLOW_COPY_AND_ASSIGN(BluetoothSocketChromeOS);
};
......
This diff is collapsed.
......@@ -21,10 +21,22 @@ scoped_refptr<BluetoothSocketThread> BluetoothSocketThread::Get() {
return g_instance.Get();
}
// static
void BluetoothSocketThread::CleanupForTesting() {
DCHECK(g_instance.Get());
g_instance.Get() = NULL;
}
BluetoothSocketThread::BluetoothSocketThread()
: active_socket_count_(0) {}
BluetoothSocketThread::~BluetoothSocketThread() {}
BluetoothSocketThread::~BluetoothSocketThread() {
if (thread_) {
thread_->Stop();
thread_.reset(NULL);
task_runner_ = NULL;
}
}
void BluetoothSocketThread::OnSocketActivate() {
DCHECK(thread_checker_.CalledOnValidThread());
......
......@@ -23,6 +23,8 @@ class BluetoothSocketThread
: public base::RefCountedThreadSafe<BluetoothSocketThread> {
public:
static scoped_refptr<BluetoothSocketThread> Get();
static void CleanupForTesting();
void OnSocketActivate();
void OnSocketDeactivate();
......
......@@ -28,9 +28,9 @@
'bluetooth/bluetooth_device_win_unittest.cc',
'bluetooth/bluetooth_chromeos_unittest.cc',
'bluetooth/bluetooth_gatt_chromeos_unittest.cc',
'bluetooth/bluetooth_profile_chromeos_unittest.cc',
'bluetooth/bluetooth_service_record_mac_unittest.mm',
'bluetooth/bluetooth_service_record_win_unittest.cc',
'bluetooth/bluetooth_socket_chromeos_unittest.cc',
'bluetooth/bluetooth_task_manager_win_unittest.cc',
'bluetooth/bluetooth_uuid_unittest.cc',
'nfc/nfc_chromeos_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