Bluetooth: clean up Bluetooth classes

The abstract BluetoothDevice class has a few problems inherited from
its origin as a ChromeOS-specific class split between implementation
and platform-specific components.

Clean those problems up, specifically:
 - replace bluetooth_class_, name_ and address_ non-abstract members
   with getter functions that the platform should implement.
 - also make IsConnected(), IsConnectable() and IsConnecting()
   abstract functions rather than providing an implementation
 - remove IsVisible() which was a CrOS-specific hack
 - remove IsBonded(), use IsPaired() instead
 - remove service_uuids_ non-abstract member; make GetServices return
   a copy of the list to allow implementations to fetch it on demand

BluetoothDevice retains implementations for GetName(), GetDisplayType()
and ProvidesServiceWithUUID() since those can be implemented entirely
using platform-provided information functions and would be identical
in each platform.

Also rename BluetoothAdapter::address() and BluetoothAdapter::name() to
GetAddress() and GetName() to match since they are also pure virtual.

BUG=none
TEST=device_unittests, browser_tests, unit_tests


Review URL: https://chromiumcodereview.appspot.com/13416005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192474 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h
index 7ea7095c..ed615860 100644
--- a/device/bluetooth/bluetooth_adapter.h
+++ b/device/bluetooth/bluetooth_adapter.h
@@ -86,10 +86,10 @@
 
   // The address of this adapter.  The address format is "XX:XX:XX:XX:XX:XX",
   // where each XX is a hexadecimal number.
-  virtual std::string address() const = 0;
+  virtual std::string GetAddress() const = 0;
 
   // The name of the adapter.
-  virtual std::string name() const = 0;
+  virtual std::string GetName() const = 0;
 
   // Indicates whether the adapter is initialized and ready to use.
   virtual bool IsInitialized() const = 0;
@@ -121,7 +121,7 @@
   //
   // Since discovery may already be in progress when this method is called,
   // callers should retrieve the current set of discovered devices by calling
-  // GetDevices() and checking for those with IsVisible() as true.
+  // GetDevices() and checking for those with IsPaired() as false.
   virtual void StartDiscovering(const base::Closure& callback,
                                 const ErrorCallback& error_callback) = 0;
 
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc
index 6ba6343..a0b2681 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_chromeos.cc
@@ -65,11 +65,11 @@
   observers_.RemoveObserver(observer);
 }
 
