summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrkc <rkc@chromium.org>2015-04-27 14:29:01 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-27 21:29:51 +0000
commitc96da18077ef4b5ab28cb8b2684cd84386075e5a (patch)
treecd6d51d9f8272552581eecc9aaa7a5387ade7edc
parent685b5b6b32a9c4dbb09224541574d8a02859d572 (diff)
downloadchromium_src-c96da18077ef4b5ab28cb8b2684cd84386075e5a.zip
chromium_src-c96da18077ef4b5ab28cb8b2684cd84386075e5a.tar.gz
chromium_src-c96da18077ef4b5ab28cb8b2684cd84386075e5a.tar.bz2
Add CPP API for BLE advertisments.
This CL adds the new classes, changes to existing classes and tests for adding the CPP API for LE advertisements. The design for this is available at http://go/chrome-ble-advertising. R=armansito@chromium.org, jamuraa@chromium.org BUG=466375 Review URL: https://codereview.chromium.org/1054743003 Cr-Commit-Position: refs/heads/master@{#327128}
-rw-r--r--chromeos/dbus/bluetooth_le_advertisement_service_provider.cc16
-rw-r--r--chromeos/dbus/bluetooth_le_advertisement_service_provider.h8
-rw-r--r--chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.cc7
-rw-r--r--chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h3
-rw-r--r--chromeos/dbus/fake_bluetooth_le_advertising_manager_client.cc3
-rw-r--r--chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h2
-rw-r--r--device/BUILD.gn1
-rw-r--r--device/bluetooth/BUILD.gn4
-rw-r--r--device/bluetooth/bluetooth.gyp4
-rw-r--r--device/bluetooth/bluetooth_adapter.h13
-rw-r--r--device/bluetooth/bluetooth_adapter_chromeos.cc10
-rw-r--r--device/bluetooth/bluetooth_adapter_chromeos.h5
-rw-r--r--device/bluetooth/bluetooth_adapter_mac.h4
-rw-r--r--device/bluetooth/bluetooth_adapter_mac.mm8
-rw-r--r--device/bluetooth/bluetooth_adapter_unittest.cc5
-rw-r--r--device/bluetooth/bluetooth_adapter_win.cc8
-rw-r--r--device/bluetooth/bluetooth_adapter_win.h4
-rw-r--r--device/bluetooth/bluetooth_advertisement.cc37
-rw-r--r--device/bluetooth/bluetooth_advertisement.h137
-rw-r--r--device/bluetooth/bluetooth_advertisement_chromeos.cc115
-rw-r--r--device/bluetooth/bluetooth_advertisement_chromeos.h59
-rw-r--r--device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc242
-rw-r--r--device/bluetooth/test/mock_bluetooth_adapter.cc6
-rw-r--r--device/bluetooth/test/mock_bluetooth_adapter.h4
-rw-r--r--device/device_tests.gyp1
25 files changed, 685 insertions, 21 deletions
diff --git a/chromeos/dbus/bluetooth_le_advertisement_service_provider.cc b/chromeos/dbus/bluetooth_le_advertisement_service_provider.cc
index aa3f234..f6a4c44 100644
--- a/chromeos/dbus/bluetooth_le_advertisement_service_provider.cc
+++ b/chromeos/dbus/bluetooth_le_advertisement_service_provider.cc
@@ -37,7 +37,6 @@ class BluetoothAdvertisementServiceProviderImpl
: origin_thread_id_(base::PlatformThread::CurrentId()),
bus_(bus),
delegate_(delegate),
- object_path_(object_path),
type_(type),
service_uuids_(service_uuids.Pass()),
manufacturer_data_(manufacturer_data.Pass()),
@@ -49,6 +48,7 @@ class BluetoothAdvertisementServiceProviderImpl
VLOG(1) << "Creating Bluetooth Advertisement: " << object_path_.value();
+ object_path_ = object_path;
exported_object_ = bus_->GetExportedObject(object_path_);
// Export Bluetooth Advertisement interface methods.
@@ -358,10 +358,6 @@ class BluetoothAdvertisementServiceProviderImpl
// 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_;
-
// Advertisement data that needs to be provided to BlueZ when requested.
AdvertisementType type_;
scoped_ptr<UUIDList> service_uuids_;
@@ -391,7 +387,7 @@ BluetoothLEAdvertisementServiceProvider::
}
// static
-BluetoothLEAdvertisementServiceProvider*
+scoped_ptr<BluetoothLEAdvertisementServiceProvider>
BluetoothLEAdvertisementServiceProvider::Create(
dbus::Bus* bus,
const dbus::ObjectPath& object_path,
@@ -402,12 +398,12 @@ BluetoothLEAdvertisementServiceProvider::Create(
scoped_ptr<UUIDList> solicit_uuids,
scoped_ptr<ServiceData> service_data) {
if (!DBusThreadManager::Get()->IsUsingStub(DBusClientBundle::BLUETOOTH)) {
- return new BluetoothAdvertisementServiceProviderImpl(
+ return make_scoped_ptr(new BluetoothAdvertisementServiceProviderImpl(
bus, object_path, delegate, type, service_uuids.Pass(),
- manufacturer_data.Pass(), solicit_uuids.Pass(), service_data.Pass());
+ manufacturer_data.Pass(), solicit_uuids.Pass(), service_data.Pass()));
} else {
- return new FakeBluetoothLEAdvertisementServiceProvider(object_path,
- delegate);
+ return make_scoped_ptr(
+ new FakeBluetoothLEAdvertisementServiceProvider(object_path, delegate));
}
}
diff --git a/chromeos/dbus/bluetooth_le_advertisement_service_provider.h b/chromeos/dbus/bluetooth_le_advertisement_service_provider.h
index 4cea5d8..98622a2 100644
--- a/chromeos/dbus/bluetooth_le_advertisement_service_provider.h
+++ b/chromeos/dbus/bluetooth_le_advertisement_service_provider.h
@@ -50,11 +50,13 @@ class CHROMEOS_EXPORT BluetoothLEAdvertisementServiceProvider {
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 BluetoothLEAdvertisementServiceProvider* Create(
+ static scoped_ptr<BluetoothLEAdvertisementServiceProvider> Create(
dbus::Bus* bus,
const dbus::ObjectPath& object_path,
Delegate* delegate,
@@ -67,6 +69,10 @@ class CHROMEOS_EXPORT BluetoothLEAdvertisementServiceProvider {
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);
};
diff --git a/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.cc b/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.cc
index 24bfb4f..ce46e3d 100644
--- a/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.cc
+++ b/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.cc
@@ -3,8 +3,8 @@
// found in the LICENSE file.
#include "chromeos/dbus/dbus_thread_manager.h"
-#include "fake_bluetooth_le_advertisement_service_provider.h"
-#include "fake_bluetooth_le_advertising_manager_client.h"
+#include "chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h"
+#include "chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h"
namespace chromeos {
@@ -12,7 +12,8 @@ FakeBluetoothLEAdvertisementServiceProvider::
FakeBluetoothLEAdvertisementServiceProvider(
const dbus::ObjectPath& object_path,
Delegate* delegate)
- : object_path_(object_path), delegate_(delegate) {
+ : delegate_(delegate) {
+ object_path_ = object_path;
VLOG(1) << "Creating Bluetooth Advertisement: " << object_path_.value();
FakeBluetoothLEAdvertisingManagerClient*
diff --git a/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h b/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h
index c56abb4..5a19aee 100644
--- a/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h
+++ b/chromeos/dbus/fake_bluetooth_le_advertisement_service_provider.h
@@ -36,9 +36,6 @@ class CHROMEOS_EXPORT FakeBluetoothLEAdvertisementServiceProvider
private:
friend class FakeBluetoothLEAdvertisingManagerClient;
- // 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.
diff --git a/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.cc b/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.cc
index 8145d1c..5702832 100644
--- a/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.cc
+++ b/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.cc
@@ -54,9 +54,6 @@ void FakeBluetoothLEAdvertisingManagerClient::RegisterAdvertisement(
} else if (!currently_registered_.value().empty()) {
error_callback.Run(bluetooth_advertising_manager::kErrorFailed,
"Maximum advertisements reached");
- } else if (advertisement_object_path != currently_registered_) {
- error_callback.Run(bluetooth_advertising_manager::kErrorAlreadyExists,
- "Already advertising.");
} else {
currently_registered_ = advertisement_object_path;
base::MessageLoop::current()->PostTask(FROM_HERE, callback);
diff --git a/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h b/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h
index ff340e8..5df129c 100644
--- a/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h
+++ b/chromeos/dbus/fake_bluetooth_le_advertising_manager_client.h
@@ -11,8 +11,8 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/observer_list.h"
-#include "bluetooth_le_advertising_manager_client.h"
#include "chromeos/chromeos_export.h"
+#include "chromeos/dbus/bluetooth_le_advertising_manager_client.h"
#include "dbus/object_path.h"
#include "dbus/property.h"
diff --git a/device/BUILD.gn b/device/BUILD.gn
index ba52290..dfd8550 100644
--- a/device/BUILD.gn
+++ b/device/BUILD.gn
@@ -20,6 +20,7 @@ test("device_unittests") {
"bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc",
"bluetooth/bluetooth_adapter_unittest.cc",
"bluetooth/bluetooth_adapter_win_unittest.cc",
+ "bluetooth/bluetooth_advertisement_chromeos_unittest.cc",
"bluetooth/bluetooth_audio_sink_chromeos_unittest.cc",
"bluetooth/bluetooth_chromeos_unittest.cc",
"bluetooth/bluetooth_device_unittest.cc",
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn
index 0d8d46fe..7411027 100644
--- a/device/bluetooth/BUILD.gn
+++ b/device/bluetooth/BUILD.gn
@@ -31,6 +31,10 @@ component("bluetooth") {
"bluetooth_adapter_profile_chromeos.h",
"bluetooth_adapter_win.cc",
"bluetooth_adapter_win.h",
+ "bluetooth_advertisement.cc",
+ "bluetooth_advertisement.h",
+ "bluetooth_advertisement_chromeos.cc",
+ "bluetooth_advertisement_chromeos.h",
"bluetooth_audio_sink.cc",
"bluetooth_audio_sink.h",
"bluetooth_audio_sink_chromeos.cc",
diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp
index ee671f5..c0a30a3 100644
--- a/device/bluetooth/bluetooth.gyp
+++ b/device/bluetooth/bluetooth.gyp
@@ -35,6 +35,10 @@
"bluetooth_adapter_profile_chromeos.h",
'bluetooth_adapter_win.cc',
'bluetooth_adapter_win.h',
+ 'bluetooth_advertisement.cc',
+ 'bluetooth_advertisement.h',
+ 'bluetooth_advertisement_chromeos.cc',
+ 'bluetooth_advertisement_chromeos.h',
'bluetooth_audio_sink.cc',
'bluetooth_audio_sink.h',
'bluetooth_audio_sink_chromeos.cc',
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h
index 87734d2..7fbd099 100644
--- a/device/bluetooth/bluetooth_adapter.h
+++ b/device/bluetooth/bluetooth_adapter.h
@@ -14,12 +14,14 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "device/bluetooth/bluetooth_advertisement.h"
#include "device/bluetooth/bluetooth_audio_sink.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_export.h"
namespace device {
+class BluetoothAdvertisement;
class BluetoothDiscoveryFilter;
class BluetoothDiscoverySession;
class BluetoothGattCharacteristic;
@@ -190,6 +192,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
CreateServiceErrorCallback;
typedef base::Callback<void(scoped_refptr<BluetoothAudioSink>)>
AcquiredCallback;
+ typedef base::Callback<void(scoped_refptr<BluetoothAdvertisement>)>
+ CreateAdvertisementCallback;
+ typedef base::Callback<void(BluetoothAdvertisement::ErrorCode)>
+ CreateAdvertisementErrorCallback;
// Returns a weak pointer to a new adapter. For platforms with asynchronous
// initialization, the returned adapter will run the |init_callback| once
@@ -369,6 +375,13 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
const AcquiredCallback& callback,
const BluetoothAudioSink::ErrorCallback& error_callback) = 0;
+ // Creates and registers an advertisement for broadcast over the LE channel.
+ // The created advertisement will be returned via the success callback.
+ virtual void RegisterAdvertisement(
+ scoped_ptr<BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) = 0;
+
protected:
friend class base::RefCounted<BluetoothAdapter>;
friend class BluetoothDiscoverySession;
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc
index 26a029b..5af69c8 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_chromeos.cc
@@ -21,6 +21,7 @@
#include "chromeos/dbus/bluetooth_input_client.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "device/bluetooth/bluetooth_adapter_profile_chromeos.h"
+#include "device/bluetooth/bluetooth_advertisement_chromeos.h"
#include "device/bluetooth/bluetooth_audio_sink_chromeos.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_device_chromeos.h"
@@ -312,6 +313,15 @@ void BluetoothAdapterChromeOS::RegisterAudioSink(
error_callback);
}
+void BluetoothAdapterChromeOS::RegisterAdvertisement(
+ scoped_ptr<device::BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) {
+ scoped_refptr<BluetoothAdvertisementChromeOS> advertisement(
+ new BluetoothAdvertisementChromeOS(advertisement_data.Pass(), this));
+ advertisement->Register(base::Bind(callback, advertisement), error_callback);
+}
+
void BluetoothAdapterChromeOS::RemovePairingDelegateInternal(
BluetoothDevice::PairingDelegate* pairing_delegate) {
// Before removing a pairing delegate make sure that there aren't any devices
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h
index 7b17f53..1811287 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_chromeos.h
@@ -96,6 +96,11 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS
const device::BluetoothAdapter::AcquiredCallback& callback,
const device::BluetoothAudioSink::ErrorCallback& error_callback) override;
+ void RegisterAdvertisement(
+ scoped_ptr<device::BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) override;
+
// Locates the device object by object path (the devices map and
// BluetoothDevice methods are by address).
BluetoothDeviceChromeOS* GetDeviceWithPath(
diff --git a/device/bluetooth/bluetooth_adapter_mac.h b/device/bluetooth/bluetooth_adapter_mac.h
index 14d5a2b..08c4fb5 100644
--- a/device/bluetooth/bluetooth_adapter_mac.h
+++ b/device/bluetooth/bluetooth_adapter_mac.h
@@ -71,6 +71,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterMac
const BluetoothAudioSink::Options& options,
const AcquiredCallback& callback,
const BluetoothAudioSink::ErrorCallback& error_callback) override;
+ void RegisterAdvertisement(
+ scoped_ptr<BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) override;
// BluetoothDiscoveryManagerMac::Observer overrides
void DeviceFound(IOBluetoothDevice* device) override;
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
index a528bd7..9773bff 100644
--- a/device/bluetooth/bluetooth_adapter_mac.mm
+++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -140,6 +140,14 @@ void BluetoothAdapterMac::RegisterAudioSink(
error_callback.Run(BluetoothAudioSink::ERROR_UNSUPPORTED_PLATFORM);
}
+void BluetoothAdapterMac::RegisterAdvertisement(
+ scoped_ptr<BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) {
+ NOTIMPLEMENTED();
+ error_callback.Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM);
+}
+
void BluetoothAdapterMac::DeviceFound(IOBluetoothDevice* device) {
DeviceAdded(device);
}
diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc
index c028b97..15a09e1 100644
--- a/device/bluetooth/bluetooth_adapter_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_unittest.cc
@@ -71,6 +71,11 @@ class TestBluetoothAdapter : public BluetoothAdapter {
const AcquiredCallback& callback,
const BluetoothAudioSink::ErrorCallback& error_callback) override {}
+ void RegisterAdvertisement(
+ scoped_ptr<BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) override {}
+
void TestErrorCallback() {}
ScopedVector<BluetoothDiscoverySession> discovery_sessions_;
diff --git a/device/bluetooth/bluetooth_adapter_win.cc b/device/bluetooth/bluetooth_adapter_win.cc
index 4f49788..2f32bd0 100644
--- a/device/bluetooth/bluetooth_adapter_win.cc
+++ b/device/bluetooth/bluetooth_adapter_win.cc
@@ -182,6 +182,14 @@ void BluetoothAdapterWin::RegisterAudioSink(
error_callback.Run(BluetoothAudioSink::ERROR_UNSUPPORTED_PLATFORM);
}
+void BluetoothAdapterWin::RegisterAdvertisement(
+ scoped_ptr<BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) {
+ NOTIMPLEMENTED();
+ error_callback.Run(BluetoothAdvertisement::ERROR_UNSUPPORTED_PLATFORM);
+}
+
void BluetoothAdapterWin::RemovePairingDelegateInternal(
BluetoothDevice::PairingDelegate* pairing_delegate) {
}
diff --git a/device/bluetooth/bluetooth_adapter_win.h b/device/bluetooth/bluetooth_adapter_win.h
index 9419373..f018c4f 100644
--- a/device/bluetooth/bluetooth_adapter_win.h
+++ b/device/bluetooth/bluetooth_adapter_win.h
@@ -71,6 +71,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterWin
const BluetoothAudioSink::Options& options,
const AcquiredCallback& callback,
const BluetoothAudioSink::ErrorCallback& error_callback) override;
+ void RegisterAdvertisement(
+ scoped_ptr<BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) override;
// BluetoothTaskManagerWin::Observer override
void AdapterStateChanged(
diff --git a/device/bluetooth/bluetooth_advertisement.cc b/device/bluetooth/bluetooth_advertisement.cc
new file mode 100644
index 0000000..05b0e52
--- /dev/null
+++ b/device/bluetooth/bluetooth_advertisement.cc
@@ -0,0 +1,37 @@
+// 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_advertisement.h"
+
+namespace device {
+
+BluetoothAdvertisement::Data::Data(AdvertisementType type)
+ : type_(type), include_tx_power_(false) {
+}
+
+BluetoothAdvertisement::Data::~Data() {
+}
+
+BluetoothAdvertisement::Data::Data()
+ : type_(ADVERTISEMENT_TYPE_BROADCAST), include_tx_power_(false) {
+}
+
+void BluetoothAdvertisement::AddObserver(
+ BluetoothAdvertisement::Observer* observer) {
+ CHECK(observer);
+ observers_.AddObserver(observer);
+}
+
+void BluetoothAdvertisement::RemoveObserver(
+ BluetoothAdvertisement::Observer* observer) {
+ CHECK(observer);
+ observers_.RemoveObserver(observer);
+}
+
+BluetoothAdvertisement::BluetoothAdvertisement() {
+}
+BluetoothAdvertisement::~BluetoothAdvertisement() {
+}
+
+} // namespace device
diff --git a/device/bluetooth/bluetooth_advertisement.h b/device/bluetooth/bluetooth_advertisement.h
new file mode 100644
index 0000000..69e7121
--- /dev/null
+++ b/device/bluetooth/bluetooth_advertisement.h
@@ -0,0 +1,137 @@
+// 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_ADVERTISEMENT_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+#include "device/bluetooth/bluetooth_export.h"
+
+namespace device {
+
+// BluetoothAdvertisement represents an advertisement which advertises over the
+// LE channel during its lifetime.
+class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
+ : public base::RefCounted<BluetoothAdvertisement> {
+ public:
+ // Possible types of error raised while registering or unregistering
+ // advertisements.
+ enum ErrorCode {
+ ERROR_UNSUPPORTED_PLATFORM, // Bluetooth advertisement not supported on
+ // current platform.
+ ERROR_ADVERTISEMENT_ALREADY_EXISTS, // An advertisement is already
+ // registered.
+ ERROR_ADVERTISEMENT_DOES_NOT_EXIST, // Unregistering an advertisement which
+ // is not registered.
+ ERROR_ADVERTISEMENT_INVALID_LENGTH, // Advertisement is not of a valid
+ // length.
+ INVALID_ADVERTISEMENT_ERROR_CODE
+ };
+
+ // Type of advertisement.
+ enum AdvertisementType {
+ // This advertises with the type set to ADV_NONCONN_IND, which indicates
+ // to receivers that our device is not connectable.
+ ADVERTISEMENT_TYPE_BROADCAST,
+ // This advertises with the type set to ADV_IND or ADV_SCAN_IND, which
+ // indicates to receivers that our device is connectable.
+ ADVERTISEMENT_TYPE_PERIPHERAL
+ };
+
+ 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>>;
+
+ // Structure that holds the data for an advertisement.
+ class DEVICE_BLUETOOTH_EXPORT Data {
+ public:
+ Data(AdvertisementType type);
+ ~Data();
+
+ AdvertisementType type() { return type_; }
+ scoped_ptr<UUIDList> service_uuids() { return service_uuids_.Pass(); }
+ scoped_ptr<ManufacturerData> manufacturer_data() {
+ return manufacturer_data_.Pass();
+ }
+ scoped_ptr<UUIDList> solicit_uuids() { return solicit_uuids_.Pass(); }
+ scoped_ptr<ServiceData> service_data() { return service_data_.Pass(); }
+
+ void set_service_uuids(scoped_ptr<UUIDList> service_uuids) {
+ service_uuids_ = service_uuids.Pass();
+ }
+ void set_manufacturer_data(scoped_ptr<ManufacturerData> manufacturer_data) {
+ manufacturer_data_ = manufacturer_data.Pass();
+ }
+ void set_solicit_uuids(scoped_ptr<UUIDList> solicit_uuids) {
+ solicit_uuids = solicit_uuids_.Pass();
+ }
+ void set_service_data(scoped_ptr<ServiceData> service_data) {
+ service_data = service_data_.Pass();
+ }
+
+ void set_include_tx_power(bool include_tx_power) {
+ include_tx_power_ = include_tx_power;
+ }
+
+ private:
+ Data();
+
+ AdvertisementType type_;
+ scoped_ptr<UUIDList> service_uuids_;
+ scoped_ptr<ManufacturerData> manufacturer_data_;
+ scoped_ptr<UUIDList> solicit_uuids_;
+ scoped_ptr<ServiceData> service_data_;
+ bool include_tx_power_;
+
+ DISALLOW_COPY_AND_ASSIGN(Data);
+ };
+
+ // Interface for observing changes to this advertisement.
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called when this advertisement is released and is no longer advertising.
+ virtual void AdvertisementReleased(
+ BluetoothAdvertisement* advertisement) = 0;
+ };
+
+ // Adds and removes observers for events for this advertisement.
+ void AddObserver(BluetoothAdvertisement::Observer* observer);
+ void RemoveObserver(BluetoothAdvertisement::Observer* observer);
+
+ // Unregisters this advertisement. Called on destruction of this object
+ // automatically but can be called directly to explicitly unregister this
+ // object.
+ using SuccessCallback = base::Closure;
+ using ErrorCallback = base::Callback<void(ErrorCode)>;
+ virtual void Unregister(const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback) = 0;
+
+ protected:
+ friend class base::RefCounted<BluetoothAdvertisement>;
+
+ BluetoothAdvertisement();
+
+ // The destructor will unregister this advertisement.
+ virtual ~BluetoothAdvertisement();
+
+ // List of observers interested in event notifications from us. Objects in
+ // |observers_| are expected to outlive a BluetoothAdvertisement object.
+ ObserverList<BluetoothAdvertisement::Observer> observers_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisement);
+};
+
+} // namespace device
+
+#endif // DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_H_
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos.cc b/device/bluetooth/bluetooth_advertisement_chromeos.cc
new file mode 100644
index 0000000..9b5f1bb
--- /dev/null
+++ b/device/bluetooth/bluetooth_advertisement_chromeos.cc
@@ -0,0 +1,115 @@
+// 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_advertisement_chromeos.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/guid.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.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 "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace {
+
+void UnregisterFailure(device::BluetoothAdvertisement::ErrorCode error) {
+ LOG(ERROR)
+ << "BluetoothAdvertisementChromeOS::Unregister failed with error code = "
+ << error;
+}
+
+void ErrorCallbackConnector(
+ const device::BluetoothAdapter::CreateAdvertisementErrorCallback&
+ error_callback,
+ const std::string& error_name,
+ const std::string& error_message) {
+ LOG(WARNING) << "Error while registering advertisement. error_name = "
+ << error_name << ", error_message = " << error_message;
+ device::BluetoothAdvertisement::ErrorCode error_code;
+ if (error_name == bluetooth_advertising_manager::kErrorFailed ||
+ error_name == bluetooth_advertising_manager::kErrorAlreadyExists) {
+ error_code = device::BluetoothAdvertisement::ErrorCode::
+ ERROR_ADVERTISEMENT_ALREADY_EXISTS;
+ } else if (error_name ==
+ bluetooth_advertising_manager::kErrorInvalidArguments) {
+ error_code = device::BluetoothAdvertisement::ErrorCode::
+ ERROR_ADVERTISEMENT_INVALID_LENGTH;
+ } else if (error_name == bluetooth_advertising_manager::kErrorDoesNotExist) {
+ error_code = device::BluetoothAdvertisement::ErrorCode::
+ ERROR_ADVERTISEMENT_DOES_NOT_EXIST;
+ }
+
+ error_callback.Run(error_code);
+}
+
+} // namespace
+
+namespace chromeos {
+
+BluetoothAdvertisementChromeOS::BluetoothAdvertisementChromeOS(
+ scoped_ptr<device::BluetoothAdvertisement::Data> data,
+ scoped_refptr<BluetoothAdapterChromeOS> adapter)
+ : adapter_(adapter) {
+ dbus::ObjectPath advertisement_object_path = dbus::ObjectPath(
+ "/org/chromium/bluetooth_advertisement/" + base::GenerateGUID());
+ DCHECK(DBusThreadManager::Get());
+ provider_ = BluetoothLEAdvertisementServiceProvider::Create(
+ DBusThreadManager::Get()->GetSystemBus(), advertisement_object_path, this,
+ static_cast<BluetoothLEAdvertisementServiceProvider::AdvertisementType>(
+ data->type()),
+ data->service_uuids().Pass(), data->manufacturer_data().Pass(),
+ data->solicit_uuids().Pass(), data->service_data().Pass());
+}
+
+void BluetoothAdvertisementChromeOS::Register(
+ const base::Closure& success_callback,
+ const device::BluetoothAdapter::CreateAdvertisementErrorCallback&
+ error_callback) {
+ DCHECK(DBusThreadManager::Get());
+ DBusThreadManager::Get()
+ ->GetBluetoothLEAdvertisingManagerClient()
+ ->RegisterAdvertisement(
+ adapter_->object_path(), provider_->object_path(), success_callback,
+ base::Bind(&ErrorCallbackConnector, error_callback));
+}
+
+BluetoothAdvertisementChromeOS::~BluetoothAdvertisementChromeOS() {
+ Unregister(base::Bind(&base::DoNothing), base::Bind(&UnregisterFailure));
+}
+
+void BluetoothAdvertisementChromeOS::Unregister(
+ const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback) {
+ // If we don't have a provider, that means we have already been unregistered,
+ // return an error.
+ if (!provider_) {
+ error_callback.Run(device::BluetoothAdvertisement::ErrorCode::
+ ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
+ return;
+ }
+
+ DCHECK(DBusThreadManager::Get());
+ DBusThreadManager::Get()
+ ->GetBluetoothLEAdvertisingManagerClient()
+ ->UnregisterAdvertisement(
+ adapter_->object_path(), provider_->object_path(), success_callback,
+ base::Bind(&ErrorCallbackConnector, error_callback));
+ provider_.reset();
+}
+
+void BluetoothAdvertisementChromeOS::Released() {
+ LOG(WARNING) << "Advertisement released.";
+ provider_.reset();
+ FOR_EACH_OBSERVER(BluetoothAdvertisement::Observer, observers_,
+ AdvertisementReleased(this));
+}
+
+} // namespace chromeos
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos.h b/device/bluetooth/bluetooth_advertisement_chromeos.h
new file mode 100644
index 0000000..aeb59b7
--- /dev/null
+++ b/device/bluetooth/bluetooth_advertisement_chromeos.h
@@ -0,0 +1,59 @@
+// 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_ADVERTISEMENT_CHROMEOS_H_
+#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"
+
+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:
+ BluetoothAdvertisementChromeOS(
+ scoped_ptr<device::BluetoothAdvertisement::Data> data,
+ scoped_refptr<BluetoothAdapterChromeOS> adapter);
+
+ // BluetoothAdvertisement overrides:
+ void Unregister(const SuccessCallback& success_callback,
+ const ErrorCallback& error_callback) override;
+
+ // BluetoothLEAdvertisementServiceProvider::Delegate overrides:
+ void Released() override;
+
+ void Register(
+ const base::Closure& success_callback,
+ const device::BluetoothAdapter::CreateAdvertisementErrorCallback&
+ error_callback);
+
+ // Used from tests to be able to trigger events on the fake advertisement
+ // provider.
+ BluetoothLEAdvertisementServiceProvider* provider() {
+ return provider_.get();
+ }
+
+ private:
+ ~BluetoothAdvertisementChromeOS() override;
+
+ // Adapter this advertisement is advertising on.
+ scoped_refptr<BluetoothAdapterChromeOS> adapter_;
+ scoped_ptr<BluetoothLEAdvertisementServiceProvider> provider_;
+
+ DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisementChromeOS);
+};
+
+} // namespace chromeos
+
+#endif // DEVICE_BLUETOOTH_BLUETOOTH_ADVERTISEMENT_CHROMEOS_H_
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc b/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc
new file mode 100644
index 0000000..02fe1e4
--- /dev/null
+++ b/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc
@@ -0,0 +1,242 @@
+// 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 <vector>
+
+#include "base/bind.h"
+#include "base/logging.h"
+#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 "testing/gtest/include/gtest/gtest.h"
+
+using device::BluetoothAdapter;
+using device::BluetoothAdapterFactory;
+using device::BluetoothAdvertisement;
+
+namespace chromeos {
+
+class TestAdvertisementObserver : public BluetoothAdvertisement::Observer {
+ public:
+ explicit TestAdvertisementObserver(
+ scoped_refptr<BluetoothAdvertisement> advertisement)
+ : released_(false), advertisement_(advertisement) {
+ advertisement_->AddObserver(this);
+ }
+
+ ~TestAdvertisementObserver() override {
+ advertisement_->RemoveObserver(this);
+ }
+
+ // BluetoothAdvertisement::Observer overrides:
+ void AdvertisementReleased(BluetoothAdvertisement* advertisement) override {
+ released_ = true;
+ }
+
+ bool released() { return released_; }
+
+ private:
+ bool released_;
+ scoped_refptr<BluetoothAdvertisement> advertisement_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestAdvertisementObserver);
+};
+
+class BluetoothAdvertisementChromeOSTest : public testing::Test {
+ public:
+ void SetUp() override {
+ DBusThreadManager::Initialize();
+
+ callback_count_ = 0;
+ error_callback_count_ = 0;
+
+ last_callback_count_ = 0;
+ last_error_callback_count_ = 0;
+
+ last_error_code_ = BluetoothAdvertisement::INVALID_ADVERTISEMENT_ERROR_CODE;
+
+ GetAdapter();
+ }
+
+ void TearDown() override {
+ observer_.reset();
+ // The adapter should outlive the advertisement.
+ advertisement_ = nullptr;
+ adapter_ = nullptr;
+ DBusThreadManager::Shutdown();
+ }
+
+ // Gets the existing Bluetooth adapter.
+ void GetAdapter() {
+ BluetoothAdapterFactory::GetAdapter(
+ base::Bind(&BluetoothAdvertisementChromeOSTest::GetAdapterCallback,
+ base::Unretained(this)));
+ }
+
+ // Called whenever BluetoothAdapter is retrieved successfully.
+ void GetAdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
+ adapter_ = adapter;
+ ASSERT_NE(adapter_.get(), nullptr);
+ ASSERT_TRUE(adapter_->IsInitialized());
+ }
+
+ scoped_ptr<BluetoothAdvertisement::Data> CreateAdvertisementData() {
+ scoped_ptr<BluetoothAdvertisement::Data> data =
+ make_scoped_ptr(new BluetoothAdvertisement::Data(
+ BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST));
+ data->set_service_uuids(
+ make_scoped_ptr(new BluetoothAdvertisement::UUIDList()).Pass());
+ data->set_manufacturer_data(
+ make_scoped_ptr(new BluetoothAdvertisement::ManufacturerData()).Pass());
+ data->set_solicit_uuids(
+ make_scoped_ptr(new BluetoothAdvertisement::UUIDList()).Pass());
+ data->set_service_data(
+ make_scoped_ptr(new BluetoothAdvertisement::ServiceData()).Pass());
+ return data.Pass();
+ }
+
+ // Creates and registers an advertisement with the adapter.
+ scoped_refptr<BluetoothAdvertisement> CreateAdvertisement() {
+ // Clear the last advertisement we created.
+ advertisement_ = nullptr;
+
+ adapter_->RegisterAdvertisement(
+ CreateAdvertisementData().Pass(),
+ base::Bind(&BluetoothAdvertisementChromeOSTest::RegisterCallback,
+ base::Unretained(this)),
+ base::Bind(
+ &BluetoothAdvertisementChromeOSTest::AdvertisementErrorCallback,
+ base::Unretained(this)));
+
+ message_loop_.RunUntilIdle();
+ return advertisement_;
+ }
+
+ void UnregisterAdvertisement(
+ scoped_refptr<BluetoothAdvertisement> advertisement) {
+ advertisement->Unregister(
+ base::Bind(&BluetoothAdvertisementChromeOSTest::Callback,
+ base::Unretained(this)),
+ base::Bind(
+ &BluetoothAdvertisementChromeOSTest::AdvertisementErrorCallback,
+ base::Unretained(this)));
+
+ message_loop_.RunUntilIdle();
+ }
+
+ void TriggerReleased(scoped_refptr<BluetoothAdvertisement> advertisement) {
+ BluetoothAdvertisementChromeOS* adv =
+ static_cast<BluetoothAdvertisementChromeOS*>(advertisement.get());
+ FakeBluetoothLEAdvertisementServiceProvider* provider =
+ static_cast<FakeBluetoothLEAdvertisementServiceProvider*>(
+ adv->provider());
+ provider->Release();
+ }
+
+ // Called whenever RegisterAdvertisement is completed successfully.
+ void RegisterCallback(scoped_refptr<BluetoothAdvertisement> advertisement) {
+ ++callback_count_;
+ advertisement_ = advertisement;
+
+ ASSERT_NE(advertisement_.get(), nullptr);
+ }
+
+ void AdvertisementErrorCallback(
+ BluetoothAdvertisement::ErrorCode error_code) {
+ ++error_callback_count_;
+ last_error_code_ = error_code;
+ }
+
+ // Generic callbacks.
+ void Callback() { ++callback_count_; }
+
+ void ErrorCallback() { ++error_callback_count_; }
+
+ void ExpectSuccess() {
+ EXPECT_EQ(last_error_callback_count_, error_callback_count_);
+ EXPECT_EQ(last_callback_count_ + 1, callback_count_);
+ last_callback_count_ = callback_count_;
+ last_error_callback_count_ = error_callback_count_;
+ }
+
+ void ExpectError(BluetoothAdvertisement::ErrorCode error_code) {
+ EXPECT_EQ(last_callback_count_, callback_count_);
+ EXPECT_EQ(last_error_callback_count_ + 1, error_callback_count_);
+ last_callback_count_ = callback_count_;
+ last_error_callback_count_ = error_callback_count_;
+ EXPECT_EQ(error_code, last_error_code_);
+ }
+
+ protected:
+ int callback_count_;
+ int error_callback_count_;
+
+ int last_callback_count_;
+ int last_error_callback_count_;
+
+ BluetoothAdvertisement::ErrorCode last_error_code_;
+
+ base::MessageLoopForIO message_loop_;
+
+ scoped_ptr<TestAdvertisementObserver> observer_;
+ scoped_refptr<BluetoothAdapter> adapter_;
+ scoped_refptr<BluetoothAdvertisement> advertisement_;
+};
+
+TEST_F(BluetoothAdvertisementChromeOSTest, RegisterSucceeded) {
+ scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement();
+ ExpectSuccess();
+ EXPECT_NE(nullptr, advertisement);
+
+ UnregisterAdvertisement(advertisement);
+ ExpectSuccess();
+}
+
+TEST_F(BluetoothAdvertisementChromeOSTest, DoubleRegisterFailed) {
+ scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement();
+ ExpectSuccess();
+ EXPECT_NE(nullptr, advertisement);
+
+ // Creating a second advertisement should give us an error.
+ scoped_refptr<BluetoothAdvertisement> advertisement2 = CreateAdvertisement();
+ ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_ALREADY_EXISTS);
+ EXPECT_EQ(nullptr, advertisement2);
+}
+
+TEST_F(BluetoothAdvertisementChromeOSTest, DoubleUnregisterFailed) {
+ scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement();
+ ExpectSuccess();
+ EXPECT_NE(nullptr, advertisement);
+
+ UnregisterAdvertisement(advertisement);
+ ExpectSuccess();
+
+ // Unregistering an already unregistered advertisement should give us an
+ // error.
+ UnregisterAdvertisement(advertisement);
+ ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
+}
+
+TEST_F(BluetoothAdvertisementChromeOSTest, UnregisterAfterReleasedFailed) {
+ scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement();
+ ExpectSuccess();
+ EXPECT_NE(nullptr, advertisement);
+
+ observer_.reset(new TestAdvertisementObserver(advertisement));
+ TriggerReleased(advertisement);
+ EXPECT_TRUE(observer_->released());
+
+ // Unregistering an advertisement that has been released should give us an
+ // error.
+ UnregisterAdvertisement(advertisement);
+ ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
+}
+
+} // namespace chromeos
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.cc b/device/bluetooth/test/mock_bluetooth_adapter.cc
index 615239b..4b47579 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.cc
+++ b/device/bluetooth/test/mock_bluetooth_adapter.cc
@@ -46,4 +46,10 @@ void MockBluetoothAdapter::StartDiscoverySessionWithFilter(
error_callback);
}
+void MockBluetoothAdapter::RegisterAdvertisement(
+ scoped_ptr<BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) {
+}
+
} // namespace device
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.h b/device/bluetooth/test/mock_bluetooth_adapter.h
index 37f6450..e1523f9 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.h
+++ b/device/bluetooth/test/mock_bluetooth_adapter.h
@@ -109,6 +109,10 @@ class MockBluetoothAdapter : public BluetoothAdapter {
void SetDiscoveryFilter(scoped_ptr<BluetoothDiscoveryFilter> discovery_filter,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
+ void RegisterAdvertisement(
+ scoped_ptr<BluetoothAdvertisement::Data> advertisement_data,
+ const CreateAdvertisementCallback& callback,
+ const CreateAdvertisementErrorCallback& error_callback) override;
virtual ~MockBluetoothAdapter();
MOCK_METHOD1(RemovePairingDelegateInternal,
diff --git a/device/device_tests.gyp b/device/device_tests.gyp
index 8b1545a0..3c0c23a 100644
--- a/device/device_tests.gyp
+++ b/device/device_tests.gyp
@@ -36,6 +36,7 @@
'bluetooth/bluetooth_adapter_profile_chromeos_unittest.cc',
'bluetooth/bluetooth_adapter_unittest.cc',
'bluetooth/bluetooth_adapter_win_unittest.cc',
+ 'bluetooth/bluetooth_advertisement_chromeos_unittest.cc',
'bluetooth/bluetooth_audio_sink_chromeos_unittest.cc',
'bluetooth/bluetooth_chromeos_unittest.cc',
'bluetooth/bluetooth_device_unittest.cc',