#include <string>
#include "base/basictypes.h"
+#include "base/containers/scoped_ptr_hash_map.h"
#include "base/logging.h"
#include "base/memory/scoped_vector.h"
#include "base/sequenced_task_runner.h"
namespace device {
BluetoothDeviceWin::BluetoothDeviceWin(
- const BluetoothTaskManagerWin::DeviceState& state,
- scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
- scoped_refptr<BluetoothSocketThread> socket_thread,
+ const BluetoothTaskManagerWin::DeviceState& device_state,
+ const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner,
+ const scoped_refptr<BluetoothSocketThread>& socket_thread,
net::NetLog* net_log,
const net::NetLog::Source& net_log_source)
: BluetoothDevice(),
socket_thread_(socket_thread),
net_log_(net_log),
net_log_source_(net_log_source) {
- name_ = state.name;
- address_ = CanonicalizeAddress(state.address);
- bluetooth_class_ = state.bluetooth_class;
- visible_ = state.visible;
- connected_ = state.connected;
- paired_ = state.authenticated;
+ Update(device_state);
+}
+
+BluetoothDeviceWin::~BluetoothDeviceWin() {
+}
+
+void BluetoothDeviceWin::Update(
+ const BluetoothTaskManagerWin::DeviceState& device_state) {
+ address_ = device_state.address;
+ // Note: Callers are responsible for providing a canonicalized address.
+ DCHECK_EQ(address_, BluetoothDevice::CanonicalizeAddress(address_));
+ name_ = device_state.name;
+ bluetooth_class_ = device_state.bluetooth_class;
+ visible_ = device_state.visible;
+ connected_ = device_state.connected;
+ paired_ = device_state.authenticated;
+ UpdateServices(device_state);
+}
+
+void BluetoothDeviceWin::UpdateServices(
+ const BluetoothTaskManagerWin::DeviceState& device_state) {
+ uuids_.clear();
+ service_record_list_.clear();
for (ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>::const_iterator
- iter = state.service_record_states.begin();
- iter != state.service_record_states.end();
+ iter = device_state.service_record_states.begin();
+ iter != device_state.service_record_states.end();
++iter) {
- uint8 sdp_bytes_buffer[kSdpBytesBufferSize];
- std::copy((*iter)->sdp_bytes.begin(),
- (*iter)->sdp_bytes.end(),
- sdp_bytes_buffer);
- BluetoothServiceRecordWin* service_record = new BluetoothServiceRecordWin(
- (*iter)->name,
- (*iter)->address,
- (*iter)->sdp_bytes.size(),
- sdp_bytes_buffer);
+ BluetoothServiceRecordWin* service_record =
+ new BluetoothServiceRecordWin(device_state.address,
+ (*iter)->name,
+ (*iter)->sdp_bytes,
+ (*iter)->gatt_uuid);
service_record_list_.push_back(service_record);
uuids_.push_back(service_record->uuid());
}
}
-BluetoothDeviceWin::~BluetoothDeviceWin() {
-}
+bool BluetoothDeviceWin::IsEqual(
+ const BluetoothTaskManagerWin::DeviceState& device_state) {
+ if (address_ != device_state.address || name_ != device_state.name ||
+ bluetooth_class_ != device_state.bluetooth_class ||
+ visible_ != device_state.visible ||
+ connected_ != device_state.connected ||
+ paired_ != device_state.authenticated) {
+ return false;
+ }
-void BluetoothDeviceWin::SetVisible(bool visible) {
- visible_ = visible;
-}
+ // Checks service collection
+ typedef std::set<BluetoothUUID> UUIDSet;
+ typedef base::ScopedPtrHashMap<std::string, BluetoothServiceRecordWin>
+ ServiceRecordMap;
-void BluetoothDeviceWin::AddObserver(
- device::BluetoothDevice::Observer* observer) {
- DCHECK(observer);
- observers_.AddObserver(observer);
-}
+ UUIDSet known_services;
+ for (UUIDList::const_iterator iter = uuids_.begin(); iter != uuids_.end();
+ ++iter) {
+ known_services.insert((*iter));
+ }
+
+ UUIDSet new_services;
+ ServiceRecordMap new_service_records;
+ for (ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>::const_iterator
+ iter = device_state.service_record_states.begin();
+ iter != device_state.service_record_states.end();
+ ++iter) {
+ BluetoothServiceRecordWin* service_record = new BluetoothServiceRecordWin(
+ address_, (*iter)->name, (*iter)->sdp_bytes, (*iter)->gatt_uuid);
+ new_services.insert(service_record->uuid());
+ new_service_records.set(
+ service_record->uuid().canonical_value(),
+ scoped_ptr<BluetoothServiceRecordWin>(service_record));
+ }
+
+ UUIDSet removed_services =
+ base::STLSetDifference<UUIDSet>(known_services, new_services);
+ if (!removed_services.empty()) {
+ return false;
+ }
+ UUIDSet added_devices =
+ base::STLSetDifference<UUIDSet>(new_services, known_services);
+ if (!added_devices.empty()) {
+ return false;
+ }
-void BluetoothDeviceWin::RemoveObserver(
- device::BluetoothDevice::Observer* observer) {
- DCHECK(observer);
- observers_.RemoveObserver(observer);
+ for (ServiceRecordList::const_iterator iter = service_record_list_.begin();
+ iter != service_record_list_.end();
+ ++iter) {
+ BluetoothServiceRecordWin* service_record = (*iter);
+ BluetoothServiceRecordWin* new_service_record =
+ new_service_records.get((*iter)->uuid().canonical_value());
+ if (!service_record->IsEqual(*new_service_record))
+ return false;
+ }
+ return true;
}
+void BluetoothDeviceWin::SetVisible(bool visible) {
+ visible_ = visible;
+}
uint32 BluetoothDeviceWin::GetBluetoothClass() const {
return bluetooth_class_;
const ConnectToServiceErrorCallback& error_callback) {
scoped_refptr<BluetoothSocketWin> socket(
BluetoothSocketWin::CreateBluetoothSocket(
- ui_task_runner_, socket_thread_, NULL, net::NetLog::Source()));
+ ui_task_runner_, socket_thread_));
socket->Connect(this, uuid, base::Bind(callback, socket), error_callback);
}