-std::string BluetoothAdapterChromeOS::address() const {
+std::string BluetoothAdapterChromeOS::GetAddress() const {
   return address_;
 }
 
-std::string BluetoothAdapterChromeOS::name() const {
+std::string BluetoothAdapterChromeOS::GetName() const {
   return name_;
 }
 
@@ -359,8 +359,7 @@
     devices_[address] = device;
   }
 
-  const bool was_paired = device->IsPaired();
-  if (!was_paired) {
+  if (!device->HasObjectPath()) {
     VLOG(1) << "Assigned object path " << device_path.value() << " to device "
             << address;
     device->SetObjectPath(device_path);
@@ -417,16 +416,16 @@
     // DeviceRemoved can also be called to indicate a device that is visible
     // during discovery has disconnected, but it is still visible to the
     // adapter, so don't remove in that case and only clear the object path.
-    if (!device->IsVisible()) {
+    if (!device->WasDiscovered()) {
       FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                         DeviceRemoved(this, device));
 
-      VLOG(1) << "Removed device " << device->address();
+      VLOG(1) << "Removed device " << device->GetAddress();
 
       delete device;
       devices_.erase(temp);
     } else {
-      VLOG(1) << "Removed object path from device " << device->address();
+      VLOG(1) << "Removed object path from device " << device->GetAddress();
       device->RemoveObjectPath();
 
       FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
@@ -445,17 +444,20 @@
 void BluetoothAdapterChromeOS::ClearDiscoveredDevices() {
   DevicesMap::iterator iter = devices_.begin();
   while (iter != devices_.end()) {
-    BluetoothDevice* device = iter->second;
+    BluetoothDeviceChromeOS* device =
+        static_cast<BluetoothDeviceChromeOS*>(iter->second);
     DevicesMap::iterator temp = iter;
     ++iter;
 
-    if (!device->IsPaired()) {
+    if (!device->HasObjectPath()) {
       FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                         DeviceRemoved(this, device));
 
       delete device;
       devices_.erase(temp);
-    }
+
+    } else
+      device->SetDiscovered(false);
   }
 }
 
@@ -480,7 +482,7 @@
   }
 
   VLOG(1) << "Device " << address << " is visible to the adapter";
-  device->SetVisible(true);
+  device->SetDiscovered(true);
   device->Update(&properties, false);
 
   if (update_device) {
@@ -508,19 +510,19 @@
   // DeviceDisappeared can also be called to indicate that a device we've
   // paired with is no longer visible to the adapter, so don't remove
   // in that case and only clear the visible flag.
-  if (!device->IsPaired()) {
+  if (!device->HasObjectPath()) {
     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                       DeviceRemoved(this, device));
 
-    VLOG(1) << "Discovered device " << device->address()
+    VLOG(1) << "Discovered device " << device->GetAddress()
              << " is no longer visible to the adapter";
 
     delete device;
     devices_.erase(iter);
   } else {
-    VLOG(1) << "Paired device " << device->address()
+    VLOG(1) << "Paired device " << device->GetAddress()
             << " is no longer visible to the adapter";
-    device->SetVisible(false);
+    device->SetDiscovered(false);
 
     FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_,
                       DeviceChanged(this, device));
diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h
index 0c4f960..c210a30 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_chromeos.h
@@ -42,8 +42,8 @@
       device::BluetoothAdapter::Observer* observer) OVERRIDE;
   virtual void RemoveObserver(
       device::BluetoothAdapter::Observer* observer) OVERRIDE;
-  virtual std::string address() const OVERRIDE;
-  virtual std::string name() const OVERRIDE;
+  virtual std::string GetAddress() const OVERRIDE;
+  virtual std::string GetName() const OVERRIDE;
   virtual bool IsInitialized() const OVERRIDE;
   virtual bool IsPresent() const OVERRIDE;
   virtual bool IsPowered() const OVERRIDE;
diff --git a/device/bluetooth/bluetooth_adapter_chromeos_unittest.cc b/device/bluetooth/bluetooth_adapter_chromeos_unittest.cc
index 1137063..59cb632 100644
--- a/device/bluetooth/bluetooth_adapter_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_chromeos_unittest.cc
@@ -130,7 +130,7 @@
 
   // Adapter should be present with the given address.
   EXPECT_TRUE(adapter_->IsPresent());
-  EXPECT_EQ(adapter_address, adapter_->address());
+  EXPECT_EQ(adapter_address, adapter_->GetAddress());
 }
 
 TEST_F(BluetoothAdapterChromeOSTest, DefaultAdapterWithoutAddress) {
@@ -185,7 +185,7 @@
 
   // Adapter should be present with the given address.
   EXPECT_TRUE(adapter_->IsPresent());
-  EXPECT_EQ(adapter_address, adapter_->address());
+  EXPECT_EQ(adapter_address, adapter_->GetAddress());
 }
 
 TEST_F(BluetoothAdapterChromeOSTest, DefaultAdapterBecomesPresentWithAddress) {
@@ -230,7 +230,7 @@
 
   // Adapter should be present with the new address.
   EXPECT_TRUE(adapter_->IsPresent());
-  EXPECT_EQ(adapter_address, adapter_->address());
+  EXPECT_EQ(adapter_address, adapter_->GetAddress());
 }
 
 TEST_F(BluetoothAdapterChromeOSTest, DefaultAdapterReplacedWithAddress) {
@@ -289,7 +289,7 @@
 
   // Adapter should be present with the new address.
   EXPECT_TRUE(adapter_->IsPresent());
-  EXPECT_EQ(new_adapter_address, adapter_->address());
+  EXPECT_EQ(new_adapter_address, adapter_->GetAddress());
 }
 
 TEST_F(BluetoothAdapterChromeOSTest,
@@ -348,7 +348,7 @@
 
   // Adapter should be present with the new address.
   EXPECT_TRUE(adapter_->IsPresent());
-  EXPECT_EQ(adapter_address, adapter_->address());
+  EXPECT_EQ(adapter_address, adapter_->GetAddress());
 }
 
 TEST_F(BluetoothAdapterChromeOSTest, DefaultAdapterReplacedWithoutAddress) {
@@ -417,7 +417,7 @@
 
   // Adapter should be present with the new address.
   EXPECT_TRUE(adapter_->IsPresent());
-  EXPECT_EQ(new_adapter_address, adapter_->address());
+  EXPECT_EQ(new_adapter_address, adapter_->GetAddress());
 }
 
 TEST_F(BluetoothAdapterChromeOSTest, DefaultAdapterRemoved) {
diff --git a/device/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc b/device/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc
index a4e01de..723941a 100644
--- a/device/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc
+++ b/device/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc
@@ -155,7 +155,7 @@
   static_cast<BluetoothAdapterClient::Observer*>(adapter_chromeos)
       ->DeviceCreated(adapter_path_, device_path);
 
-  // Finally remove the adapter again;
+  // Finally remove the device again;
   // BluetoothAdapterClient::Observer::DeviceRemoved should be not called,
   // instead BluetoothAdapterClient::Observer::DeviceChanged will be called.
   EXPECT_CALL(adapter_observer_, DeviceRemoved(adapter_.get(), device))
@@ -167,7 +167,6 @@
       ->DeviceRemoved(adapter_path_, device_path);
 
   // Verify that the device is still visible, just no longer paired.
-  EXPECT_TRUE(device->IsVisible());
   EXPECT_FALSE(device->IsPaired());
 }
 
diff --git a/device/bluetooth/bluetooth_adapter_experimental_chromeos.cc b/device/bluetooth/bluetooth_adapter_experimental_chromeos.cc
index ea0883a..8cdfb96 100644
--- a/device/bluetooth/bluetooth_adapter_experimental_chromeos.cc
+++ b/device/bluetooth/bluetooth_adapter_experimental_chromeos.cc
@@ -26,11 +26,11 @@
     BluetoothAdapter::Observer* observer) {
 }
 
