Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / device / bluetooth / bluetooth_device_win.cc
index 47376bc..67c2aec 100644 (file)
@@ -7,6 +7,7 @@
 #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"
@@ -26,9 +27,9 @@ const int kSdpBytesBufferSize = 1024;
 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(),
@@ -36,50 +37,105 @@ BluetoothDeviceWin::BluetoothDeviceWin(
       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_;
@@ -203,7 +259,7 @@ void BluetoothDeviceWin::ConnectToService(
     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);
 }