Add abstract BluetoothProfile class

This class will form the base of the 4.0 BR+LE compatible API,
allowing for both incoming connections for profiles we're clients
for and implementing services within Chrome.

BUG=229636
TEST=none

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195280 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h
index 1220bcca8..d022ea9 100644
--- a/device/bluetooth/bluetooth_device.h
+++ b/device/bluetooth/bluetooth_device.h
@@ -14,6 +14,7 @@
 
 namespace device {
 
+class BluetoothProfile;
 class BluetoothServiceRecord;
 class BluetoothSocket;
 
@@ -318,6 +319,12 @@
   virtual void ConnectToService(const std::string& service_uuid,
                                 const SocketCallback& callback) = 0;
 
+  // Attempts to initiate an outgoing connection to this device for the profile
+  // identified by |profile|, on success the profile's connection callback
+  // wil be called; on failure |error_callback| will be called.
+  virtual void ConnectToProfile(BluetoothProfile* profile,
+                                const ErrorCallback& error_callback) = 0;
+
   // Sets the Out Of Band pairing data for this device to |data|.  Exactly one
   // of |callback| or |error_callback| will be run.
   virtual void SetOutOfBandPairingData(
diff --git a/device/bluetooth/bluetooth_device_chromeos.cc b/device/bluetooth/bluetooth_device_chromeos.cc
index 67666b8..ce8cd9a 100644
--- a/device/bluetooth/bluetooth_device_chromeos.cc
+++ b/device/bluetooth/bluetooth_device_chromeos.cc
@@ -325,6 +325,12 @@
           callback));
 }
 