-std::string BluetoothAdapterExperimentalChromeOS::address() const {
+std::string BluetoothAdapterExperimentalChromeOS::GetAddress() const {
   return std::string();
 }
 
-std::string BluetoothAdapterExperimentalChromeOS::name() const {
+std::string BluetoothAdapterExperimentalChromeOS::GetName() const {
   return std::string();
 }
 
diff --git a/device/bluetooth/bluetooth_adapter_experimental_chromeos.h b/device/bluetooth/bluetooth_adapter_experimental_chromeos.h
index 10b727d..1379352 100644
--- a/device/bluetooth/bluetooth_adapter_experimental_chromeos.h
+++ b/device/bluetooth/bluetooth_adapter_experimental_chromeos.h
@@ -30,8 +30,8 @@
       device::BluetoothAdapter::Observer* observer) OVERRIDE;
   virtual void RemoveObserver(
       device::BluetoothAdapter::Observer* observer) OVERRIDE;
-  virtual std::string address() const OVERRIDE;
-  virtual std::string name() const OVERRIDE;
+  virtual std::string GetAddress() const OVERRIDE;
+  virtual std::string GetName() const OVERRIDE;
   virtual bool IsInitialized() const OVERRIDE;
   virtual bool IsPresent() const OVERRIDE;
   virtual bool IsPowered() const OVERRIDE;
diff --git a/device/bluetooth/bluetooth_adapter_mac.h b/device/bluetooth/bluetooth_adapter_mac.h
index 3f107d2..dc4b06b 100644
--- a/device/bluetooth/bluetooth_adapter_mac.h
+++ b/device/bluetooth/bluetooth_adapter_mac.h
@@ -43,8 +43,8 @@
   // BluetoothAdapter override
   virtual void AddObserver(BluetoothAdapter::Observer* observer) OVERRIDE;
   virtual void RemoveObserver(BluetoothAdapter::Observer* observer) OVERRIDE;
-  virtual std::string address() const OVERRIDE;
-  virtual std::string name() const OVERRIDE;
+  virtual std::string GetAddress() const OVERRIDE;
+  virtual std::string GetName() const OVERRIDE;
   virtual bool IsInitialized() const OVERRIDE;
   virtual bool IsPresent() const OVERRIDE;
   virtual bool IsPowered() const OVERRIDE;
diff --git a/device/bluetooth/bluetooth_adapter_mac.mm b/device/bluetooth/bluetooth_adapter_mac.mm
index 0d2233c..9ca4b3ab 100644
--- a/device/bluetooth/bluetooth_adapter_mac.mm
+++ b/device/bluetooth/bluetooth_adapter_mac.mm
@@ -117,11 +117,11 @@
   observers_.RemoveObserver(observer);
 }
 
-std::string BluetoothAdapterMac::address() const {
+std::string BluetoothAdapterMac::GetAddress() const {
   return address_;
 }
 
-std::string BluetoothAdapterMac::name() const {
+std::string BluetoothAdapterMac::GetName() const {
   return name_;
 }
 
diff --git a/device/bluetooth/bluetooth_adapter_win.cc b/device/bluetooth/bluetooth_adapter_win.cc
index 28d3dcc..ddbff839 100644
--- a/device/bluetooth/bluetooth_adapter_win.cc
+++ b/device/bluetooth/bluetooth_adapter_win.cc
@@ -45,11 +45,11 @@
   observers_.RemoveObserver(observer);
 }
 
-std::string BluetoothAdapterWin::address() const {
+std::string BluetoothAdapterWin::GetAddress() const {
   return address_;
 }
 
-std::string BluetoothAdapterWin::name() const {
+std::string BluetoothAdapterWin::GetName() const {
   return name_;
 }
 
diff --git a/device/bluetooth/bluetooth_adapter_win.h b/device/bluetooth/bluetooth_adapter_win.h
index d255448..0265624 100644
--- a/device/bluetooth/bluetooth_adapter_win.h
+++ b/device/bluetooth/bluetooth_adapter_win.h
@@ -36,8 +36,8 @@
   // BluetoothAdapter override
   virtual void AddObserver(BluetoothAdapter::Observer* observer) OVERRIDE;
   virtual void RemoveObserver(BluetoothAdapter::Observer* observer) OVERRIDE;
-  virtual std::string address() const OVERRIDE;
-  virtual std::string name() const OVERRIDE;
+  virtual std::string GetAddress() const OVERRIDE;
+  virtual std::string GetName() const OVERRIDE;
   virtual bool IsInitialized() const OVERRIDE;
   virtual bool IsPresent() const OVERRIDE;
   virtual bool IsPowered() const OVERRIDE;
diff --git a/device/bluetooth/bluetooth_device.cc b/device/bluetooth/bluetooth_device.cc
index a2249c5..f7bea9ed 100644
--- a/device/bluetooth/bluetooth_device.cc
+++ b/device/bluetooth/bluetooth_device.cc
@@ -18,84 +18,77 @@
   return !bluetooth_utils::CanonicalUuid(uuid).empty();
 }
 
-BluetoothDevice::BluetoothDevice()
-    : bluetooth_class_(0),
-      visible_(false),
-      bonded_(false),
-      connected_(false),
-      connectable_(true),
-      connecting_(false) {
+BluetoothDevice::BluetoothDevice() {
 }
 
 BluetoothDevice::~BluetoothDevice() {
 }
 
-const std::string& BluetoothDevice::address() const {
-  return address_;
-}
-
 string16 BluetoothDevice::GetName() const {
-  if (!name_.empty()) {
-    return UTF8ToUTF16(name_);
+  std::string name = GetDeviceName();
+  if (!name.empty()) {
+    return UTF8ToUTF16(name);
   } else {
     return GetAddressWithLocalizedDeviceTypeName();
   }
 }
 
 string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const {
-  string16 address = UTF8ToUTF16(address_);
+  string16 address_utf16 = UTF8ToUTF16(GetAddress());
   BluetoothDevice::DeviceType device_type = GetDeviceType();
   switch (device_type) {
     case DEVICE_COMPUTER:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER,
-                                        address);
+                                        address_utf16);
     case DEVICE_PHONE:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE,
-                                        address);
+                                        address_utf16);
     case DEVICE_MODEM:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM,
-                                        address);
+                                        address_utf16);
     case DEVICE_AUDIO:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO,
-                                        address);
+                                        address_utf16);
     case DEVICE_CAR_AUDIO:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO,
-                                        address);
+                                        address_utf16);
     case DEVICE_VIDEO:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO,
-                                        address);
+                                        address_utf16);
     case DEVICE_JOYSTICK:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK,
-                                        address);
+                                        address_utf16);
     case DEVICE_GAMEPAD:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD,
-                                        address);
+                                        address_utf16);
     case DEVICE_KEYBOARD:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD,
-                                        address);
+                                        address_utf16);
     case DEVICE_MOUSE:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE,