+void BluetoothDeviceChromeOS::ConnectToProfile(
+    device::BluetoothProfile* profile,
+    const ErrorCallback& error_callback) {
+  // TODO(keybuk): implement
+}
+
 void BluetoothDeviceChromeOS::SetOutOfBandPairingData(
     const BluetoothOutOfBandPairingData& data,
     const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_device_chromeos.h b/device/bluetooth/bluetooth_device_chromeos.h
index 558cccea..939ca06 100644
--- a/device/bluetooth/bluetooth_device_chromeos.h
+++ b/device/bluetooth/bluetooth_device_chromeos.h
@@ -71,6 +71,9 @@
   virtual void ConnectToService(
       const std::string& service_uuid,
       const SocketCallback& callback) OVERRIDE;
+  virtual void ConnectToProfile(
+      device::BluetoothProfile* profile,
+      const ErrorCallback& error_callback) OVERRIDE;
   virtual void SetOutOfBandPairingData(
       const device::BluetoothOutOfBandPairingData& data,
       const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_device_experimental_chromeos.cc b/device/bluetooth/bluetooth_device_experimental_chromeos.cc
index 0f3e478..85e84d3 100644
--- a/device/bluetooth/bluetooth_device_experimental_chromeos.cc
+++ b/device/bluetooth/bluetooth_device_experimental_chromeos.cc
@@ -257,6 +257,13 @@
   callback.Run(scoped_refptr<device::BluetoothSocket>());
 }
 
+void BluetoothDeviceExperimentalChromeOS::ConnectToProfile(
+    device::BluetoothProfile* profile,
+    const ErrorCallback& error_callback) {
+  // TODO(keybuk): implement
+  error_callback.Run();
+}
+
 void BluetoothDeviceExperimentalChromeOS::SetOutOfBandPairingData(
     const device::BluetoothOutOfBandPairingData& data,
     const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_device_experimental_chromeos.h b/device/bluetooth/bluetooth_device_experimental_chromeos.h
index e30fdf8..ff31ddb 100644
--- a/device/bluetooth/bluetooth_device_experimental_chromeos.h
+++ b/device/bluetooth/bluetooth_device_experimental_chromeos.h
@@ -58,6 +58,9 @@
   virtual void ConnectToService(
       const std::string& service_uuid,
       const SocketCallback& callback) OVERRIDE;
+  virtual void ConnectToProfile(
+      device::BluetoothProfile* profile,
+      const ErrorCallback& error_callback) OVERRIDE;
   virtual void SetOutOfBandPairingData(
       const device::BluetoothOutOfBandPairingData& data,
       const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_device_mac.h b/device/bluetooth/bluetooth_device_mac.h
index 66ab5d6..e61676a 100644
--- a/device/bluetooth/bluetooth_device_mac.h
+++ b/device/bluetooth/bluetooth_device_mac.h
@@ -55,6 +55,9 @@
   virtual void ConnectToService(
       const std::string& service_uuid,
       const SocketCallback& callback) OVERRIDE;
+  virtual void ConnectToProfile(
+      device::BluetoothProfile* profile,
+      const ErrorCallback& error_callback) OVERRIDE;
   virtual void SetOutOfBandPairingData(
       const BluetoothOutOfBandPairingData& data,
       const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_device_mac.mm b/device/bluetooth/bluetooth_device_mac.mm
index 51ef722a..85d1426 100644
--- a/device/bluetooth/bluetooth_device_mac.mm
+++ b/device/bluetooth/bluetooth_device_mac.mm
@@ -196,6 +196,12 @@
   }
 }
 
+void BluetoothDeviceMac::ConnectToProfile(
+    device::BluetoothProfile* profile,
+    const ErrorCallback& error_callback) {
+  // TODO(keybuk): implement
+}
+
 void BluetoothDeviceMac::SetOutOfBandPairingData(
     const BluetoothOutOfBandPairingData& data,
     const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_device_win.cc b/device/bluetooth/bluetooth_device_win.cc
index 22f51de..4af740b 100644
--- a/device/bluetooth/bluetooth_device_win.cc
+++ b/device/bluetooth/bluetooth_device_win.cc
@@ -181,6 +181,12 @@
   }
 }
 
+void BluetoothDeviceWin::ConnectToProfile(
+    device::BluetoothProfile* profile,
+    const ErrorCallback& error_callback) {
+  // TODO(keybuk): implement
+}
+
 void BluetoothDeviceWin::SetOutOfBandPairingData(
     const BluetoothOutOfBandPairingData& data,
     const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h
index 7213cd1..89cb78d1 100644
--- a/device/bluetooth/bluetooth_device_win.h
+++ b/device/bluetooth/bluetooth_device_win.h
@@ -54,6 +54,9 @@
   virtual void ConnectToService(
       const std::string& service_uuid,
       const SocketCallback& callback) OVERRIDE;
+  virtual void ConnectToProfile(
+      device::BluetoothProfile* profile,
+      const ErrorCallback& error_callback) OVERRIDE;
   virtual void SetOutOfBandPairingData(
       const BluetoothOutOfBandPairingData& data,
       const base::Closure& callback,
diff --git a/device/bluetooth/bluetooth_profile.cc b/device/bluetooth/bluetooth_profile.cc
new file mode 100644
index 0000000..b6d420b
--- /dev/null
+++ b/device/bluetooth/bluetooth_profile.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "device/bluetooth/bluetooth_profile.h"
+
+#include <string>
+
+namespace device {
+
+BluetoothProfile::Options::Options()
+    : channel(0),
+      psm(0),
+      require_authentication(false),
+      require_authorization(false),
+      version(0),
+      features(0) {
+}
+
+BluetoothProfile::Options::~Options() {
+
+}
+
+
+BluetoothProfile::BluetoothProfile() {
+
+}
+
+BluetoothProfile::~BluetoothProfile() {
+
+}
+
+
+// static
+void BluetoothProfile::Register(const std::string& uuid,
+                                const Options& options,
+                                const ProfileCallback& callback) {
+  // TODO(keybuk): Implement selection of the appropriate BluetoothProfile
+  // subclass just like BluetoothAdapterFactory
+  callback.Run(NULL);
+}
+
+}  // namespace device
diff --git a/device/bluetooth/bluetooth_profile.h b/device/bluetooth/bluetooth_profile.h
new file mode 100644
index 0000000..ecc437c
--- /dev/null
+++ b/device/bluetooth/bluetooth_profile.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_H_
+#define DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/memory/ref_counted.h"
+
+namespace device {
+
+class BluetoothSocket;
+
+// BluetoothProfile represents an implementation of either a client or server
+// of a particular specified profile (aka service or protocol in other
+// standards).
+//
+// Profile implementations are created by registering them through the static
+// BluetoothProfile::Register() method and are always identified by a UUID
+// which in any method may be specified in the short or long form.
+//
+// The lifecycle of BluetoothProfile instances is managed by the implementation
+// but they are guaranteed to exist once provided to a Register() callback until
+// the instance's Unregister() method is called, so others may hold on to
+// pointers to them.
+class BluetoothProfile {
+ public:
+  // Options used to register a BluetoothProfile object.
+  struct Options {
+    Options();
+    ~Options();
+
+    // Human readable name of the Profile, e.g. "Health Device".
+    // Exported in the adapter's SDP or GATT tables where relevant.
+    std::string name;
+
+    // RFCOMM channel used by the profile.
+    // Exported in the adapter's SDP or GATT tables where relevant.
+    uint16 channel;
+
+    // L2CAP PSM number.
+    // Exported in the adapter's SDP or GATT tables where relevant.
+    uint16 psm;
+
+    // Specifies whether pairing (and encryption) is required to be able to
+    // connect. Defaults to false.
+    bool require_authentication;
+
+    // Specifies whether user authorization is required to be able to connect.
+    // Defaults to false.
+    bool require_authorization;
+
+    // Implemented version of the profile.
+    // Exported in the adapter's SDP or GATT tables where relevant.
+    uint16 version;
+
+    // Implemented feature set of the profile.
+    // Exported in the adapter's SDP or GATT tables where relevant.
+    uint16 features;
+  };
+
+  // Register an implementation of the profile with UUID |uuid| and
+  // additional details specified in |options|. The corresponding profile
+  // object will be created and returned by |callback|. If the profile cannot
+  // be registered, NULL will be passed.
+  //
+  // This pointer is not owned by the receiver, but will not be freed unless
+  // its Unregister() method is called.
+  typedef base::Callback<void(BluetoothProfile*)> ProfileCallback;
+  static void Register(const std::string& uuid,
+                       const Options& options,
+                       const ProfileCallback& callback);
+
+  // Unregister the profile. This deletes the profile object so, once called,
+  // any pointers to the profile should be discarded.
+  virtual void Unregister() = 0;
+
+  // Set the connection callback for the profile to |callback|, any successful
+  // connection initiated by BluetoothDevice::ConnectToProfile() or incoming
+  // connections from devices, will have a BluetoothSocket created and passed
+  // to this callback.
+  //
+  // The socket will be closed when all references are released; none of the
+  // BluetoothProfile, or BluetoothAdapter or BluetoothDevice objects are
+  // guaranteed to hold a reference so this may outlive all of them.
+  typedef base::Callback<void(scoped_refptr<BluetoothSocket>)> SocketCallback;
+  virtual void SetConnectionCallback(const SocketCallback& callback) = 0;
+
+ private:
+  BluetoothProfile();
+  virtual ~BluetoothProfile();
+};
+
+}  // namespace device
+
+#endif /* DEVICE_BLUETOOTH_BLUETOOTH_PROFILE_H_ */
diff --git a/device/bluetooth/test/mock_bluetooth_device.h b/device/bluetooth/test/mock_bluetooth_device.h
index 663bfd8..c742d8e 100644
--- a/device/bluetooth/test/mock_bluetooth_device.h
+++ b/device/bluetooth/test/mock_bluetooth_device.h
@@ -47,7 +47,7 @@
   MOCK_CONST_METHOD0(ExpectingPasskey, bool());
   MOCK_CONST_METHOD0(ExpectingConfirmation, bool());
   MOCK_METHOD3(Connect,
-               void(BluetoothDevice::PairingDelegate* pairnig_delegate,
+               void(BluetoothDevice::PairingDelegate* pairing_delegate,
                     const base::Closure& callback,
                     const BluetoothDevice::ConnectErrorCallback&
                         error_callback));
@@ -63,6 +63,9 @@
   MOCK_METHOD2(ConnectToService,
                void(const std::string&,
                     const BluetoothDevice::SocketCallback&));
+  MOCK_METHOD2(ConnectToProfile,
+               void(BluetoothProfile*,
+                    const BluetoothDevice::ErrorCallback&));
 
   MOCK_METHOD3(SetOutOfBandPairingData,
       void(const BluetoothOutOfBandPairingData& data,
diff --git a/device/device.gyp b/device/device.gyp
index 0bb684a..3a8c87a 100644
--- a/device/device.gyp
+++ b/device/device.gyp
@@ -44,6 +44,8 @@
         'bluetooth/bluetooth_init_win.cc',
         'bluetooth/bluetooth_init_win.h',
         'bluetooth/bluetooth_out_of_band_pairing_data.h',
+        'bluetooth/bluetooth_profile.cc',
+        'bluetooth/bluetooth_profile.h',
         'bluetooth/bluetooth_service_record.cc',
         'bluetooth/bluetooth_service_record.h',
         'bluetooth/bluetooth_service_record_chromeos.cc',