-                                        address);
+                                        address_utf16);
     case DEVICE_TABLET:
       return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET,
-                                        address);
+                                        address_utf16);
     case DEVICE_KEYBOARD_MOUSE_COMBO:
       return l10n_util::GetStringFUTF16(
-          IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address);
+          IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address_utf16);
     default:
-      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN, address);
+      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN,
+                                        address_utf16);
   }
 }
 
 BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const {
   // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
-  switch ((bluetooth_class_ & 0x1f00) >> 8) {
+  uint32 bluetooth_class = GetBluetoothClass();
+  switch ((bluetooth_class & 0x1f00) >> 8) {
     case 0x01:
       // Computer major device class.
       return DEVICE_COMPUTER;
     case 0x02:
       // Phone major device class.
-      switch ((bluetooth_class_ & 0xfc) >> 2) {
+      switch ((bluetooth_class & 0xfc) >> 2) {
         case 0x01:
         case 0x02:
         case 0x03:
@@ -109,7 +102,7 @@
       break;
     case 0x04:
       // Audio major device class.
-      switch ((bluetooth_class_ & 0xfc) >> 2) {
+      switch ((bluetooth_class & 0xfc) >> 2) {
         case 0x08:
           // Car audio.
           return DEVICE_CAR_AUDIO;
@@ -127,10 +120,10 @@
       break;
     case 0x05:
       // Peripheral major device class.
-      switch ((bluetooth_class_ & 0xc0) >> 6) {
+      switch ((bluetooth_class & 0xc0) >> 6) {
         case 0x00:
           // "Not a keyboard or pointing device."
-          switch ((bluetooth_class_ & 0x01e) >> 2) {
+          switch ((bluetooth_class & 0x01e) >> 2) {
             case 0x01:
               // Joystick.
               return DEVICE_JOYSTICK;
@@ -146,7 +139,7 @@
           return DEVICE_KEYBOARD;
         case 0x02:
           // Pointing device.
-          switch ((bluetooth_class_ & 0x01e) >> 2) {
+          switch ((bluetooth_class & 0x01e) >> 2) {
             case 0x05:
               // Digitizer tablet.
               return DEVICE_TABLET;
@@ -165,30 +158,11 @@
   return DEVICE_UNKNOWN;
 }
 
-bool BluetoothDevice::IsVisible() const {
-  return visible_;
-}
-
-bool BluetoothDevice::IsBonded() const {
-  return bonded_;
-}
-
-bool BluetoothDevice::IsConnected() const {
-  return connected_;
-}
-
-bool BluetoothDevice::IsConnectable() const {
-  return connectable_;
-}
-
-bool BluetoothDevice::IsConnecting() const {
-  return connecting_;
-}
 
 bool BluetoothDevice::ProvidesServiceWithUUID(
     const std::string& uuid) const {
   std::string canonical_uuid = bluetooth_utils::CanonicalUuid(uuid);
-  const BluetoothDevice::ServiceList& services = GetServices();
+  BluetoothDevice::ServiceList services = GetServices();
   for (BluetoothDevice::ServiceList::const_iterator iter = services.begin();
        iter != services.end();
        ++iter) {
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h
index b7dc9e2a..bb363f9 100644
--- a/device/bluetooth/bluetooth_device.h
+++ b/device/bluetooth/bluetooth_device.h
@@ -6,7 +6,6 @@
 #define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_
 
 #include <string>
-#include <vector>
 
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
@@ -26,7 +25,7 @@
 //
 // The class is instantiated and managed by the BluetoothAdapter class
 // and pointers should only be obtained from that class and not cached,
-// instead use the address() method as a unique key for a device.
+// instead use the GetAddress() method as a unique key for a device.
 //
 // Since the lifecycle of BluetoothDevice instances is managed by
 // BluetoothAdapter, that class rather than this provides observer methods
@@ -153,7 +152,7 @@
 
   // Returns the Bluetooth of address the device. This should be used as
   // a unique key to identify the device and copied where needed.
-  virtual const std::string& address() const;
+  virtual std::string GetAddress() const = 0;
 
   // Returns the name of the device suitable for displaying, this may
   // be a synthesied string containing the address and localized type name
@@ -166,35 +165,24 @@
   // DEVICE_PERIPHERAL.
   DeviceType GetDeviceType() const;
 
-  // Indicates whether the device is paired to the adapter, whether or not
-  // that pairing is permanent or temporary.
+  // Indicates whether the device is paired with the adapter.
   virtual bool IsPaired() const = 0;
 
-  // Indicates whether the device is visible to the adapter, this is not
-  // mutually exclusive to being paired.
-  virtual bool IsVisible() const;
+  // Indicates whether the device is currently connected to the adapter.
+  virtual bool IsConnected() const = 0;
 
-  // Indicates whether the device is bonded to the adapter, bonding is
-  // formed by pairing and exchanging high-security link keys so that
-  // connections may be encrypted.
-  virtual bool IsBonded() const;
-
-  // Indicates whether the device is currently connected to the adapter
-  // and at least one service available for use.
-  virtual bool IsConnected() const;
-
-  // Indicates whether the bonded device accepts connections initiated from the
-  // adapter. This value is undefined for unbonded devices.
-  virtual bool IsConnectable() const;
+  // Indicates whether the paired device accepts connections initiated from the
+  // adapter. This value is undefined for unpaired devices.
+  virtual bool IsConnectable() const = 0;
 
   // Indicates whether there is a call to Connect() ongoing. For this attribute,
   // we consider a call is ongoing if none of the callbacks passed to Connect()
   // were called after the corresponding call to Connect().
-  virtual bool IsConnecting() const;
+  virtual bool IsConnecting() const = 0;
 
   // Returns the services (as UUID strings) that this device provides.
   typedef std::vector<std::string> ServiceList;
-  virtual const ServiceList& GetServices() const = 0;
+  virtual ServiceList GetServices() const = 0;
 
   // The ErrorCallback is used for methods that can fail in which case it
   // is called, in the success case the callback is simply not called.
@@ -326,31 +314,11 @@
  protected:
   BluetoothDevice();
 
-  // The Bluetooth class of the device, a bitmask that may be decoded using
-  // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
-  uint32 bluetooth_class_;
+  // Returns the Bluetooth class of the device, used by GetDeviceType().
+  virtual uint32 GetBluetoothClass() const = 0;
 
-  // The name of the device, as supplied by the remote device.
-  std::string name_;
-
-  // The Bluetooth address of the device.
-  std::string address_;
-
-  // Tracked device state, updated by the adapter managing the lifecyle of
-  // the device.
-  bool visible_;
-  bool bonded_;
-  bool connected_;
-
-  // Indicates whether the device normally accepts connections initiated from
-  // the adapter once paired.
-  bool connectable_;
-
-  // Indicated whether the device is in a connecting status.
-  bool connecting_;
-
-  // The services (identified by UUIDs) that this device provides.
-  ServiceList service_uuids_;
+  // Returns the internal name of the Bluetooth device, used by GetName().
+  virtual std::string GetDeviceName() const = 0;
 
  private:
   // Returns a localized string containing the device's bluetooth address and
diff --git a/device/bluetooth/bluetooth_device_chromeos.cc b/device/bluetooth/bluetooth_device_chromeos.cc
index 32f4d9fd..0d87b18 100644
--- a/device/bluetooth/bluetooth_device_chromeos.cc
+++ b/device/bluetooth/bluetooth_device_chromeos.cc
@@ -50,6 +50,11 @@
     BluetoothAdapterChromeOS* adapter)
     : BluetoothDevice(),
       adapter_(adapter),
+      bluetooth_class_(0),
+      paired_(false),
+      connected_(false),
+      connectable_(true),
+      connecting_(false),
       pairing_delegate_(NULL),
       connecting_applications_counter_(0),
       connecting_calls_(0),
@@ -60,11 +65,35 @@
 BluetoothDeviceChromeOS::~BluetoothDeviceChromeOS() {
 }
 
-bool BluetoothDeviceChromeOS::IsPaired() const {
-  return !object_path_.value().empty();
+uint32 BluetoothDeviceChromeOS::GetBluetoothClass() const {
+  return bluetooth_class_;
 }
 
-const BluetoothDevice::ServiceList&
+std::string BluetoothDeviceChromeOS::GetDeviceName() const {
+  return name_;
+}
+
+std::string BluetoothDeviceChromeOS::GetAddress() const {
+  return address_;
+}
+
+bool BluetoothDeviceChromeOS::IsPaired() const {
+  return paired_;
+}
+
+bool BluetoothDeviceChromeOS::IsConnected() const {
+  return connected_;
+}
+
+bool BluetoothDeviceChromeOS::IsConnectable() const {
+  return connectable_;
+}
+
+bool BluetoothDeviceChromeOS::IsConnecting() const {
+  return connecting_;
+}
+
+BluetoothDeviceChromeOS::ServiceList
 BluetoothDeviceChromeOS::GetServices() const {
   return service_uuids_;
 }
@@ -129,7 +158,7 @@
       weak_ptr_factory_.GetWeakPtr(),
       error_callback);
 
-  if (IsPaired() || IsBonded() || IsConnected()) {
+  if (IsPaired() || IsConnected()) {
     // Connection to already paired or connected device.
     ConnectApplications(wrapped_callback, wrapped_error_callback);
 
@@ -301,7 +330,7 @@
   DBusThreadManager::Get()->GetBluetoothOutOfBandClient()->
       AddRemoteData(
           object_path_,
-          address(),
+          address_,
           data,
           base::Bind(&BluetoothDeviceChromeOS::OnRemoteDataCallback,
                      weak_ptr_factory_.GetWeakPtr(),
@@ -315,7 +344,7 @@
   DBusThreadManager::Get()->GetBluetoothOutOfBandClient()->
       RemoveRemoteData(
           object_path_,
-          address(),
+          address_,
           base::Bind(&BluetoothDeviceChromeOS::OnRemoteDataCallback,
                      weak_ptr_factory_.GetWeakPtr(),
                      callback,
@@ -360,9 +389,7 @@
       GetServiceRecords(base::Bind(&DoNothingServiceRecordList),
                         base::Bind(&base::DoNothing));
 
-    // BlueZ uses paired to mean link keys exchanged, whereas the Bluetooth
-    // spec refers to this as bonded. Use the spec name for our interface.
-    bonded_ = properties->paired.value();
+    paired_ = properties->paired.value();
     connected_ = properties->connected.value();
   }
 }
@@ -454,7 +481,7 @@
   for (BluetoothDeviceClient::ServiceMap::const_iterator i =
       service_map.begin(); i != service_map.end(); ++i) {
     service_records_.push_back(
-        new BluetoothServiceRecordChromeOS(address(), i->second));
+        new BluetoothServiceRecordChromeOS(address_, i->second));
   }
   service_records_loaded_ = true;
 
diff --git a/device/bluetooth/bluetooth_device_chromeos.h b/device/bluetooth/bluetooth_device_chromeos.h
index 32e8984a..30bf9c6 100644
--- a/device/bluetooth/bluetooth_device_chromeos.h
+++ b/device/bluetooth/bluetooth_device_chromeos.h
@@ -40,8 +40,12 @@
   virtual ~BluetoothDeviceChromeOS();
 
   // BluetoothDevice override
+  virtual std::string GetAddress() const OVERRIDE;
   virtual bool IsPaired() const OVERRIDE;
-  virtual const ServiceList& GetServices() const OVERRIDE;
+  virtual bool IsConnected() const OVERRIDE;
+  virtual bool IsConnectable() const OVERRIDE;
+  virtual bool IsConnecting() const OVERRIDE;
+  virtual ServiceList GetServices() const OVERRIDE;
   virtual void GetServiceRecords(
       const ServiceRecordsCallback& callback,
       const ErrorCallback& error_callback) OVERRIDE;
@@ -75,22 +79,33 @@
       const base::Closure& callback,
       const ErrorCallback& error_callback) OVERRIDE;
 
+ protected:
+  // BluetoothDevice override
+  virtual uint32 GetBluetoothClass() const OVERRIDE;
+  virtual std::string GetDeviceName() const OVERRIDE;
+
  private:
   friend class BluetoothAdapterChromeOS;
   friend class device::MockBluetoothDevice;
 
   explicit BluetoothDeviceChromeOS(BluetoothAdapterChromeOS* adapter);
 
+  // Returns whether this device has an object path.
+  bool HasObjectPath() const { return !object_path_.value().empty(); }
+
   // Sets the dbus object path for the device to |object_path|, indicating
-  // that the device has gone from being discovered to paired or bonded.
+  // that the device has gone from being discovered to paired or connected.
   void SetObjectPath(const dbus::ObjectPath& object_path);
 
   // Removes the dbus object path from the device, indicating that the
-  // device is no longer paired or bonded, but perhaps still visible.
+  // device is no longer paired or connected, but perhaps still visible.
   void RemoveObjectPath();
 
-  // Sets whether the device is visible to the owning adapter to |visible|.
-  void SetVisible(bool visible) { visible_ = visible; }
+  // Returns whether this was a discovered device.
+  bool WasDiscovered() const { return discovered_; }
+
+  // Sets whether the device was discovered.
+  void SetDiscovered(bool discovered) { discovered_ = discovered; }
 
   // Updates device information from the properties in |properties|, device
   // state properties such as |paired_| and |connected_| are ignored unless
@@ -371,8 +386,34 @@
   // been discovered and not yet paired with.
   dbus::ObjectPath object_path_;
 
+  // The Bluetooth class of the device, a bitmask that may be decoded using
+  // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
+  uint32 bluetooth_class_;
+
+  // The name of the device, as supplied by the remote device.
+  std::string name_;
+
+  // The Bluetooth address of the device.
+  std::string address_;
+
+  // Tracked device state, updated by the adapter managing the lifecyle of
+  // the device.
+  bool paired_;
+  bool connected_;
+
+  // Indicates whether the device normally accepts connections initiated from
+  // the adapter once paired.
+  bool connectable_;
+
+  // Indicated whether the device is in a connecting status.
+  bool connecting_;
+
+  // Used by BluetoothAdapterChromeOS (a friend) to avoid removing discovered
+  // devices when they are unpaired.
+  bool discovered_;
+
   // The services (identified by UUIDs) that this device provides.
-  std::vector<std::string> service_uuids_;
+  ServiceList service_uuids_;
 
   // During pairing this is set to an object that we don't own, but on which
   // we can make method calls to request, display or confirm PIN Codes and
diff --git a/device/bluetooth/bluetooth_device_mac.h b/device/bluetooth/bluetooth_device_mac.h
index a3e42d86..653c246 100644
--- a/device/bluetooth/bluetooth_device_mac.h
+++ b/device/bluetooth/bluetooth_device_mac.h
@@ -24,8 +24,12 @@
   virtual ~BluetoothDeviceMac();
 
   // BluetoothDevice override
+  virtual std::string GetAddress() const OVERRIDE;
   virtual bool IsPaired() const OVERRIDE;
-  virtual const ServiceList& GetServices() const OVERRIDE;
+  virtual bool IsConnected() const OVERRIDE;
+  virtual bool IsConnectable() const OVERRIDE;
+  virtual bool IsConnecting() const OVERRIDE;
+  virtual ServiceList GetServices() const OVERRIDE;
   virtual void GetServiceRecords(
       const ServiceRecordsCallback& callback,
       const ErrorCallback& error_callback) OVERRIDE;
@@ -59,6 +63,11 @@
       const base::Closure& callback,
       const ErrorCallback& error_callback) OVERRIDE;
 
+ protected:
+  // BluetoothDevice override
+  virtual uint32 GetBluetoothClass() const OVERRIDE;
+  virtual std::string GetDeviceName() const OVERRIDE;
+
  private:
   friend class BluetoothAdapterMac;
 
@@ -69,6 +78,24 @@
     return device_fingerprint_;
   }
 
+  // The Bluetooth class of the device, a bitmask that may be decoded using
+  // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
+  uint32 bluetooth_class_;
+
+  // The name of the device, as supplied by the remote device.
+  std::string name_;
+
+  // The Bluetooth address of the device.
+  std::string address_;
+
+  // Tracked device state, updated by the adapter managing the lifecyle of
+  // the device.
+  bool paired_;
+  bool connected_;
+
+  // The services (identified by UUIDs) that this device provides.
+  ServiceList service_uuids_;
+
   // Used to compare the devices.
   const uint32 device_fingerprint_;
   ServiceRecordList service_record_list_;
diff --git a/device/bluetooth/bluetooth_device_mac.mm b/device/bluetooth/bluetooth_device_mac.mm
index 9669cfa..df0b0af4 100644
--- a/device/bluetooth/bluetooth_device_mac.mm
+++ b/device/bluetooth/bluetooth_device_mac.mm
@@ -40,8 +40,7 @@
   address_ = base::SysNSStringToUTF8([device addressString]);
   bluetooth_class_ = [device classOfDevice];
   connected_ = [device isConnected];
-  bonded_ = [device isPaired];
-  visible_ = true;
+  paired_ = [device isPaired];
 
   for (IOBluetoothSDPServiceRecord* service in [device services]) {
     BluetoothServiceRecord* service_record =
@@ -54,11 +53,35 @@
 BluetoothDeviceMac::~BluetoothDeviceMac() {
 }
 
-bool BluetoothDeviceMac::IsPaired() const {
-  return bonded_;
+uint32 BluetoothDeviceMac::GetBluetoothClass() const {
+  return bluetooth_class_;
 }
 
-const BluetoothDevice::ServiceList& BluetoothDeviceMac::GetServices() const {
+std::string BluetoothDeviceMac::GetDeviceName() const {
+  return name_;
+}
+
+std::string BluetoothDeviceMac::GetAddress() const {
+  return address_;
+}
+
+bool BluetoothDeviceMac::IsPaired() const {
+  return paired_;
+}
+
+bool BluetoothDeviceMac::IsConnected() const {
+  return connected_;
+}
+
+bool BluetoothDeviceMac::IsConnectable() const {
+  return false;
+}
+
+bool BluetoothDeviceMac::IsConnecting() const {
+  return false;
+}
+
+BluetoothDevice::ServiceList BluetoothDeviceMac::GetServices() const {
   return service_uuids_;
 }
 
diff --git a/device/bluetooth/bluetooth_device_win.cc b/device/bluetooth/bluetooth_device_win.cc
index c06693f..22f51de 100644
--- a/device/bluetooth/bluetooth_device_win.cc
+++ b/device/bluetooth/bluetooth_device_win.cc
@@ -30,8 +30,9 @@
   name_ = state.name;
   address_ = state.address;
   bluetooth_class_ = state.bluetooth_class;
+  visible_ = state.visible;
   connected_ = state.connected;
-  bonded_ = state.authenticated;
+  paired_ = state.authenticated;
 
   for (ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>::const_iterator
        iter = state.service_record_states.begin();
@@ -58,11 +59,35 @@
   visible_ = visible;
 }
 
+uint32 BluetoothDeviceWin::GetBluetoothClass() const {
+  return bluetooth_class_;
+}
+
+std::string BluetoothDeviceWin::GetDeviceName() const {
+  return name_;
+}
+
+std::string BluetoothDeviceWin::GetAddress() const {
+  return address_;
+}
+
 bool BluetoothDeviceWin::IsPaired() const {
+  return paired_;
+}
+
+bool BluetoothDeviceWin::IsConnected() const {
+  return connected_;
+}
+
+bool BluetoothDeviceWin::IsConnectable() const {
   return false;
 }
 
-const BluetoothDevice::ServiceList& BluetoothDeviceWin::GetServices() const {
+bool BluetoothDeviceWin::IsConnecting() const {
+  return false;
+}
+
+BluetoothDevice::ServiceList BluetoothDeviceWin::GetServices() const {
   return service_uuids_;
 }
 
diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h
index b1e9d80..7213cd1 100644
--- a/device/bluetooth/bluetooth_device_win.h
+++ b/device/bluetooth/bluetooth_device_win.h
@@ -22,11 +22,13 @@
       const BluetoothTaskManagerWin::DeviceState& state);
   virtual ~BluetoothDeviceWin();
 
-  void SetVisible(bool visible);
-
   // BluetoothDevice override
+  virtual std::string GetAddress() const OVERRIDE;
   virtual bool IsPaired() const OVERRIDE;
-  virtual const ServiceList& GetServices() const OVERRIDE;
+  virtual bool IsConnected() const OVERRIDE;
+  virtual bool IsConnectable() const OVERRIDE;
+  virtual bool IsConnecting() const OVERRIDE;
+  virtual ServiceList GetServices() const OVERRIDE;
   virtual void GetServiceRecords(
       const ServiceRecordsCallback& callback,
       const ErrorCallback& error_callback) OVERRIDE;
@@ -60,9 +62,18 @@
       const base::Closure& callback,
       const ErrorCallback& error_callback) OVERRIDE;
 
+ protected:
+  // BluetoothDevice override
+  virtual uint32 GetBluetoothClass() const OVERRIDE;
+  virtual std::string GetDeviceName() const OVERRIDE;
+
  private:
   friend class BluetoothAdapterWin;
 
+  // Used by BluetoothAdapterWin to update the visible state during
+  // discovery.
+  void SetVisible(bool visible);
+
   // Computes the fingerprint that can be used to compare the devices.
   static uint32 ComputeDeviceFingerprint(
       const BluetoothTaskManagerWin::DeviceState& state);
@@ -71,6 +82,28 @@
     return device_fingerprint_;
   }
 
+  // The Bluetooth class of the device, a bitmask that may be decoded using
+  // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
+  uint32 bluetooth_class_;
+
+  // The name of the device, as supplied by the remote device.
+  std::string name_;
+
+  // The Bluetooth address of the device.
+  std::string address_;
+
+  // Tracked device state, updated by the adapter managing the lifecyle of
+  // the device.
+  bool paired_;
+  bool connected_;
+
+  // Used to send change notifications when a device disappears during
+  // discovery.
+  bool visible_;
+
+  // The services (identified by UUIDs) that this device provides.
+  ServiceList service_uuids_;
+
   // Used to compare the devices.
   uint32 device_fingerprint_;
   ServiceRecordList service_record_list_;
diff --git a/device/bluetooth/bluetooth_device_win_unittest.cc b/device/bluetooth/bluetooth_device_win_unittest.cc
index 892f0229..0f41665 100644
--- a/device/bluetooth/bluetooth_device_win_unittest.cc
+++ b/device/bluetooth/bluetooth_device_win_unittest.cc
@@ -85,7 +85,7 @@
 };
 
 TEST_F(BluetoothDeviceWinTest, GetServices) {
-  const BluetoothDevice::ServiceList& service_list = device_->GetServices();
+  BluetoothDevice::ServiceList service_list = device_->GetServices();
 
   EXPECT_EQ(2, service_list.size());
   EXPECT_STREQ(kTestAudioSdpUuid, service_list[0].c_str());
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.h b/device/bluetooth/test/mock_bluetooth_adapter.h
index f375b4c..d2c987886 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.h
+++ b/device/bluetooth/test/mock_bluetooth_adapter.h
@@ -33,8 +33,8 @@
 
   MOCK_METHOD1(AddObserver, void(BluetoothAdapter::Observer*));
   MOCK_METHOD1(RemoveObserver, void(BluetoothAdapter::Observer*));
-  MOCK_CONST_METHOD0(address, std::string());
-  MOCK_CONST_METHOD0(name, std::string());
+  MOCK_CONST_METHOD0(GetAddress, std::string());
+  MOCK_CONST_METHOD0(GetName, std::string());
   MOCK_CONST_METHOD0(IsInitialized, bool());
   MOCK_CONST_METHOD0(IsPresent, bool());
   MOCK_CONST_METHOD0(IsPowered, bool());
diff --git a/device/bluetooth/test/mock_bluetooth_device.cc b/device/bluetooth/test/mock_bluetooth_device.cc
index 6762e04..61ab155 100644
--- a/device/bluetooth/test/mock_bluetooth_device.cc
+++ b/device/bluetooth/test/mock_bluetooth_device.cc
@@ -10,23 +10,30 @@
 namespace device {
 
 MockBluetoothDevice::MockBluetoothDevice(MockBluetoothAdapter* adapter,
+                                         uint32 bluetooth_class,
                                          const std::string& name,
                                          const std::string& address,
                                          bool paired,
-                                         bool bonded,
                                          bool connected)
-    : name_(UTF8ToUTF16(name)),
+    : bluetooth_class_(bluetooth_class),
+      name_(name),
       address_(address) {
-  ON_CALL(*this, GetName())
+  ON_CALL(*this, GetBluetoothClass())
+      .WillByDefault(testing::Return(bluetooth_class_));
+  ON_CALL(*this, GetDeviceName())
       .WillByDefault(testing::Return(name_));
-  ON_CALL(*this, address())
-      .WillByDefault(testing::ReturnRef(address_));
+  ON_CALL(*this, GetAddress())
+      .WillByDefault(testing::Return(address_));
   ON_CALL(*this, IsPaired())
       .WillByDefault(testing::Return(paired));
-  ON_CALL(*this, IsBonded())
-      .WillByDefault(testing::Return(bonded));
   ON_CALL(*this, IsConnected())
       .WillByDefault(testing::Return(connected));
+  ON_CALL(*this, IsConnectable())
+      .WillByDefault(testing::Return(false));
+  ON_CALL(*this, IsConnecting())
+      .WillByDefault(testing::Return(false));
+  ON_CALL(*this, GetName())
+      .WillByDefault(testing::Return(UTF8ToUTF16(name_)));
   ON_CALL(*this, ExpectingPinCode())
       .WillByDefault(testing::Return(false));
   ON_CALL(*this, ExpectingPasskey())
@@ -34,7 +41,7 @@
   ON_CALL(*this, ExpectingConfirmation())
       .WillByDefault(testing::Return(false));
   ON_CALL(*this, GetServices())
-      .WillByDefault(testing::ReturnRef(service_list_));
+      .WillByDefault(testing::Return(service_list_));
 }
 
 MockBluetoothDevice::~MockBluetoothDevice() {}
diff --git a/device/bluetooth/test/mock_bluetooth_device.h b/device/bluetooth/test/mock_bluetooth_device.h
index 56ca4c2..663bfd8 100644
--- a/device/bluetooth/test/mock_bluetooth_device.h
+++ b/device/bluetooth/test/mock_bluetooth_device.h
@@ -19,20 +19,23 @@
 class MockBluetoothDevice : public BluetoothDevice {
  public:
   MockBluetoothDevice(MockBluetoothAdapter* adapter,
+                      uint32 bluetooth_class,
                       const std::string& name,
                       const std::string& address,
                       bool paired,
-                      bool bonded,
                       bool connected);
   virtual ~MockBluetoothDevice();
 
-  MOCK_CONST_METHOD0(address, const std::string&());
+  MOCK_CONST_METHOD0(GetBluetoothClass, uint32());
+  MOCK_CONST_METHOD0(GetDeviceName, std::string());
+  MOCK_CONST_METHOD0(GetAddress, std::string());
   MOCK_CONST_METHOD0(GetName, string16());
   MOCK_CONST_METHOD0(GetDeviceType, BluetoothDevice::DeviceType());
   MOCK_CONST_METHOD0(IsPaired, bool());
-  MOCK_CONST_METHOD0(IsBonded, bool());
   MOCK_CONST_METHOD0(IsConnected, bool());
-  MOCK_CONST_METHOD0(GetServices, const ServiceList&());
+  MOCK_CONST_METHOD0(IsConnectable, bool());
+  MOCK_CONST_METHOD0(IsConnecting, bool());
+  MOCK_CONST_METHOD0(GetServices, ServiceList());
   MOCK_METHOD2(GetServiceRecords,
                void(const BluetoothDevice::ServiceRecordsCallback&,
                     const BluetoothDevice::ErrorCallback&));
@@ -70,7 +73,8 @@
            const BluetoothDevice::ErrorCallback& error_callback));
 
  private:
-  string16 name_;
+  uint32 bluetooth_class_;
+  std::string name_;
   std::string address_;
   BluetoothDevice::ServiceList service_list_;
 };