From cab208eb0702d3541a7fa430889c26a3d1182120 Mon Sep 17 00:00:00 2001 From: "youngki@chromium.org" Date: Thu, 18 Oct 2012 22:15:23 +0000 Subject: Moved bluetooth adapter files from chrome/browser/chromeos/bluetooth/ to device/bluetooth/. device/bluetooth/ is a new directory to host the bluetooth related files. I also changed the namespace from chromeos to bluetooth under new directory. BUG=135470 Review URL: https://chromiumcodereview.appspot.com/11075006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162811 0039d316-1c4b-4281-b951-d872f2087c98 --- build/all.gyp | 9 + chrome/app/generated_resources.grd | 81 +- chrome/browser/DEPS | 1 + chrome/browser/chromeos/DEPS | 1 + chrome/browser/chromeos/bluetooth/OWNERS | 2 - .../chromeos/bluetooth/bluetooth_adapter.cc | 34 - .../browser/chromeos/bluetooth/bluetooth_adapter.h | 155 -- .../bluetooth/bluetooth_adapter_chromeos.cc | 535 ------- .../bluetooth/bluetooth_adapter_chromeos.h | 232 --- .../bluetooth_adapter_chromeos_unittest.cc | 1553 ------------------- .../bluetooth_adapter_devices_chromeos_unittest.cc | 163 -- .../bluetooth/bluetooth_adapter_factory.cc | 44 - .../chromeos/bluetooth/bluetooth_adapter_factory.h | 32 - .../browser/chromeos/bluetooth/bluetooth_device.cc | 170 --- .../browser/chromeos/bluetooth/bluetooth_device.h | 318 ---- .../bluetooth/bluetooth_device_chromeos.cc | 685 --------- .../chromeos/bluetooth/bluetooth_device_chromeos.h | 369 ----- .../chromeos/bluetooth/bluetooth_service_record.cc | 122 -- .../chromeos/bluetooth/bluetooth_service_record.h | 59 - .../bluetooth/bluetooth_service_record_unittest.cc | 75 - .../browser/chromeos/bluetooth/bluetooth_socket.h | 30 - .../bluetooth/bluetooth_socket_chromeos.cc | 68 - .../chromeos/bluetooth/bluetooth_socket_chromeos.h | 40 - .../browser/chromeos/bluetooth/bluetooth_utils.cc | 88 -- .../browser/chromeos/bluetooth/bluetooth_utils.h | 38 - .../chromeos/bluetooth/bluetooth_utils_unittest.cc | 72 - .../bluetooth/test/mock_bluetooth_adapter.cc | 20 - .../bluetooth/test/mock_bluetooth_adapter.h | 62 - .../bluetooth/test/mock_bluetooth_device.cc | 41 - .../bluetooth/test/mock_bluetooth_device.h | 77 - .../chromeos/extensions/bluetooth_event_router.cc | 173 --- .../chromeos/extensions/bluetooth_event_router.h | 95 -- .../chromeos/system/ash_system_tray_delegate.cc | 37 +- .../extensions/api/bluetooth/bluetooth_api.cc | 266 ++-- .../extensions/api/bluetooth/bluetooth_api.h | 49 +- .../api/bluetooth/bluetooth_api_utils.cc | 15 +- .../extensions/api/bluetooth/bluetooth_api_utils.h | 13 +- .../api/bluetooth/bluetooth_apitest_chromeos.cc | 54 +- .../browser/extensions/bluetooth_event_router.cc | 176 +++ chrome/browser/extensions/bluetooth_event_router.h | 102 ++ chrome/browser/extensions/event_names.cc | 2 - chrome/browser/extensions/event_names.h | 2 - chrome/browser/extensions/extension_service.cc | 7 +- chrome/browser/extensions/extension_service.h | 10 +- chrome/browser/ui/webui/DEPS | 1 + .../options/chromeos/bluetooth_options_handler.cc | 49 +- .../options/chromeos/bluetooth_options_handler.h | 81 +- chrome/chrome_browser_chromeos.gypi | 20 +- chrome/chrome_browser_extensions.gypi | 3 + chrome/chrome_browser_ui.gypi | 1 + chrome/chrome_tests.gypi | 11 +- .../test/data/chromeos/bluetooth/invalid_uuid.xml | 8 - .../test/data/chromeos/bluetooth/medium_uuid.xml | 8 - chrome/test/data/chromeos/bluetooth/rfcomm.xml | 39 - chrome/test/data/chromeos/bluetooth/short_uuid.xml | 8 - .../data/chromeos/bluetooth/uppercase_uuid.xml | 8 - chromeos/chromeos.gyp | 1 - chromeos/dbus/DEPS | 1 + chromeos/dbus/bluetooth_out_of_band_client.cc | 23 +- chromeos/dbus/bluetooth_out_of_band_client.h | 11 +- chromeos/dbus/bluetooth_out_of_band_pairing_data.h | 27 - chromeos/dbus/mock_bluetooth_out_of_band_client.h | 4 +- device/DEPS | 4 + device/bluetooth/DEPS | 11 + device/bluetooth/OWNERS | 2 + device/bluetooth/bluetooth_adapter.cc | 34 + device/bluetooth/bluetooth_adapter.h | 155 ++ device/bluetooth/bluetooth_adapter_chromeos.cc | 539 +++++++ device/bluetooth/bluetooth_adapter_chromeos.h | 245 +++ .../bluetooth_adapter_chromeos_devices_unittest.cc | 168 +++ .../bluetooth_adapter_chromeos_unittest.cc | 1557 ++++++++++++++++++++ device/bluetooth/bluetooth_adapter_factory.cc | 55 + device/bluetooth/bluetooth_adapter_factory.h | 33 + device/bluetooth/bluetooth_device.cc | 170 +++ device/bluetooth/bluetooth_device.h | 318 ++++ device/bluetooth/bluetooth_device_chromeos.cc | 690 +++++++++ device/bluetooth/bluetooth_device_chromeos.h | 375 +++++ .../bluetooth/bluetooth_out_of_band_pairing_data.h | 27 + device/bluetooth/bluetooth_service_record.cc | 122 ++ device/bluetooth/bluetooth_service_record.h | 59 + .../bluetooth/bluetooth_service_record_unittest.cc | 78 + device/bluetooth/bluetooth_socket.h | 30 + device/bluetooth/bluetooth_socket_chromeos.cc | 71 + device/bluetooth/bluetooth_socket_chromeos.h | 45 + device/bluetooth/bluetooth_utils.cc | 92 ++ device/bluetooth/bluetooth_utils.h | 42 + device/bluetooth/bluetooth_utils_unittest.cc | 76 + device/bluetooth/test/mock_bluetooth_adapter.cc | 20 + device/bluetooth/test/mock_bluetooth_adapter.h | 61 + device/bluetooth/test/mock_bluetooth_device.cc | 41 + device/bluetooth/test/mock_bluetooth_device.h | 79 + device/device.gyp | 111 ++ device/test/data/bluetooth/invalid_uuid.xml | 8 + device/test/data/bluetooth/medium_uuid.xml | 8 + device/test/data/bluetooth/rfcomm.xml | 39 + device/test/data/bluetooth/short_uuid.xml | 8 + device/test/data/bluetooth/uppercase_uuid.xml | 8 + device/test/device_test_suite.cc | 18 + device/test/device_test_suite.h | 19 + device/test/run_all_unittests.cc | 10 + 100 files changed, 6053 insertions(+), 5856 deletions(-) delete mode 100644 chrome/browser/chromeos/bluetooth/OWNERS delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_adapter.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_adapter.h delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos_unittest.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_device.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_device.h delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_service_record.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_service_record.h delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_service_record_unittest.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_socket.h delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_utils.cc delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_utils.h delete mode 100644 chrome/browser/chromeos/bluetooth/bluetooth_utils_unittest.cc delete mode 100644 chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.cc delete mode 100644 chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h delete mode 100644 chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.cc delete mode 100644 chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h delete mode 100644 chrome/browser/chromeos/extensions/bluetooth_event_router.cc delete mode 100644 chrome/browser/chromeos/extensions/bluetooth_event_router.h create mode 100644 chrome/browser/extensions/bluetooth_event_router.cc create mode 100644 chrome/browser/extensions/bluetooth_event_router.h delete mode 100644 chrome/test/data/chromeos/bluetooth/invalid_uuid.xml delete mode 100644 chrome/test/data/chromeos/bluetooth/medium_uuid.xml delete mode 100644 chrome/test/data/chromeos/bluetooth/rfcomm.xml delete mode 100644 chrome/test/data/chromeos/bluetooth/short_uuid.xml delete mode 100644 chrome/test/data/chromeos/bluetooth/uppercase_uuid.xml delete mode 100644 chromeos/dbus/bluetooth_out_of_band_pairing_data.h create mode 100644 device/DEPS create mode 100644 device/bluetooth/DEPS create mode 100644 device/bluetooth/OWNERS create mode 100644 device/bluetooth/bluetooth_adapter.cc create mode 100644 device/bluetooth/bluetooth_adapter.h create mode 100644 device/bluetooth/bluetooth_adapter_chromeos.cc create mode 100644 device/bluetooth/bluetooth_adapter_chromeos.h create mode 100644 device/bluetooth/bluetooth_adapter_chromeos_devices_unittest.cc create mode 100644 device/bluetooth/bluetooth_adapter_chromeos_unittest.cc create mode 100644 device/bluetooth/bluetooth_adapter_factory.cc create mode 100644 device/bluetooth/bluetooth_adapter_factory.h create mode 100644 device/bluetooth/bluetooth_device.cc create mode 100644 device/bluetooth/bluetooth_device.h create mode 100644 device/bluetooth/bluetooth_device_chromeos.cc create mode 100644 device/bluetooth/bluetooth_device_chromeos.h create mode 100644 device/bluetooth/bluetooth_out_of_band_pairing_data.h create mode 100644 device/bluetooth/bluetooth_service_record.cc create mode 100644 device/bluetooth/bluetooth_service_record.h create mode 100644 device/bluetooth/bluetooth_service_record_unittest.cc create mode 100644 device/bluetooth/bluetooth_socket.h create mode 100644 device/bluetooth/bluetooth_socket_chromeos.cc create mode 100644 device/bluetooth/bluetooth_socket_chromeos.h create mode 100644 device/bluetooth/bluetooth_utils.cc create mode 100644 device/bluetooth/bluetooth_utils.h create mode 100644 device/bluetooth/bluetooth_utils_unittest.cc create mode 100644 device/bluetooth/test/mock_bluetooth_adapter.cc create mode 100644 device/bluetooth/test/mock_bluetooth_adapter.h create mode 100644 device/bluetooth/test/mock_bluetooth_device.cc create mode 100644 device/bluetooth/test/mock_bluetooth_device.h create mode 100644 device/device.gyp create mode 100644 device/test/data/bluetooth/invalid_uuid.xml create mode 100644 device/test/data/bluetooth/medium_uuid.xml create mode 100644 device/test/data/bluetooth/rfcomm.xml create mode 100644 device/test/data/bluetooth/short_uuid.xml create mode 100644 device/test/data/bluetooth/uppercase_uuid.xml create mode 100644 device/test/device_test_suite.cc create mode 100644 device/test/device_test_suite.h create mode 100644 device/test/run_all_unittests.cc diff --git a/build/all.gyp b/build/all.gyp index e7b50dd..7985110 100644 --- a/build/all.gyp +++ b/build/all.gyp @@ -33,6 +33,7 @@ 'dependencies': [ '../cc/cc_tests.gyp:*', '../chrome/chrome.gyp:*', + '../device/device.gyp:*', '../gpu/gpu.gyp:*', '../gpu/tools/tools.gyp:*', '../ipc/ipc.gyp:*', @@ -196,6 +197,7 @@ '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', + '../device/device.gyp:device_unittests', '../gpu/gpu.gyp:gpu_unittests', '../gpu/gles2_conform_support/gles2_conform_support.gyp:gles2_conform_support', '../ipc/ipc.gyp:ipc_tests', @@ -364,6 +366,7 @@ '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', + '../device/device.gyp:device_unittests', '../ui/ui.gyp:ui_unittests', '../gpu/gpu.gyp:gpu_unittests', '../ipc/ipc.gyp:ipc_tests', @@ -395,6 +398,7 @@ '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', + '../device/device.gyp:device_unittests', '../ui/ui.gyp:ui_unittests', '../gpu/gpu.gyp:gpu_unittests', '../ipc/ipc.gyp:ipc_tests', @@ -453,6 +457,7 @@ '../chrome/chrome.gyp:safe_browsing_tests', '../chrome/chrome.gyp:unit_tests', '../content/content.gyp:content_unittests', + '../device/device.gyp:device_unittests', '../ui/ui.gyp:ui_unittests', '../jingle/jingle.gyp:jingle_unittests', '../sql/sql.gyp:sql_unittests', @@ -495,6 +500,7 @@ '../chrome_frame/chrome_frame.gyp:chrome_frame_unittests', '../chrome_frame/chrome_frame.gyp:npchrome_frame', '../courgette/courgette.gyp:courgette_unittests', + '../device/device.gyp:device_unittests', '../ui/ui.gyp:ui_unittests', '../gpu/gpu.gyp:gpu_unittests', '../ipc/ipc.gyp:ipc_tests', @@ -554,6 +560,7 @@ '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_unittests', '../crypto/crypto.gyp:crypto_unittests', + '../device/device.gyp:device_unittests', '../ipc/ipc.gyp:ipc_tests', '../jingle/jingle.gyp:jingle_unittests', '../media/media.gyp:media_unittests', @@ -640,6 +647,7 @@ '../chrome/chrome.gyp:unit_tests', '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', + '../device/device.gyp:device_unittests', '../ppapi/ppapi_internal.gyp:ppapi_unittests', '../remoting/remoting.gyp:remoting_unittests', '../ui/aura/aura.gyp:*', @@ -686,6 +694,7 @@ 'dependencies!': [ '../chrome/chrome.gyp:chrome', '../chrome/chrome.gyp:unit_tests', + '../device/device.gyp:device_unittests', '../ui/views/views.gyp:views_unittests', ], }], diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 6ee27c8..2e854a6 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -14417,48 +14417,45 @@ Some features may be unavailable. Please check that the profile exists and you Expand - - - - Unknown or Unsupported Device ($112:34:56:78:9A:BC) - - - Computer ($112:34:56:78:9A:BC) - - - Phone ($112:34:56:78:9A:BC) - - - Modem ($112:34:56:78:9A:BC) - - - Audio ($112:34:56:78:9A:BC) - - - Car audio ($112:34:56:78:9A:BC) - - - Video ($112:34:56:78:9A:BC) - - - Joystick ($112:34:56:78:9A:BC) - - - Gamepad ($112:34:56:78:9A:BC) - - - Keyboard ($112:34:56:78:9A:BC) - - - Tablet ($112:34:56:78:9A:BC) - - - Mouse ($112:34:56:78:9A:BC) - - - Keyboard/Mouse ($112:34:56:78:9A:BC) - - + + Unknown or Unsupported Device ($112:34:56:78:9A:BC) + + + Computer ($112:34:56:78:9A:BC) + + + Phone ($112:34:56:78:9A:BC) + + + Modem ($112:34:56:78:9A:BC) + + + Audio ($112:34:56:78:9A:BC) + + + Car audio ($112:34:56:78:9A:BC) + + + Video ($112:34:56:78:9A:BC) + + + Joystick ($112:34:56:78:9A:BC) + + + Gamepad ($112:34:56:78:9A:BC) + + + Keyboard ($112:34:56:78:9A:BC) + + + Tablet ($112:34:56:78:9A:BC) + + + Mouse ($112:34:56:78:9A:BC) + + + Keyboard/Mouse ($112:34:56:78:9A:BC) + (this)->GetDevices(); - - DeviceList devices; - for (ConstDeviceList::const_iterator i = const_devices.begin(); - i != const_devices.end(); ++i) - devices.push_back(const_cast(*i)); - - return devices; -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter.h b/chrome/browser/chromeos/bluetooth/bluetooth_adapter.h deleted file mode 100644 index 14a94a1..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter.h +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_H_ - -#include -#include - -#include "base/callback.h" -#include "base/memory/ref_counted.h" - -namespace chromeos { - -class BluetoothDevice; - -struct BluetoothOutOfBandPairingData; - -// BluetoothAdapter represents a local Bluetooth adapter which may be used to -// interact with remote Bluetooth devices. As well as providing support for -// determining whether an adapter is present, and whether the radio is powered, -// this class also provides support for obtaining the list of remote devices -// known to the adapter, discovering new devices, and providing notification of -// updates to device information. -class BluetoothAdapter : public base::RefCounted { - public: - // Interface for observing changes from bluetooth adapters. - class Observer { - public: - virtual ~Observer() {} - - // Called when the presence of the adapter |adapter| changes, when - // |present| is true the adapter is now present, false means the adapter - // has been removed from the system. - virtual void AdapterPresentChanged(BluetoothAdapter* adapter, - bool present) {} - - // Called when the radio power state of the adapter |adapter| changes, - // when |powered| is true the adapter radio is powered, false means the - // adapter radio is off. - virtual void AdapterPoweredChanged(BluetoothAdapter* adapter, - bool powered) {} - - // Called when the discovering state of the adapter |adapter| changes, - // when |discovering| is true the adapter is seeking new devices, false - // means it is not. Note that device discovery involves both states when - // the adapter is seeking new devices and states when it is not because - // it is interrogating the devices it found. - virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter, - bool discovering) {} - - // Called when a new device |device| is added to the adapter |adapter|, - // either because it has been discovered or a connection made. |device| - // should not be cached, instead copy its address. - virtual void DeviceAdded(BluetoothAdapter* adapter, - BluetoothDevice* device) {} - - // Called when properties of the device |device| known to the adapter - // |adapter| change. |device| should not be cached, instead copy its - // address. - virtual void DeviceChanged(BluetoothAdapter* adapter, - BluetoothDevice* device) {} - - // Called when the device |device| is removed from the adapter |adapter|, - // either as a result of a discovered device being lost between discovering - // phases or pairing information deleted. |device| should not be cached. - virtual void DeviceRemoved(BluetoothAdapter* adapter, - BluetoothDevice* device) {} - }; - - // 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. - typedef base::Callback ErrorCallback; - - // The BluetoothOutOfBandPairingDataCallback is used to return - // BluetoothOutOfBandPairingData to the caller. - typedef base::Callback - BluetoothOutOfBandPairingDataCallback; - - // Adds and removes observers for events on this bluetooth adapter, - // if monitoring multiple adapters check the |adapter| parameter of - // observer methods to determine which adapter is issuing the event. - virtual void AddObserver(BluetoothAdapter::Observer* observer) = 0; - virtual void RemoveObserver( - BluetoothAdapter::Observer* observer) = 0; - - // The address of this adapter. The address format is "XX:XX:XX:XX:XX:XX", - // where each XX is a hexadecimal number. - virtual const std::string& address() const; - - // The name of the adapter. - virtual const std::string& name() const; - - // Indicates whether the adapter is actually present on the system, for - // the default adapter this indicates whether any adapter is present. An - // adapter is only considered present if the address has been obtained. - virtual bool IsPresent() const = 0; - - // Indicates whether the adapter radio is powered. - virtual bool IsPowered() const = 0; - - // Requests a change to the adapter radio power, setting |powered| to true - // will turn on the radio and false will turn it off. On success, callback - // will be called. On failure, |error_callback| will be called. - virtual void SetPowered(bool powered, - const base::Closure& callback, - const ErrorCallback& error_callback) = 0; - - // Indicates whether the adapter is currently discovering new devices, - // note that a typical discovery process has phases of this being true - // followed by phases of being false when the adapter interrogates the - // devices found. - virtual bool IsDiscovering() const = 0; - - // Requests that the adapter either begin discovering new devices when - // |discovering| is true, or cease any discovery when false. On success, - // callback will be called. On failure, |error_callback| will be called. - virtual void SetDiscovering(bool discovering, - const base::Closure& callback, - const ErrorCallback& error_callback) = 0; - - // Requests the list of devices from the adapter, all are returned - // including those currently connected and those paired. Use the - // returned device pointers to determine which they are. - typedef std::vector DeviceList; - virtual DeviceList GetDevices(); - typedef std::vector ConstDeviceList; - virtual ConstDeviceList GetDevices() const = 0; - - // Returns a pointer to the device with the given address |address| or - // NULL if no such device is known. - virtual BluetoothDevice* GetDevice(const std::string& address) = 0; - virtual const BluetoothDevice* GetDevice( - const std::string& address) const = 0; - - // Requests the local Out Of Band pairing data. - virtual void ReadLocalOutOfBandPairingData( - const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback) = 0; - - protected: - friend class base::RefCounted; - virtual ~BluetoothAdapter(); - - // Address of the adapter. - std::string address_; - - // Name of the adapter. - std::string name_; -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc deleted file mode 100644 index d71dae4..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc +++ /dev/null @@ -1,535 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" - -#include - -#include "base/bind.h" -#include "base/logging.h" -#include "base/stl_util.h" -#include "base/values.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h" -#include "chromeos/dbus/bluetooth_adapter_client.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_manager_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "dbus/object_path.h" - -namespace chromeos { - -BluetoothAdapterChromeOs::BluetoothAdapterChromeOs() : track_default_(false), - powered_(false), - discovering_(false), - weak_ptr_factory_(this) { - DBusThreadManager::Get()->GetBluetoothManagerClient()-> - AddObserver(this); - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - AddObserver(this); - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - AddObserver(this); -} - -BluetoothAdapterChromeOs::~BluetoothAdapterChromeOs() { - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - RemoveObserver(this); - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - RemoveObserver(this); - DBusThreadManager::Get()->GetBluetoothManagerClient()-> - RemoveObserver(this); - - STLDeleteValues(&devices_); -} - -void BluetoothAdapterChromeOs::AddObserver( - BluetoothAdapter::Observer* observer) { - DCHECK(observer); - observers_.AddObserver(observer); -} - -void BluetoothAdapterChromeOs::RemoveObserver( - BluetoothAdapter::Observer* observer) { - DCHECK(observer); - observers_.RemoveObserver(observer); -} - -bool BluetoothAdapterChromeOs::IsPresent() const { - return !object_path_.value().empty() && !address_.empty(); -} - -bool BluetoothAdapterChromeOs::IsPowered() const { - return powered_; -} - -void BluetoothAdapterChromeOs::SetPowered(bool powered, - const base::Closure& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - GetProperties(object_path_)->powered.Set( - powered, - base::Bind(&BluetoothAdapterChromeOs::OnSetPowered, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -bool BluetoothAdapterChromeOs::IsDiscovering() const { - return discovering_; -} - -void BluetoothAdapterChromeOs::SetDiscovering( - bool discovering, - const base::Closure& callback, - const ErrorCallback& error_callback) { - if (discovering) { - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - StartDiscovery(object_path_, - base::Bind(&BluetoothAdapterChromeOs::OnStartDiscovery, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); - } else { - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - StopDiscovery(object_path_, - base::Bind(&BluetoothAdapterChromeOs::OnStopDiscovery, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); - } -} - -BluetoothAdapter::ConstDeviceList BluetoothAdapterChromeOs::GetDevices() const { - ConstDeviceList devices; - for (DevicesMap::const_iterator iter = devices_.begin(); - iter != devices_.end(); - ++iter) - devices.push_back(iter->second); - - return devices; -} - -BluetoothDevice* BluetoothAdapterChromeOs::GetDevice( - const std::string& address) { - return const_cast( - const_cast(this)->GetDevice(address)); -} - -const BluetoothDevice* BluetoothAdapterChromeOs::GetDevice( - const std::string& address) const { - DevicesMap::const_iterator iter = devices_.find(address); - if (iter != devices_.end()) - return iter->second; - - return NULL; -} - -void BluetoothAdapterChromeOs::ReadLocalOutOfBandPairingData( - const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> - ReadLocalData(object_path_, - base::Bind(&BluetoothAdapterChromeOs::OnReadLocalData, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -void BluetoothAdapterChromeOs::TrackDefaultAdapter() { - DVLOG(1) << "Tracking default adapter"; - track_default_ = true; - DBusThreadManager::Get()->GetBluetoothManagerClient()-> - DefaultAdapter(base::Bind(&BluetoothAdapterChromeOs::AdapterCallback, - weak_ptr_factory_.GetWeakPtr())); -} - -void BluetoothAdapterChromeOs::FindAdapter(const std::string& address) { - DVLOG(1) << "Using adapter " << address; - track_default_ = false; - DBusThreadManager::Get()->GetBluetoothManagerClient()-> - FindAdapter(address, - base::Bind(&BluetoothAdapterChromeOs::AdapterCallback, - weak_ptr_factory_.GetWeakPtr())); -} - -void BluetoothAdapterChromeOs::AdapterCallback( - const dbus::ObjectPath& adapter_path, - bool success) { - if (success) { - ChangeAdapter(adapter_path); - } else if (!object_path_.value().empty()) { - RemoveAdapter(); - } -} - -void BluetoothAdapterChromeOs::DefaultAdapterChanged( - const dbus::ObjectPath& adapter_path) { - if (track_default_) - ChangeAdapter(adapter_path); -} - -void BluetoothAdapterChromeOs::AdapterRemoved( - const dbus::ObjectPath& adapter_path) { - if (adapter_path == object_path_) - RemoveAdapter(); -} - -void BluetoothAdapterChromeOs::ChangeAdapter( - const dbus::ObjectPath& adapter_path) { - if (object_path_.value().empty()) { - DVLOG(1) << "Adapter path initialized to " << adapter_path.value(); - } else if (object_path_.value() != adapter_path.value()) { - DVLOG(1) << "Adapter path changed from " << object_path_.value() - << " to " << adapter_path.value(); - - RemoveAdapter(); - } else { - DVLOG(1) << "Adapter address updated"; - } - - object_path_ = adapter_path; - - // Update properties to their new values. - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - GetProperties(object_path_); - - address_ = properties->address.value(); - name_ = properties->name.value(); - - // Delay announcing a new adapter until we have an address. - if (address_.empty()) { - DVLOG(1) << "Adapter address not yet known"; - return; - } - - PoweredChanged(properties->powered.value()); - DiscoveringChanged(properties->discovering.value()); - DevicesChanged(properties->devices.value()); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - AdapterPresentChanged(this, true)); -} - -void BluetoothAdapterChromeOs::RemoveAdapter() { - const bool adapter_was_present = IsPresent(); - - DVLOG(1) << "Adapter lost."; - PoweredChanged(false); - DiscoveringChanged(false); - ClearDevices(); - - object_path_ = dbus::ObjectPath(""); - address_.clear(); - name_.clear(); - - if (adapter_was_present) - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - AdapterPresentChanged(this, false)); -} - -void BluetoothAdapterChromeOs::OnSetPowered(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success) { - if (success) - callback.Run(); - else - error_callback.Run(); -} - -void BluetoothAdapterChromeOs::PoweredChanged(bool powered) { - if (powered == powered_) - return; - - powered_ = powered; - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - AdapterPoweredChanged(this, powered_)); -} - -void BluetoothAdapterChromeOs::OnStartDiscovery( - const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, - bool success) { - if (success) { - DVLOG(1) << object_path_.value() << ": started discovery."; - - // Clear devices found in previous discovery attempts - ClearDiscoveredDevices(); - callback.Run(); - } else { - // TODO(keybuk): in future, don't run the callback if the error was just - // that we were already discovering. - error_callback.Run(); - } -} - -void BluetoothAdapterChromeOs::OnStopDiscovery( - const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, - bool success) { - if (success) { - DVLOG(1) << object_path_.value() << ": stopped discovery."; - callback.Run(); - // Leave found devices available for perusing. - } else { - // TODO(keybuk): in future, don't run the callback if the error was just - // that we weren't discovering. - error_callback.Run(); - } -} - -void BluetoothAdapterChromeOs::DiscoveringChanged(bool discovering) { - if (discovering == discovering_) - return; - - discovering_ = discovering; - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - AdapterDiscoveringChanged(this, discovering_)); -} - -void BluetoothAdapterChromeOs::OnReadLocalData( - const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback, - const BluetoothOutOfBandPairingData& data, - bool success) { - if (success) - callback.Run(data); - else - error_callback.Run(); -} - -void BluetoothAdapterChromeOs::AdapterPropertyChanged( - const dbus::ObjectPath& adapter_path, - const std::string& property_name) { - if (adapter_path != object_path_) - return; - - BluetoothAdapterClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - GetProperties(object_path_); - - if (property_name == properties->address.name()) { - ChangeAdapter(object_path_); - - } else if (!address_.empty()) { - if (property_name == properties->powered.name()) { - PoweredChanged(properties->powered.value()); - - } else if (property_name == properties->discovering.name()) { - DiscoveringChanged(properties->discovering.value()); - - } else if (property_name == properties->devices.name()) { - DevicesChanged(properties->devices.value()); - - } else if (property_name == properties->name.name()) { - name_ = properties->name.value(); - - } - } -} - -void BluetoothAdapterChromeOs::DevicePropertyChanged( - const dbus::ObjectPath& device_path, - const std::string& property_name) { - UpdateDevice(device_path); -} - -void BluetoothAdapterChromeOs::UpdateDevice( - const dbus::ObjectPath& device_path) { - BluetoothDeviceClient::Properties* properties = - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - GetProperties(device_path); - - // When we first see a device, we may not know the address yet and need to - // wait for the DevicePropertyChanged signal before adding the device. - const std::string address = properties->address.value(); - if (address.empty()) - return; - - // The device may be already known to us, either because this is an update - // to properties, or the device going from discovered to connected and - // pairing gaining an object path in the process. In any case, we want - // to update the existing object, not create a new one. - DevicesMap::iterator iter = devices_.find(address); - BluetoothDeviceChromeOs* device; - const bool update_device = (iter != devices_.end()); - if (update_device) { - device = iter->second; - } else { - device = BluetoothDeviceChromeOs::Create(this); - devices_[address] = device; - } - - const bool was_paired = device->IsPaired(); - if (!was_paired) { - DVLOG(1) << "Assigned object path " << device_path.value() << " to device " - << address; - device->SetObjectPath(device_path); - } - device->Update(properties, true); - - if (update_device) { - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceChanged(this, device)); - } else { - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceAdded(this, device)); - } -} - -void BluetoothAdapterChromeOs::ClearDevices() { - DevicesMap replace; - devices_.swap(replace); - for (DevicesMap::iterator iter = replace.begin(); - iter != replace.end(); ++iter) { - BluetoothDeviceChromeOs* device = iter->second; - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceRemoved(this, device)); - - delete device; - } -} - -void BluetoothAdapterChromeOs::DeviceCreated( - const dbus::ObjectPath& adapter_path, - const dbus::ObjectPath& device_path) { - if (adapter_path != object_path_) - return; - - UpdateDevice(device_path); -} - -void BluetoothAdapterChromeOs::DeviceRemoved( - const dbus::ObjectPath& adapter_path, - const dbus::ObjectPath& device_path) { - if (adapter_path != object_path_) - return; - - DevicesMap::iterator iter = devices_.begin(); - while (iter != devices_.end()) { - BluetoothDeviceChromeOs* device = iter->second; - DevicesMap::iterator temp = iter; - ++iter; - - if (device->object_path_ != device_path) - continue; - - // 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()) { - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceRemoved(this, device)); - - DVLOG(1) << "Removed device " << device->address(); - - delete device; - devices_.erase(temp); - } else { - DVLOG(1) << "Removed object path from device " << device->address(); - device->RemoveObjectPath(); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceChanged(this, device)); - } - } -} - -void BluetoothAdapterChromeOs::DevicesChanged( - const std::vector& devices) { - for (std::vector::const_iterator iter = - devices.begin(); iter != devices.end(); ++iter) - UpdateDevice(*iter); -} - -void BluetoothAdapterChromeOs::ClearDiscoveredDevices() { - DevicesMap::iterator iter = devices_.begin(); - while (iter != devices_.end()) { - BluetoothDeviceChromeOs* device = iter->second; - DevicesMap::iterator temp = iter; - ++iter; - - if (!device->IsPaired()) { - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceRemoved(this, device)); - - delete device; - devices_.erase(temp); - } - } -} - -void BluetoothAdapterChromeOs::DeviceFound( - const dbus::ObjectPath& adapter_path, - const std::string& address, - const BluetoothDeviceClient::Properties& properties) { - if (adapter_path != object_path_) - return; - - // DeviceFound can also be called to indicate that a device we've - // paired with is now visible to the adapter during discovery, in which - // case we want to update the existing object, not create a new one. - BluetoothDeviceChromeOs* device; - DevicesMap::iterator iter = devices_.find(address); - const bool update_device = (iter != devices_.end()); - if (update_device) { - device = iter->second; - } else { - device = BluetoothDeviceChromeOs::Create(this); - devices_[address] = device; - } - - DVLOG(1) << "Device " << address << " is visible to the adapter"; - device->SetVisible(true); - device->Update(&properties, false); - - if (update_device) { - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceChanged(this, device)); - } else { - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceAdded(this, device)); - } -} - -void BluetoothAdapterChromeOs::DeviceDisappeared( - const dbus::ObjectPath& adapter_path, - const std::string& address) { - if (adapter_path != object_path_) - return; - - DevicesMap::iterator iter = devices_.find(address); - if (iter == devices_.end()) - return; - - BluetoothDeviceChromeOs* device = iter->second; - - // 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()) { - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceRemoved(this, device)); - - DVLOG(1) << "Discovered device " << device->address() - << " is no longer visible to the adapter"; - - delete device; - devices_.erase(iter); - } else { - DVLOG(1) << "Paired device " << device->address() - << " is no longer visible to the adapter"; - device->SetVisible(false); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - DeviceChanged(this, device)); - } -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h deleted file mode 100644 index 2a0db65..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ - -#include -#include -#include - -#include "base/basictypes.h" -#include "base/callback.h" -#include "base/observer_list.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chromeos/dbus/bluetooth_adapter_client.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_manager_client.h" -#include "dbus/object_path.h" - -namespace chromeos { - -class BluetoothDeviceChromeOs; - -struct BluetoothOutOfBandPairingData; - -// The BluetoothAdapterChromeOs class is an implementation of BluetoothAdapter -// for Chrome OS platform. -class BluetoothAdapterChromeOs : public BluetoothAdapter, - public BluetoothManagerClient::Observer, - public BluetoothAdapterClient::Observer, - public BluetoothDeviceClient::Observer { - public: - // BluetoothAdapter override - virtual void AddObserver(BluetoothAdapter::Observer* observer) OVERRIDE; - virtual void RemoveObserver(BluetoothAdapter::Observer* observer) OVERRIDE; - virtual bool IsPresent() const OVERRIDE; - virtual bool IsPowered() const OVERRIDE; - virtual void SetPowered( - bool powered, - const base::Closure& callback, - const ErrorCallback& error_callback) OVERRIDE; - virtual bool IsDiscovering() const OVERRIDE; - virtual void SetDiscovering( - bool discovering, - const base::Closure& callback, - const ErrorCallback& error_callback) OVERRIDE; - virtual ConstDeviceList GetDevices() const OVERRIDE; - virtual BluetoothDevice* GetDevice(const std::string& address) OVERRIDE; - virtual const BluetoothDevice* GetDevice( - const std::string& address) const OVERRIDE; - virtual void ReadLocalOutOfBandPairingData( - const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback) OVERRIDE; - - private: - friend class BluetoothAdapterFactory; - friend class BluetoothDeviceChromeOs; - friend class MockBluetoothAdapter; - - BluetoothAdapterChromeOs(); - virtual ~BluetoothAdapterChromeOs(); - - // Obtains the default adapter object path from the Bluetooth Daemon - // and tracks future changes to it. - void TrackDefaultAdapter(); - - // Obtains the object paht for the adapter named by |address| from the - // Bluetooth Daemon. - void FindAdapter(const std::string& address); - - // Called by dbus:: in response to the method call sent by both - // DefaultAdapter() and FindAdapter(), |object_path| will contain the - // dbus object path of the requested adapter when |success| is true. - void AdapterCallback(const dbus::ObjectPath& adapter_path, bool success); - - // BluetoothManagerClient::Observer override. - // - // Called when the default local bluetooth adapter changes. - // |object_path| is the dbus object path of the new default adapter. - // Not called if all adapters are removed. - virtual void DefaultAdapterChanged(const dbus::ObjectPath& adapter_path) - OVERRIDE; - - // BluetoothManagerClient::Observer override. - // - // Called when a local bluetooth adapter is removed. - // |object_path| is the dbus object path of the adapter. - virtual void AdapterRemoved(const dbus::ObjectPath& adapter_path) OVERRIDE; - - // Changes the tracked adapter to the dbus object path |adapter_path|, - // clearing information from the previously tracked adapter and updating - // to the new adapter. - void ChangeAdapter(const dbus::ObjectPath& adapter_path); - - // Clears the tracked adapter information. - void RemoveAdapter(); - - // Called by dbus:: in response to the method call send by SetPowered(). - // |callback| and |error_callback| are the callbacks passed to SetPowered(). - void OnSetPowered(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success); - - // Updates the tracked state of the adapter's radio power to |powered| - // and notifies observers. Called on receipt of a property changed signal, - // and directly using values obtained from properties. - void PoweredChanged(bool powered); - - // Called by dbus:: in response to the method calls send by SetDiscovering(). - // |callback| and |error_callback| are the callbacks passed to - // SetDiscovering(). - void OnStartDiscovery(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, - bool success); - void OnStopDiscovery(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, - bool success); - - // Updates the tracked state of the adapter's discovering state to - // |discovering| and notifies observers. Called on receipt of a property - // changed signal, and directly using values obtained from properties. - void DiscoveringChanged(bool discovering); - - // Called by dbus:: in response to the ReadLocalData method call. - void OnReadLocalData(const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback, - const BluetoothOutOfBandPairingData& data, - bool success); - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |adapter_path| has a - // change in value of the property named |property_name|. - virtual void AdapterPropertyChanged(const dbus::ObjectPath& adapter_path, - const std::string& property_name) - OVERRIDE; - - // BluetoothDeviceClient::Observer override. - // - // Called when the device with object path |device_path| has a - // change in value of the property named |property_name|. - virtual void DevicePropertyChanged(const dbus::ObjectPath& device_path, - const std::string& property_name) - OVERRIDE; - - // Updates information on the device with object path |device_path|, - // adding it to the |devices_| map if not already present. - void UpdateDevice(const dbus::ObjectPath& device_path); - - // Clears the |devices_| list, notifying obsevers of the device removal. - void ClearDevices(); - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |object_path| has a - // new known device with object path |object_path|. - virtual void DeviceCreated(const dbus::ObjectPath& adapter_path, - const dbus::ObjectPath& device_path) OVERRIDE; - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |object_path| removes - // the known device with object path |object_path|. - virtual void DeviceRemoved(const dbus::ObjectPath& adapter_path, - const dbus::ObjectPath& device_path) OVERRIDE; - - // Updates the adapter |devices_| list, adding or updating devices using - // the object paths in the|devices| list. This doesn't remove devices, - // relying instead on the DeviceRemoved() signal for that. Called on - // receipt of a property changed signal, and directly using values obtained - // from properties. - void DevicesChanged(const std::vector& devices); - - // Clears discovered devices from the |devices_| list, notifying - // observers, and leaving only those devices with a dbus object path. - void ClearDiscoveredDevices(); - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |object_path| discovers - // a new remote device with address |address| and properties - // |properties|, there is no device object path until connected. - // - // |properties| supports only value() calls, not Get() or Set(), and - // should be copied if needed. - virtual void DeviceFound( - const dbus::ObjectPath& adapter_path, - const std::string& address, - const BluetoothDeviceClient::Properties& properties) OVERRIDE; - - // BluetoothAdapterClient::Observer override. - // - // Called when the adapter with object path |object_path| can no - // longer communicate with the discovered removed device with - // address |address|. - virtual void DeviceDisappeared(const dbus::ObjectPath& object_path, - const std::string& address) OVERRIDE; - - // List of observers interested in event notifications from us. - ObserverList observers_; - - // Object path of adapter for this instance, this is fixed at creation time - // unless |track_default_| is true in which case we update it to always - // point at the default adapter. - bool track_default_; - dbus::ObjectPath object_path_; - - // Tracked adapter state, cached locally so we only send change notifications - // to observers on a genuine change. - bool powered_; - bool discovering_; - - // Devices paired with, connected to, discovered by, or visible to the - // adapter. The key is the Bluetooth address of the device and the value - // is the BluetoothDeviceChromeOs object whose lifetime is managed by the - // adapter instance. - typedef std::map DevicesMap; - DevicesMap devices_; - - // Note: This should remain the last member so it'll be destroyed and - // invalidate its weak pointers before any other members are destroyed. - base::WeakPtrFactory weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterChromeOs); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos_unittest.cc b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos_unittest.cc deleted file mode 100644 index d909559..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos_unittest.cc +++ /dev/null @@ -1,1553 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" -#include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h" -#include "chromeos/dbus/mock_bluetooth_adapter_client.h" -#include "chromeos/dbus/mock_bluetooth_manager_client.h" -#include "chromeos/dbus/mock_dbus_thread_manager.h" -#include "dbus/object_path.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::_; -using ::testing::InSequence; -using ::testing::Return; -using ::testing::SaveArg; - -namespace chromeos { - -class BluetoothAdapterChromeOsTest : public testing::Test { - public: - virtual void SetUp() { - MockDBusThreadManager* mock_dbus_thread_manager = new MockDBusThreadManager; - - EXPECT_CALL(*mock_dbus_thread_manager, GetSystemBus()) - .WillRepeatedly(Return(reinterpret_cast(NULL))); - DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager); - - mock_manager_client_ = - mock_dbus_thread_manager->mock_bluetooth_manager_client(); - mock_adapter_client_ = - mock_dbus_thread_manager->mock_bluetooth_adapter_client(); - - set_callback_called_ = false; - error_callback_called_ = false; - } - - virtual void TearDown() { - DBusThreadManager::Shutdown(); - } - - void SetCallback() { - set_callback_called_ = true; - } - - void ErrorCallback() { - error_callback_called_ = true; - } - - protected: - MockBluetoothManagerClient* mock_manager_client_; - MockBluetoothAdapterClient* mock_adapter_client_; - - bool set_callback_called_; - bool error_callback_called_; -}; - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterNotPresent) { - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; make out it failed. - // BluetoothAdapter::Observer::AdapterPresentChanged must not be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) - .Times(0); - - adapter_callback.Run(dbus::ObjectPath(""), false); - - // Adapter should not be present. - EXPECT_FALSE(adapter->IsPresent()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterWithAddress) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - // BluetoothAdapter::Observer::AdapterPresentChanged will be called to - // indicate the adapter is now present. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - adapter_callback.Run(adapter_path, true); - - // Adapter should be present with the given address. - EXPECT_TRUE(adapter->IsPresent()); - EXPECT_EQ(adapter_address, adapter->address()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterWithoutAddress) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - // BluetoothAdapter::Observer::AdapterPresentChanged must not be called - // yet. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) - .Times(0); - - adapter_callback.Run(adapter_path, true); - - // Adapter should not be present yet. - EXPECT_FALSE(adapter->IsPresent()); - - // Tell the adapter the address now; - // BluetoothAdapter::Observer::AdapterPresentChanged now must be called. - adapter_properties.address.ReplaceValue(adapter_address); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.address.name()); - - // Adapter should be present with the given address. - EXPECT_TRUE(adapter->IsPresent()); - EXPECT_EQ(adapter_address, adapter->address()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterBecomesPresentWithAddress) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; make out it failed. - adapter_callback.Run(dbus::ObjectPath(""), false); - - // Tell the adapter the default adapter changed; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - // BluetoothAdapter::Observer::AdapterPresentChanged must be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->DefaultAdapterChanged(adapter_path); - - // Adapter should be present with the new address. - EXPECT_TRUE(adapter->IsPresent()); - EXPECT_EQ(adapter_address, adapter->address()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterReplacedWithAddress) { - const dbus::ObjectPath initial_adapter_path("/fake/hci0"); - const dbus::ObjectPath new_adapter_path("/fake/hci1"); - const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; - const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties initial_adapter_properties; - initial_adapter_properties.address.ReplaceValue(initial_adapter_address); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) - .WillRepeatedly(Return(&initial_adapter_properties)); - - adapter_callback.Run(initial_adapter_path, true); - - // Tell the adapter the default adapter changed; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties new_adapter_properties; - new_adapter_properties.address.ReplaceValue(new_adapter_address); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) - .WillRepeatedly(Return(&new_adapter_properties)); - - // BluetoothAdapter::Observer::AdapterPresentChanged must be called once - // with false to indicate the old adapter being removed and once with true - // to announce the new adapter. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) - .Times(1); - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->DefaultAdapterChanged(new_adapter_path); - - // Adapter should be present with the new address. - EXPECT_TRUE(adapter->IsPresent()); - EXPECT_EQ(new_adapter_address, adapter->address()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterBecomesPresentWithoutAddress) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; make out it failed. - adapter_callback.Run(dbus::ObjectPath(""), false); - - // Tell the adapter the default adapter changed; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - // BluetoothAdapter::Observer::AdapterPresentChanged must not be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) - .Times(0); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->DefaultAdapterChanged(adapter_path); - - // Adapter should not be present yet. - EXPECT_FALSE(adapter->IsPresent()); - - // Tell the adapter the address now; - // BluetoothAdapter::Observer::AdapterPresentChanged now must be called. - adapter_properties.address.ReplaceValue(adapter_address); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.address.name()); - - // Adapter should be present with the new address. - EXPECT_TRUE(adapter->IsPresent()); - EXPECT_EQ(adapter_address, adapter->address()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterReplacedWithoutAddress) { - const dbus::ObjectPath initial_adapter_path("/fake/hci0"); - const dbus::ObjectPath new_adapter_path("/fake/hci1"); - const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; - const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties initial_adapter_properties; - initial_adapter_properties.address.ReplaceValue(initial_adapter_address); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) - .WillRepeatedly(Return(&initial_adapter_properties)); - - adapter_callback.Run(initial_adapter_path, true); - - // Tell the adapter the default adapter changed; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties new_adapter_properties; - - EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) - .WillRepeatedly(Return(&new_adapter_properties)); - - // BluetoothAdapter::Observer::AdapterPresentChanged must be called to - // indicate the adapter has gone away. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->DefaultAdapterChanged(new_adapter_path); - - // Adapter should be now marked not present. - EXPECT_FALSE(adapter->IsPresent()); - - // Tell the adapter the address now; - // BluetoothAdapter::Observer::AdapterPresentChanged now must be called. - new_adapter_properties.address.ReplaceValue(new_adapter_address); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(new_adapter_path, - new_adapter_properties.address.name()); - - // Adapter should be present with the new address. - EXPECT_TRUE(adapter->IsPresent()); - EXPECT_EQ(new_adapter_address, adapter->address()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterRemoved) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Report that the adapter has been removed; - // BluetoothAdapter::Observer::AdapterPresentChanged will be called to - // indicate the adapter is no longer present. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterRemoved(adapter_path); - - // Adapter should be no longer present. - EXPECT_FALSE(adapter->IsPresent()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterWithoutAddressRemoved) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Report that the adapter has been removed; - // BluetoothAdapter::Observer::AdapterPresentChanged must not be called - // since we never should have announced it in the first place. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) - .Times(0); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterRemoved(adapter_path); - - // Adapter should be still no longer present. - EXPECT_FALSE(adapter->IsPresent()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterPoweredPropertyInitiallyFalse) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.powered.ReplaceValue(false); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Adapter should have the correct property value. - EXPECT_FALSE(adapter->IsPowered()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterPoweredPropertyInitiallyTrue) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.powered.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - // BluetoothAdapter::Observer::AdapterPoweredChanged will be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) - .Times(1); - - adapter_callback.Run(adapter_path, true); - - // Adapter should have the correct property value. - EXPECT_TRUE(adapter->IsPowered()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterPoweredPropertyInitiallyTrueWithoutAddress) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set but BluetoothAdapter::Observer::AdapterPoweredChanged - // should not yet be called. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.powered.ReplaceValue(true); - - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) - .Times(0); - - adapter_callback.Run(adapter_path, true); - - // Adapter should not yet have the property value. - EXPECT_FALSE(adapter->IsPowered()); - - // Tell the adapter the address now, - // BluetoothAdapter::Observer::AdapterPresentChanged and - // BluetoothAdapter::Observer::AdapterPoweredChanged now must be called. - adapter_properties.address.ReplaceValue(adapter_address); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.address.name()); - - // Adapter should have the correct property value. - EXPECT_TRUE(adapter->IsPowered()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterPoweredPropertyChanged) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.powered.ReplaceValue(false); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Adapter should have the correct property value. - EXPECT_FALSE(adapter->IsPowered()); - - // Report that the property has been changed; - // BluetoothAdapter::Observer::AdapterPoweredChanged will be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) - .Times(1); - - adapter_properties.powered.ReplaceValue(true); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.powered.name()); - - // Adapter should have the new property values. - EXPECT_TRUE(adapter->IsPowered()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterPoweredPropertyUnchanged) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.powered.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Adapter should have the correct property value. - EXPECT_TRUE(adapter->IsPowered()); - - // Report that the property has been changed, but don't change the value; - // BluetoothAdapter::Observer::AdapterPoweredChanged should not be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) - .Times(0); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.powered.name()); - - // Adapter should still have the same property values. - EXPECT_TRUE(adapter->IsPowered()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterPoweredPropertyChangedWithoutAddress) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set but BluetoothAdapter::Observer::AdapterPoweredChanged - // should not yet be called. - MockBluetoothAdapterClient::Properties adapter_properties; - - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) - .Times(0); - - adapter_callback.Run(adapter_path, true); - - // Tell the adapter that its powered property changed, the observer - // method should still not be called because there is no address for - // the adapter so it is not present. - adapter_properties.powered.ReplaceValue(true); - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) - .Times(0); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.powered.name()); - - // Adapter should not yet have the property value. - EXPECT_FALSE(adapter->IsPowered()); - - // Tell the adapter the address now, - // BluetoothAdapter::Observer::AdapterPresentChanged and - // BluetoothAdapter::Observer::AdapterPoweredChanged now must be called. - adapter_properties.address.ReplaceValue(adapter_address); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) - .Times(1); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.address.name()); - - // Adapter should now have the correct property value. - EXPECT_TRUE(adapter->IsPowered()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterPoweredPropertyResetOnReplace) { - const dbus::ObjectPath initial_adapter_path("/fake/hci0"); - const dbus::ObjectPath new_adapter_path("/fake/hci1"); - const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; - const std::string new_adapter_address = "00:C0:11:CO:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties initial_adapter_properties; - initial_adapter_properties.address.ReplaceValue(initial_adapter_address); - initial_adapter_properties.powered.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) - .WillRepeatedly(Return(&initial_adapter_properties)); - - adapter_callback.Run(initial_adapter_path, true); - - // Tell the adapter the default adapter changed; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties new_adapter_properties; - new_adapter_properties.address.ReplaceValue(new_adapter_address); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) - .WillRepeatedly(Return(&new_adapter_properties)); - - // BluetoothAdapter::Observer::AdapterPoweredChanged will be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - { - InSequence s; - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) - .Times(1); - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - } - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), false)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->DefaultAdapterChanged(new_adapter_path); - - // Adapter should have the new property value. - EXPECT_FALSE(adapter->IsPowered()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterPoweredPropertyResetOnReplaceWhenTrue) { - const dbus::ObjectPath initial_adapter_path("/fake/hci0"); - const dbus::ObjectPath new_adapter_path("/fake/hci1"); - const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; - const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties initial_adapter_properties; - initial_adapter_properties.address.ReplaceValue(initial_adapter_address); - initial_adapter_properties.powered.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) - .WillRepeatedly(Return(&initial_adapter_properties)); - - adapter_callback.Run(initial_adapter_path, true); - - // Tell the adapter the default adapter changed; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties new_adapter_properties; - new_adapter_properties.address.ReplaceValue(new_adapter_address); - new_adapter_properties.powered.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) - .WillRepeatedly(Return(&new_adapter_properties)); - - // BluetoothAdapter::Observer::AdapterPoweredChanged will be called once - // to set the value to false for the previous adapter and once to set the - // value to true for the new adapter. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - { - InSequence s; - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) - .Times(1); - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - } - - { - InSequence s; - - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), false)) - .Times(1); - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) - .Times(1); - } - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->DefaultAdapterChanged(new_adapter_path); - - // Adapter should have the new property value. - EXPECT_TRUE(adapter->IsPowered()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterPoweredPropertyResetOnRemove) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.powered.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Report that the adapter has been removed; - // BluetoothAdapter::Observer::AdapterPoweredChanged will be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) - .Times(1); - EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), false)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterRemoved(adapter_path); - - // Adapter should have the new property value. - EXPECT_FALSE(adapter->IsPowered()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterSetPowered) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Request that the powered property be changed; - // MockBluetoothAdapterClient::Set should be called, passing the address - // of the powered property and a callback to receive the response. - dbus::PropertySet::SetCallback set_callback; - EXPECT_CALL(adapter_properties, Set(&adapter_properties.powered, _)) - .WillOnce(SaveArg<1>(&set_callback)); - - adapter->SetPowered(true, - base::Bind(&BluetoothAdapterChromeOsTest::SetCallback, - base::Unretained(this)), - base::Bind(&BluetoothAdapterChromeOsTest::ErrorCallback, - base::Unretained(this))); - - // Reply to the callback to indicate success, the set callback we provided - // should be called but the properties should not be refetched. - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .Times(0); - - set_callback.Run(true); - - EXPECT_TRUE(set_callback_called_); - EXPECT_FALSE(error_callback_called_); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterSetPoweredError) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Request that the powered property be changed; - // MockBluetoothAdapterClient::Set should be called, passing the address - // of the powered property and a callback to receive the response. - dbus::PropertySet::SetCallback set_callback; - EXPECT_CALL(adapter_properties, Set(&adapter_properties.powered, _)) - .WillOnce(SaveArg<1>(&set_callback)); - - adapter->SetPowered(true, - base::Bind(&BluetoothAdapterChromeOsTest::SetCallback, - base::Unretained(this)), - base::Bind(&BluetoothAdapterChromeOsTest::ErrorCallback, - base::Unretained(this))); - - // Reply to the callback to indicate failure, the error callback we provided - // should be called but the properties should not be refetched. - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .Times(0); - - set_callback.Run(false); - - EXPECT_FALSE(set_callback_called_); - EXPECT_TRUE(error_callback_called_); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterDiscoveringPropertyInitiallyFalse) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.discovering.ReplaceValue(false); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Adapter should have the correct property value. - EXPECT_FALSE(adapter->IsDiscovering()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterDiscoveringPropertyInitiallyTrue) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.discovering.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) - .Times(1); - - adapter_callback.Run(adapter_path, true); - - // Adapter should have the correct property value. - EXPECT_TRUE(adapter->IsDiscovering()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterDiscoveringPropertyInitiallyTrueWithoutAddress) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set but BluetoothAdapter::Observer::AdapterDiscoveringChanged - // should not yet be called. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.discovering.ReplaceValue(true); - - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) - .Times(0); - - adapter_callback.Run(adapter_path, true); - - // Adapter should not yet have the property value. - EXPECT_FALSE(adapter->IsDiscovering()); - - // Tell the adapter the address now, - // BluetoothAdapter::Observer::AdapterPresentChanged and - // BluetoothAdapter::Observer::AdapterDiscoveringChanged now must be called. - adapter_properties.address.ReplaceValue(adapter_address); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.address.name()); - - // Adapter should have the correct property value. - EXPECT_TRUE(adapter->IsDiscovering()); -} - -TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterDiscoveringPropertyChanged) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.discovering.ReplaceValue(false); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Adapter should have the correct property value. - EXPECT_FALSE(adapter->IsDiscovering()); - - // Report that the property has been changed; - // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) - .Times(1); - - adapter_properties.discovering.ReplaceValue(true); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.discovering.name()); - - // Adapter should have the new property values. - EXPECT_TRUE(adapter->IsDiscovering()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterDiscoveringPropertyUnchanged) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.discovering.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Adapter should have the correct property value. - EXPECT_TRUE(adapter->IsDiscovering()); - - // Report that the property has been changed, but don't change the value; - // BluetoothAdapter::Observer::AdapterDiscoveringChanged should not be - // called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) - .Times(0); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.discovering.name()); - - // Adapter should still have the same property values. - EXPECT_TRUE(adapter->IsDiscovering()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterDiscoveringPropertyChangedWithoutAddress) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set but BluetoothAdapter::Observer::AdapterDiscoveringChanged - // should not yet be called. - MockBluetoothAdapterClient::Properties adapter_properties; - - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) - .Times(0); - - adapter_callback.Run(adapter_path, true); - - // Tell the adapter that its discovering property changed, the observer - // method should still not be called because there is no address for - // the adapter so it is not present. - adapter_properties.discovering.ReplaceValue(true); - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) - .Times(0); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.discovering.name()); - - // Adapter should not yet have the property value. - EXPECT_FALSE(adapter->IsDiscovering()); - - // Tell the adapter the address now, - // BluetoothAdapter::Observer::AdapterPresentChanged and - // BluetoothAdapter::Observer::AdapterDiscoveringChanged now must be called. - adapter_properties.address.ReplaceValue(adapter_address); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) - .Times(1); - - static_cast(adapter_chromeos) - ->AdapterPropertyChanged(adapter_path, - adapter_properties.address.name()); - - // Adapter should now have the correct property value. - EXPECT_TRUE(adapter->IsDiscovering()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterDiscoveringPropertyResetOnReplace) { - const dbus::ObjectPath initial_adapter_path("/fake/hci0"); - const dbus::ObjectPath new_adapter_path("/fake/hci1"); - const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; - const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties initial_adapter_properties; - initial_adapter_properties.address.ReplaceValue(initial_adapter_address); - initial_adapter_properties.discovering.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) - .WillRepeatedly(Return(&initial_adapter_properties)); - - adapter_callback.Run(initial_adapter_path, true); - - // Tell the adapter the default adapter changed; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties new_adapter_properties; - new_adapter_properties.address.ReplaceValue(new_adapter_address); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) - .WillRepeatedly(Return(&new_adapter_properties)); - - // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - { - InSequence s; - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) - .Times(1); - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - } - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), false)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->DefaultAdapterChanged(new_adapter_path); - - // Adapter should have the new property value. - EXPECT_FALSE(adapter->IsDiscovering()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterDiscoveringPropertyResetOnReplaceWhenTrue) { - const dbus::ObjectPath initial_adapter_path("/fake/hci0"); - const dbus::ObjectPath new_adapter_path("/fake/hci1"); - const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; - const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties initial_adapter_properties; - initial_adapter_properties.address.ReplaceValue(initial_adapter_address); - initial_adapter_properties.discovering.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) - .WillRepeatedly(Return(&initial_adapter_properties)); - - adapter_callback.Run(initial_adapter_path, true); - - // Tell the adapter the default adapter changed; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties new_adapter_properties; - new_adapter_properties.address.ReplaceValue(new_adapter_address); - new_adapter_properties.discovering.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) - .WillRepeatedly(Return(&new_adapter_properties)); - - // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called once - // to set the value to false for the previous adapter and once to set the - // value to true for the new adapter. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - { - InSequence s; - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) - .Times(1); - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) - .Times(1); - } - - { - InSequence s; - - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), - false)) - .Times(1); - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), - true)) - .Times(1); - } - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->DefaultAdapterChanged(new_adapter_path); - - // Adapter should have the new property value. - EXPECT_TRUE(adapter->IsDiscovering()); -} - -TEST_F(BluetoothAdapterChromeOsTest, - DefaultAdapterDiscoveringPropertyResetOnRemove) { - const dbus::ObjectPath adapter_path("/fake/hci0"); - const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - scoped_refptr adapter = - BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address); - adapter_properties.discovering.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) - .WillRepeatedly(Return(&adapter_properties)); - - adapter_callback.Run(adapter_path, true); - - // Report that the adapter has been removed; - // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called. - MockBluetoothAdapter::Observer adapter_observer; - adapter->AddObserver(&adapter_observer); - - EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) - .Times(1); - EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), false)) - .Times(1); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter.get()); - - static_cast(adapter_chromeos) - ->AdapterRemoved(adapter_path); - - // Adapter should have the new property value. - EXPECT_FALSE(adapter->IsDiscovering()); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc deleted file mode 100644 index d1c1805..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" -#include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h" -#include "chromeos/dbus/mock_bluetooth_adapter_client.h" -#include "chromeos/dbus/mock_bluetooth_device_client.h" -#include "chromeos/dbus/mock_bluetooth_manager_client.h" -#include "chromeos/dbus/mock_dbus_thread_manager.h" -#include "dbus/object_path.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::_; -using ::testing::Mock; -using ::testing::Return; -using ::testing::SaveArg; - -namespace chromeos { - -class BluetoothAdapterDevicesChromeOsTest : public testing::Test { - public: - virtual void SetUp() { - MockDBusThreadManager* mock_dbus_thread_manager = new MockDBusThreadManager; - - EXPECT_CALL(*mock_dbus_thread_manager, GetSystemBus()) - .WillRepeatedly(Return(reinterpret_cast(NULL))); - DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager); - - mock_manager_client_ = - mock_dbus_thread_manager->mock_bluetooth_manager_client(); - mock_adapter_client_ = - mock_dbus_thread_manager->mock_bluetooth_adapter_client(); - mock_device_client_ = - mock_dbus_thread_manager->mock_bluetooth_device_client(); - - // Create the default adapter instance; - // BluetoothManagerClient::DefaultAdapter will be called once, passing - // a callback to obtain the adapter path. - BluetoothManagerClient::AdapterCallback adapter_callback; - EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) - .WillOnce(SaveArg<0>(&adapter_callback)); - - EXPECT_CALL(*mock_manager_client_, AddObserver(_)) - .Times(1); - EXPECT_CALL(*mock_adapter_client_, AddObserver(_)) - .Times(1); - - adapter_ = BluetoothAdapterFactory::DefaultAdapter(); - - // Call the adapter callback; - // BluetoothAdapterClient::GetProperties will be called once to obtain - // the property set. - MockBluetoothAdapterClient::Properties adapter_properties; - adapter_properties.address.ReplaceValue(adapter_address_); - adapter_properties.powered.ReplaceValue(true); - - EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path_)) - .WillRepeatedly(Return(&adapter_properties)); - - // Add an observer to the adapter; expect the usual set of changes to - // an adapter becoming present and then clear to clean up for the test. - adapter_->AddObserver(&adapter_observer_); - - EXPECT_CALL(adapter_observer_, AdapterPresentChanged(adapter_.get(), true)) - .Times(1); - EXPECT_CALL(adapter_observer_, AdapterPoweredChanged(adapter_.get(), true)) - .Times(1); - - adapter_callback.Run(adapter_path_, true); - - Mock::VerifyAndClearExpectations(mock_manager_client_); - Mock::VerifyAndClearExpectations(mock_adapter_client_); - Mock::VerifyAndClearExpectations(mock_device_client_); - Mock::VerifyAndClearExpectations(&adapter_observer_); - } - - virtual void TearDown() { - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter_.get()); - EXPECT_CALL(*mock_device_client_, RemoveObserver(adapter_chromeos)) - .Times(1); - EXPECT_CALL(*mock_adapter_client_, RemoveObserver(adapter_chromeos)) - .Times(1); - EXPECT_CALL(*mock_manager_client_, RemoveObserver(adapter_chromeos)) - .Times(1); - - adapter_ = NULL; - DBusThreadManager::Shutdown(); - } - - protected: - MockBluetoothManagerClient* mock_manager_client_; - MockBluetoothAdapterClient* mock_adapter_client_; - MockBluetoothDeviceClient* mock_device_client_; - - static const dbus::ObjectPath adapter_path_; - static const std::string adapter_address_; - scoped_refptr adapter_; - - MockBluetoothAdapter::Observer adapter_observer_; -}; - -const dbus::ObjectPath BluetoothAdapterDevicesChromeOsTest::adapter_path_( - "/fake/hci0"); -const std::string BluetoothAdapterDevicesChromeOsTest::adapter_address_ = - "CA:FE:4A:C0:FE:FE"; - -TEST_F(BluetoothAdapterDevicesChromeOsTest, DeviceRemovedAfterFound) { - const dbus::ObjectPath device_path("/fake/hci0/dev_ba_c0_11_00_00_01"); - const std::string device_address = "BA:C0:11:00:00:01"; - - MockBluetoothDeviceClient::Properties device_properties; - device_properties.address.ReplaceValue(device_address); - device_properties.name.ReplaceValue("Fake Keyboard"); - device_properties.bluetooth_class.ReplaceValue(0x2540); - - // Inform the adapter that the device has been found; - // BluetoothAdapterClient::Observer::DeviceAdded will be called, passing - // the device object. - BluetoothDevice* device; - EXPECT_CALL(adapter_observer_, DeviceAdded(adapter_.get(), _)) - .Times(1) - .WillOnce(SaveArg<1>(&device)); - - BluetoothAdapterChromeOs* adapter_chromeos = - static_cast(adapter_.get()); - static_cast(adapter_chromeos) - ->DeviceFound(adapter_path_, device_address, device_properties); - - // Now inform the adapter that the device has been added and assigned an - // object path; BluetoothDeviceClient::GetProperties will be called to - // obtain the property set; and - // BluetoothAdapterClient::Observer::DeviceChanged will be called passing - // the same device object as before. - EXPECT_CALL(*mock_device_client_, GetProperties(device_path)) - .WillRepeatedly(Return(&device_properties)); - - EXPECT_CALL(adapter_observer_, DeviceChanged(adapter_chromeos, device)) - .Times(1); - - static_cast(adapter_chromeos) - ->DeviceCreated(adapter_path_, device_path); - - // Finally remove the adapter again; - // BluetoothAdapterClient::Observer::DeviceRemoved should be not called, - // instead BluetoothAdapterClient::Observer::DeviceChanged will be called. - EXPECT_CALL(adapter_observer_, DeviceRemoved(adapter_.get(), device)) - .Times(0); - EXPECT_CALL(adapter_observer_, DeviceChanged(adapter_.get(), device)) - .Times(1); - - static_cast(adapter_chromeos) - ->DeviceRemoved(adapter_path_, device_path); - - // Verify that the device is still visible, just no longer paired. - EXPECT_TRUE(device->IsVisible()); - EXPECT_FALSE(device->IsPaired()); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.cc b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.cc deleted file mode 100644 index eb62622..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2012 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. -// -// TODO(youngki): Guard the ChromeOS specific part with "#ifdef CHROME_OS" block -// once we move this code into common directory. - -#include "base/lazy_instance.h" -#include "base/memory/ref_counted.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" - -namespace { - -// Shared default adapter instance, we don't want to keep this class around -// if nobody is using it so use a WeakPtr and create the object when needed; -// since Google C++ Style (and clang's static analyzer) forbids us having -// exit-time destructors we use a leaky lazy instance for it. -base::LazyInstance >::Leaky - default_adapter = LAZY_INSTANCE_INITIALIZER; - -} // namespace - -namespace chromeos { - -// static -scoped_refptr BluetoothAdapterFactory::DefaultAdapter() { - if (!default_adapter.Get().get()) { - BluetoothAdapterChromeOs* new_adapter = new BluetoothAdapterChromeOs; - new_adapter->TrackDefaultAdapter(); - default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); - } - - return scoped_refptr(default_adapter.Get()); -} - -// static -BluetoothAdapter* BluetoothAdapterFactory::Create(const std::string& address) { - BluetoothAdapterChromeOs* adapter = new BluetoothAdapterChromeOs; - adapter->FindAdapter(address); - return adapter; -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h b/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h deleted file mode 100644 index 0cd4b24..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_FACTORY_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_FACTORY_H_ - -#include - -#include "base/memory/ref_counted.h" - -namespace chromeos { - -class BluetoothAdapter; - -// BluetoothAdapterFactory is a class that contains static methods, which -// instantiate either a specific bluetooth adapter, or the generic "default -// adapter" which may change depending on availability. -class BluetoothAdapterFactory { - public: - // Returns the shared instance for the default adapter, whichever that may - // be at the time. Use IsPresent() and the AdapterPresentChanged() observer - // method to determine whether an adapter is actually available or not. - static scoped_refptr DefaultAdapter(); - - // Creates an instance for a specific adapter at address |address|. - static BluetoothAdapter* Create(const std::string& address); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_ADAPTER_FACTORY_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_device.cc b/chrome/browser/chromeos/bluetooth/bluetooth_device.cc deleted file mode 100644 index f91189a..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_device.cc +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_device.h" - -#include "base/utf_string_conversions.h" -#include "grit/generated_resources.h" -#include "ui/base/l10n/l10n_util.h" - -namespace chromeos { - -BluetoothDevice::BluetoothDevice() - : bluetooth_class_(0), - visible_(false), - bonded_(false), - connected_(false) { -} - -BluetoothDevice::~BluetoothDevice() { -} - -const std::string& BluetoothDevice::address() const { - return address_; -} - -string16 BluetoothDevice::GetName() const { - if (!name_.empty()) { - return UTF8ToUTF16(name_); - } else { - return GetAddressWithLocalizedDeviceTypeName(); - } -} - -string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const { - string16 address = UTF8ToUTF16(address_); - BluetoothDevice::DeviceType device_type = GetDeviceType(); - switch (device_type) { - case DEVICE_COMPUTER: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER, - address); - case DEVICE_PHONE: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE, - address); - case DEVICE_MODEM: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM, - address); - case DEVICE_AUDIO: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO, - address); - case DEVICE_CAR_AUDIO: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO, - address); - case DEVICE_VIDEO: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO, - address); - case DEVICE_JOYSTICK: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK, - address); - case DEVICE_GAMEPAD: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD, - address); - case DEVICE_KEYBOARD: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD, - address); - case DEVICE_MOUSE: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE, - address); - case DEVICE_TABLET: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET, - address); - case DEVICE_KEYBOARD_MOUSE_COMBO: - return l10n_util::GetStringFUTF16( - IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address); - default: - return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN, address); - } -} - -BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const { - // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm - 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) { - case 0x01: - case 0x02: - case 0x03: - // Cellular, cordless and smart phones. - return DEVICE_PHONE; - case 0x04: - case 0x05: - // Modems: wired or voice gateway and common ISDN access. - return DEVICE_MODEM; - } - break; - case 0x04: - // Audio major device class. - switch ((bluetooth_class_ & 0xfc) >> 2) { - case 0x08: - // Car audio. - return DEVICE_CAR_AUDIO; - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: - case 0x010: - // Video devices. - return DEVICE_VIDEO; - default: - return DEVICE_AUDIO; - } - break; - case 0x05: - // Peripheral major device class. - switch ((bluetooth_class_ & 0xc0) >> 6) { - case 0x00: - // "Not a keyboard or pointing device." - switch ((bluetooth_class_ & 0x01e) >> 2) { - case 0x01: - // Joystick. - return DEVICE_JOYSTICK; - case 0x02: - // Gamepad. - return DEVICE_GAMEPAD; - default: - return DEVICE_PERIPHERAL; - } - break; - case 0x01: - // Keyboard. - return DEVICE_KEYBOARD; - case 0x02: - // Pointing device. - switch ((bluetooth_class_ & 0x01e) >> 2) { - case 0x05: - // Digitizer tablet. - return DEVICE_TABLET; - default: - // Mouse. - return DEVICE_MOUSE; - } - break; - case 0x03: - // Combo device. - return DEVICE_KEYBOARD_MOUSE_COMBO; - } - break; - } - - return DEVICE_UNKNOWN; -} - -bool BluetoothDevice::IsVisible() const { - return visible_; -} - -bool BluetoothDevice::IsBonded() const { - return bonded_; -} - -bool BluetoothDevice::IsConnected() const { - return connected_; -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_device.h b/chrome/browser/chromeos/bluetooth/bluetooth_device.h deleted file mode 100644 index ddd4f80..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_device.h +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_DEVICE_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_DEVICE_H_ - -#include -#include - -#include "base/callback.h" -#include "base/string16.h" -#include "base/memory/ref_counted.h" - -namespace chromeos { - -class BluetoothServiceRecord; -class BluetoothSocket; - -struct BluetoothOutOfBandPairingData; - -// BluetoothDevice represents a remote Bluetooth device, both its properties and -// capabilities as discovered by a local adapter and actions that may be -// performed on the remove device such as pairing, connection and disconnection. -// -// 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. -// -// Since the lifecycle of BluetoothDevice instances is managed by -// BluetoothAdapter, that class rather than this provides observer methods -// for devices coming and going, as well as properties being updated. -class BluetoothDevice { - public: - // Possible values that may be returned by GetDeviceType(), representing - // different types of bluetooth device that we support or are aware of - // decoded from the bluetooth class information. - enum DeviceType { - DEVICE_UNKNOWN, - DEVICE_COMPUTER, - DEVICE_PHONE, - DEVICE_MODEM, - DEVICE_AUDIO, - DEVICE_CAR_AUDIO, - DEVICE_VIDEO, - DEVICE_PERIPHERAL, - DEVICE_JOYSTICK, - DEVICE_GAMEPAD, - DEVICE_KEYBOARD, - DEVICE_MOUSE, - DEVICE_TABLET, - DEVICE_KEYBOARD_MOUSE_COMBO - }; - - // Interface for observing changes from bluetooth devices. - class Observer { - public: - virtual ~Observer() {} - - // TODO(keybuk): add observers for pairing and connection. - }; - - // Interface for negotiating pairing of bluetooth devices. - class PairingDelegate { - public: - virtual ~PairingDelegate() {} - - // This method will be called when the Bluetooth daemon requires a - // PIN Code for authentication of the device |device|, the delegate should - // obtain the code from the user and call SetPinCode() on the device to - // provide it, or RejectPairing() or CancelPairing() to reject or cancel - // the request. - // - // PIN Codes are generally required for Bluetooth 2.0 and earlier devices - // for which there is no automatic pairing or special handling. - virtual void RequestPinCode(BluetoothDevice* device) = 0; - - // This method will be called when the Bluetooth daemon requires a - // Passkey for authentication of the device |device|, the delegate should - // obtain the passkey from the user (a numeric in the range 0-999999) and - // call SetPasskey() on the device to provide it, or RejectPairing() or - // CancelPairing() to reject or cancel the request. - // - // Passkeys are generally required for Bluetooth 2.1 and later devices - // which cannot provide input or display on their own, and don't accept - // passkey-less pairing. - virtual void RequestPasskey(BluetoothDevice* device) = 0; - - // This method will be called when the Bluetooth daemon requires that the - // user enter the PIN code |pincode| into the device |device| so that it - // may be authenticated. The DismissDisplayOrConfirm() method - // will be called to dismiss the display once pairing is complete or - // cancelled. - // - // This is used for Bluetooth 2.0 and earlier keyboard devices, the - // |pincode| will always be a six-digit numeric in the range 000000-999999 - // for compatibilty with later specifications. - virtual void DisplayPinCode(BluetoothDevice* device, - const std::string& pincode) = 0; - - // This method will be called when the Bluetooth daemon requires that the - // user enter the Passkey |passkey| into the device |device| so that it - // may be authenticated. The DismissDisplayOrConfirm() method will be - // called to dismiss the display once pairing is complete or cancelled. - // - // This is used for Bluetooth 2.1 and later devices that support input - // but not display, such as keyboards. The Passkey is a numeric in the - // range 0-999999 and should be always presented zero-padded to six - // digits. - virtual void DisplayPasskey(BluetoothDevice* device, - uint32 passkey) = 0; - - // This method will be called when the Bluetooth daemon requires that the - // user confirm that the Passkey |passkey| is displayed on the screen - // of the device |device| so that it may be authenticated. The delegate - // should display to the user and ask for confirmation, then call - // ConfirmPairing() on the device to confirm, RejectPairing() on the device - // to reject or CancelPairing() on the device to cancel authentication - // for any other reason. - // - // This is used for Bluetooth 2.1 and later devices that support display, - // such as other computers or phones. The Passkey is a numeric in the - // range 0-999999 and should be always present zero-padded to six - // digits. - virtual void ConfirmPasskey(BluetoothDevice* device, - uint32 passkey) = 0; - - // This method will be called when any previous DisplayPinCode(), - // DisplayPasskey() or ConfirmPasskey() request should be concluded - // and removed from the user. - virtual void DismissDisplayOrConfirm() = 0; - }; - - virtual ~BluetoothDevice(); - - // 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; - - // Returns the name of the device suitable for displaying, this may - // be a synthesied string containing the address and localized type name - // if the device has no obtained name. - virtual string16 GetName() const; - - // Returns the type of the device, limited to those we support or are - // aware of, by decoding the bluetooth class information. The returned - // values are unique, and do not overlap, so DEVICE_KEYBOARD is not also - // DEVICE_PERIPHERAL. - DeviceType GetDeviceType() const; - - // Indicates whether the device is paired to the adapter, whether or not - // that pairing is permanent or temporary. - 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 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; - - // Returns the services (as UUID strings) that this device provides. - typedef std::vector ServiceList; - virtual const 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. - typedef base::Callback ErrorCallback; - - // Returns the services (as BluetoothServiceRecord objects) that this device - // provides. - typedef ScopedVector ServiceRecordList; - typedef base::Callback ServiceRecordsCallback; - virtual void GetServiceRecords(const ServiceRecordsCallback& callback, - const ErrorCallback& error_callback) = 0; - - // Indicates whether this device provides the given service. |uuid| should - // be in canonical form (see bluetooth_utils::CanonicalUuid). - virtual bool ProvidesServiceWithUUID(const std::string& uuid) const = 0; - - // The ProvidesServiceCallback is used by ProvidesServiceWithName to indicate - // whether or not a matching service was found. - typedef base::Callback ProvidesServiceCallback; - - // Indicates whether this device provides the given service. - virtual void ProvidesServiceWithName( - const std::string& name, - const ProvidesServiceCallback& callback) = 0; - - // Indicates whether the device is currently pairing and expecting a - // PIN Code to be returned. - virtual bool ExpectingPinCode() const = 0; - - // Indicates whether the device is currently pairing and expecting a - // Passkey to be returned. - virtual bool ExpectingPasskey() const = 0; - - // Indicates whether the device is currently pairing and expecting - // confirmation of a displayed passkey. - virtual bool ExpectingConfirmation() const = 0; - - // SocketCallback is used by ConnectToService to return a BluetoothSocket to - // the caller, or NULL if there was an error. The socket will remain open - // until the last reference to the returned BluetoothSocket is released. - typedef base::Callback)> - SocketCallback; - - // Initiates a connection to the device, pairing first if necessary. - // - // Method calls will be made on the supplied object |pairing_delegate| - // to indicate what display, and in response should make method calls - // back to the device object. Not all devices require user responses - // during pairing, so it is normal for |pairing_delegate| to receive no - // calls. To explicitly force a low-security connection without bonding, - // pass NULL, though this is ignored if the device is already paired. - // - // If the request fails, |error_callback| will be called; otherwise, - // |callback| is called when the request is complete. - virtual void Connect(PairingDelegate* pairing_delegate, - const base::Closure& callback, - const ErrorCallback& error_callback) = 0; - - // Sends the PIN code |pincode| to the remote device during pairing. - // - // PIN Codes are generally required for Bluetooth 2.0 and earlier devices - // for which there is no automatic pairing or special handling. - virtual void SetPinCode(const std::string& pincode) = 0; - - // Sends the Passkey |passkey| to the remote device during pairing. - // - // Passkeys are generally required for Bluetooth 2.1 and later devices - // which cannot provide input or display on their own, and don't accept - // passkey-less pairing, and are a numeric in the range 0-999999. - virtual void SetPasskey(uint32 passkey) = 0; - - // Confirms to the remote device during pairing that a passkey provided by - // the ConfirmPasskey() delegate call is displayed on both devices. - virtual void ConfirmPairing() = 0; - - // Rejects a pairing or connection request from a remote device. - virtual void RejectPairing() = 0; - - // Cancels a pairing or connection attempt to a remote device. - virtual void CancelPairing() = 0; - - // Disconnects the device, terminating the low-level ACL connection - // and any application connections using it. Link keys and other pairing - // information are not discarded, and the device object is not deleted. - // If the request fails, |error_callback| will be called; otherwise, - // |callback| is called when the request is complete. - virtual void Disconnect(const base::Closure& callback, - const ErrorCallback& error_callback) = 0; - - // Disconnects the device, terminating the low-level ACL connection - // and any application connections using it, and then discards link keys - // and other pairing information. The device object remainds valid until - // returing from the calling function, after which it should be assumed to - // have been deleted. If the request fails, |error_callback| will be called. - // There is no callback for success beause this object is often deleted - // before that callback would be called. - virtual void Forget(const ErrorCallback& error_callback) = 0; - - // Attempts to open a socket to a service matching |uuid| on this device. If - // the connection is successful, |callback| is called with a BluetoothSocket. - // Otherwise |callback| is called with NULL. The socket is closed as soon as - // all references to the BluetoothSocket are released. Note that the - // BluetoothSocket object can outlive both this BluetoothDevice and the - // BluetoothAdapter for this device. - virtual void ConnectToService(const std::string& service_uuid, - const SocketCallback& 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( - const BluetoothOutOfBandPairingData& data, - const base::Closure& callback, - const ErrorCallback& error_callback) = 0; - - // Clears the Out Of Band pairing data for this device. Exactly one of - // |callback| or |error_callback| will be run. - virtual void ClearOutOfBandPairingData( - const base::Closure& callback, - const ErrorCallback& error_callback) = 0; - - 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_; - - // 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_; - - private: - // Returns a localized string containing the device's bluetooth address and - // a device type for display when |name_| is empty. - string16 GetAddressWithLocalizedDeviceTypeName() const; -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_DEVICE_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.cc b/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.cc deleted file mode 100644 index aa060d5..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.cc +++ /dev/null @@ -1,685 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h" - -#include -#include -#include - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/logging.h" -#include "base/memory/scoped_vector.h" -#include "base/memory/weak_ptr.h" -#include "base/string16.h" -#include "base/string_util.h" -#include "base/values.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" -#include "chromeos/dbus/bluetooth_adapter_client.h" -#include "chromeos/dbus/bluetooth_agent_service_provider.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "chromeos/dbus/bluetooth_input_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/introspectable_client.h" -#include "dbus/bus.h" -#include "dbus/object_path.h" -#include "third_party/cros_system_api/dbus/service_constants.h" - -namespace chromeos { - -BluetoothDeviceChromeOs::BluetoothDeviceChromeOs( - BluetoothAdapterChromeOs* adapter) - : BluetoothDevice(), - adapter_(adapter), - pairing_delegate_(NULL), - connecting_applications_counter_(0), - weak_ptr_factory_(this) { -} - -BluetoothDeviceChromeOs::~BluetoothDeviceChromeOs() { -} - -bool BluetoothDeviceChromeOs::IsPaired() const { - return !object_path_.value().empty(); -} - -const BluetoothDevice::ServiceList& -BluetoothDeviceChromeOs::GetServices() const { - return service_uuids_; -} - -void BluetoothDeviceChromeOs::GetServiceRecords( - const ServiceRecordsCallback& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - DiscoverServices( - object_path_, - "", // empty pattern to browse all services - base::Bind(&BluetoothDeviceChromeOs::CollectServiceRecordsCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -bool BluetoothDeviceChromeOs::ProvidesServiceWithUUID( - const std::string& uuid) const { - const BluetoothDevice::ServiceList& services = GetServices(); - for (BluetoothDevice::ServiceList::const_iterator iter = services.begin(); - iter != services.end(); - ++iter) { - if (bluetooth_utils::CanonicalUuid(*iter) == uuid) - return true; - } - return false; -} - -void BluetoothDeviceChromeOs::ProvidesServiceWithName( - const std::string& name, - const ProvidesServiceCallback& callback) { - GetServiceRecords( - base::Bind(&BluetoothDeviceChromeOs::SearchServicesForNameCallback, - weak_ptr_factory_.GetWeakPtr(), - name, - callback), - base::Bind(&BluetoothDeviceChromeOs::SearchServicesForNameErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - callback)); -} - -bool BluetoothDeviceChromeOs::ExpectingPinCode() const { - return !pincode_callback_.is_null(); -} - -bool BluetoothDeviceChromeOs::ExpectingPasskey() const { - return !passkey_callback_.is_null(); -} - -bool BluetoothDeviceChromeOs::ExpectingConfirmation() const { - return !confirmation_callback_.is_null(); -} - -void BluetoothDeviceChromeOs::Connect(PairingDelegate* pairing_delegate, - const base::Closure& callback, - const ErrorCallback& error_callback) { - if (IsPaired() || IsBonded() || IsConnected()) { - // Connection to already paired or connected device. - ConnectApplications(callback, error_callback); - - } else if (!pairing_delegate) { - // No pairing delegate supplied, initiate low-security connection only. - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - CreateDevice(adapter_->object_path_, - address_, - base::Bind(&BluetoothDeviceChromeOs::ConnectCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback), - base::Bind(&BluetoothDeviceChromeOs::ConnectErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - error_callback)); - } else { - // Initiate high-security connection with pairing. - DCHECK(!pairing_delegate_); - pairing_delegate_ = pairing_delegate; - - // The agent path is relatively meaningless, we use the device address - // to generate it as we only support one pairing attempt at a time for - // a given bluetooth device. - DCHECK(agent_.get() == NULL); - - std::string agent_path_basename; - ReplaceChars(address_, ":", "_", &agent_path_basename); - dbus::ObjectPath agent_path("/org/chromium/bluetooth_agent/" + - agent_path_basename); - - dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); - if (system_bus) { - agent_.reset(BluetoothAgentServiceProvider::Create(system_bus, - agent_path, - this)); - } else { - agent_.reset(NULL); - } - - DVLOG(1) << "Pairing: " << address_; - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - CreatePairedDevice( - adapter_->object_path_, - address_, - agent_path, - bluetooth_agent::kDisplayYesNoCapability, - base::Bind(&BluetoothDeviceChromeOs::ConnectCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback), - base::Bind(&BluetoothDeviceChromeOs::ConnectErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - error_callback)); - } -} - -void BluetoothDeviceChromeOs::SetPinCode(const std::string& pincode) { - if (!agent_.get() || pincode_callback_.is_null()) - return; - - pincode_callback_.Run(SUCCESS, pincode); - pincode_callback_.Reset(); -} - -void BluetoothDeviceChromeOs::SetPasskey(uint32 passkey) { - if (!agent_.get() || passkey_callback_.is_null()) - return; - - passkey_callback_.Run(SUCCESS, passkey); - passkey_callback_.Reset(); -} - -void BluetoothDeviceChromeOs::ConfirmPairing() { - if (!agent_.get() || confirmation_callback_.is_null()) - return; - - confirmation_callback_.Run(SUCCESS); - confirmation_callback_.Reset(); -} - -void BluetoothDeviceChromeOs::RejectPairing() { - if (!agent_.get()) - return; - - if (!pincode_callback_.is_null()) { - pincode_callback_.Run(REJECTED, ""); - pincode_callback_.Reset(); - } - if (!passkey_callback_.is_null()) { - passkey_callback_.Run(REJECTED, 0); - passkey_callback_.Reset(); - } - if (!confirmation_callback_.is_null()) { - confirmation_callback_.Run(REJECTED); - confirmation_callback_.Reset(); - } -} - -void BluetoothDeviceChromeOs::CancelPairing() { - if (!agent_.get()) - return; - - if (!pincode_callback_.is_null()) { - pincode_callback_.Run(CANCELLED, ""); - pincode_callback_.Reset(); - } - if (!passkey_callback_.is_null()) { - passkey_callback_.Run(CANCELLED, 0); - passkey_callback_.Reset(); - } - if (!confirmation_callback_.is_null()) { - confirmation_callback_.Run(CANCELLED); - confirmation_callback_.Reset(); - } -} - -void BluetoothDeviceChromeOs::Disconnect(const base::Closure& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - Disconnect(object_path_, - base::Bind(&BluetoothDeviceChromeOs::DisconnectCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); - -} - -void BluetoothDeviceChromeOs::Forget(const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothAdapterClient()-> - RemoveDevice(adapter_->object_path_, - object_path_, - base::Bind(&BluetoothDeviceChromeOs::ForgetCallback, - weak_ptr_factory_.GetWeakPtr(), - error_callback)); -} - -void BluetoothDeviceChromeOs::ConnectToService(const std::string& service_uuid, - const SocketCallback& callback) { - GetServiceRecords( - base::Bind(&BluetoothDeviceChromeOs::GetServiceRecordsForConnectCallback, - weak_ptr_factory_.GetWeakPtr(), - service_uuid, - callback), - base::Bind( - &BluetoothDeviceChromeOs::GetServiceRecordsForConnectErrorCallback, - weak_ptr_factory_.GetWeakPtr(), - callback)); -} - -void BluetoothDeviceChromeOs::SetOutOfBandPairingData( - const chromeos::BluetoothOutOfBandPairingData& data, - const base::Closure& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> - AddRemoteData( - object_path_, - address(), - data, - base::Bind(&BluetoothDeviceChromeOs::OnRemoteDataCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -void BluetoothDeviceChromeOs::ClearOutOfBandPairingData( - const base::Closure& callback, - const ErrorCallback& error_callback) { - DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> - RemoveRemoteData( - object_path_, - address(), - base::Bind(&BluetoothDeviceChromeOs::OnRemoteDataCallback, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -void BluetoothDeviceChromeOs::SetObjectPath( - const dbus::ObjectPath& object_path) { - DCHECK(object_path_ == dbus::ObjectPath("")); - object_path_ = object_path; -} - -void BluetoothDeviceChromeOs::RemoveObjectPath() { - DCHECK(object_path_ != dbus::ObjectPath("")); - object_path_ = dbus::ObjectPath(""); -} - -void BluetoothDeviceChromeOs::Update( - const BluetoothDeviceClient::Properties* properties, - bool update_state) { - std::string address = properties->address.value(); - std::string name = properties->name.value(); - uint32 bluetooth_class = properties->bluetooth_class.value(); - const std::vector& uuids = properties->uuids.value(); - - if (!address.empty()) - address_ = address; - if (!name.empty()) - name_ = name; - if (bluetooth_class) - bluetooth_class_ = bluetooth_class; - if (!uuids.empty()) { - service_uuids_.clear(); - service_uuids_.assign(uuids.begin(), uuids.end()); - } - - if (update_state) { - // 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(); - connected_ = properties->connected.value(); - } -} - -void BluetoothDeviceChromeOs::ConnectCallback( - const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path) { - DVLOG(1) << "Connection successful: " << device_path.value(); - if (object_path_.value().empty()) { - object_path_ = device_path; - } else { - LOG_IF(WARNING, object_path_ != device_path) - << "Conflicting device paths for objects, result gave: " - << device_path.value() << " but signal gave: " - << object_path_.value(); - } - - // Mark the device trusted so it can connect to us automatically, and - // we can connect after rebooting. This information is part of the - // pairing information of the device, and is unique to the combination - // of our bluetooth address and the device's bluetooth address. A - // different host needs a new pairing, so it's not useful to sync. - DBusThreadManager::Get()->GetBluetoothDeviceClient()-> - GetProperties(object_path_)->trusted.Set( - true, - base::Bind(&BluetoothDeviceChromeOs::OnSetTrusted, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); - - // Connect application-layer protocols. - ConnectApplications(callback, error_callback); -} - -void BluetoothDeviceChromeOs::ConnectErrorCallback( - const ErrorCallback& error_callback, - const std::string& error_name, - const std::string& error_message) { - LOG(WARNING) << "Connection failed: " << address_ - << ": " << error_name << ": " << error_message; - error_callback.Run(); -} - -void BluetoothDeviceChromeOs::CollectServiceRecordsCallback( - const ServiceRecordsCallback& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path, - const BluetoothDeviceClient::ServiceMap& service_map, - bool success) { - if (!success) { - error_callback.Run(); - return; - } - - ScopedVector records; - for (BluetoothDeviceClient::ServiceMap::const_iterator i = - service_map.begin(); i != service_map.end(); ++i) { - records.push_back( - new BluetoothServiceRecord(address(), i->second)); - } - callback.Run(records); -} - -void BluetoothDeviceChromeOs::OnSetTrusted(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success) { - if (success) { - callback.Run(); - } else { - LOG(WARNING) << "Failed to set device as trusted: " << address_; - error_callback.Run(); - } -} - -void BluetoothDeviceChromeOs::ConnectApplications( - const base::Closure& callback, - const ErrorCallback& error_callback) { - // Introspect the device object to determine supported applications. - DBusThreadManager::Get()->GetIntrospectableClient()-> - Introspect(bluetooth_device::kBluetoothDeviceServiceName, - object_path_, - base::Bind(&BluetoothDeviceChromeOs::OnIntrospect, - weak_ptr_factory_.GetWeakPtr(), - callback, - error_callback)); -} - -void BluetoothDeviceChromeOs::OnIntrospect(const base::Closure& callback, - const ErrorCallback& error_callback, - const std::string& service_name, - const dbus::ObjectPath& device_path, - const std::string& xml_data, - bool success) { - if (!success) { - LOG(WARNING) << "Failed to determine supported applications: " << address_; - error_callback.Run(); - return; - } - - // The introspection data for the device object may list one or more - // additional D-Bus interfaces that BlueZ supports for this particular - // device. Send appropraite Connect calls for each of those interfaces - // to connect all of the application protocols for this device. - std::vector interfaces = - IntrospectableClient::GetInterfacesFromIntrospectResult(xml_data); - - DCHECK_EQ(0, connecting_applications_counter_); - connecting_applications_counter_ = 0; - for (std::vector::iterator iter = interfaces.begin(); - iter != interfaces.end(); ++iter) { - if (*iter == bluetooth_input::kBluetoothInputInterface) { - connecting_applications_counter_++; - // Supports Input interface. - DBusThreadManager::Get()->GetBluetoothInputClient()-> - Connect(object_path_, - base::Bind(&BluetoothDeviceChromeOs::OnConnect, - weak_ptr_factory_.GetWeakPtr(), - callback, - *iter), - base::Bind(&BluetoothDeviceChromeOs::OnConnectError, - weak_ptr_factory_.GetWeakPtr(), - error_callback, *iter)); - } - } - - // If OnConnect has been called for every call to Connect above, then this - // will decrement the counter to -1. In that case, call the callback - // directly as it has not been called by any of the OnConnect callbacks. - // This is safe because OnIntrospect and OnConnect run on the same thread. - connecting_applications_counter_--; - if (connecting_applications_counter_ == -1) - callback.Run(); -} - -void BluetoothDeviceChromeOs::OnConnect(const base::Closure& callback, - const std::string& interface_name, - const dbus::ObjectPath& device_path) { - DVLOG(1) << "Application connection successful: " << device_path.value() - << ": " << interface_name; - - connecting_applications_counter_--; - // |callback| should only be called once, meaning it cannot be called before - // all requests have been started. The extra decrement after all requests - // have been started, and the check for -1 instead of 0 below, insure only a - // single call to |callback| will occur (provided OnConnect and OnIntrospect - // run on the same thread, which is true). - if (connecting_applications_counter_ == -1) { - connecting_applications_counter_ = 0; - callback.Run(); - } -} - -void BluetoothDeviceChromeOs::OnConnectError( - const ErrorCallback& error_callback, - const std::string& interface_name, - const dbus::ObjectPath& device_path, - const std::string& error_name, - const std::string& error_message) { - LOG(WARNING) << "Connection failed: " << address_ << ": " << interface_name - << ": " << error_name << ": " << error_message; - error_callback.Run(); -} - -void BluetoothDeviceChromeOs::DisconnectCallback( - const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path, - bool success) { - DCHECK(device_path == object_path_); - if (success) { - DVLOG(1) << "Disconnection successful: " << address_; - callback.Run(); - } else { - LOG(WARNING) << "Disconnection failed: " << address_; - error_callback.Run(); - } -} - -void BluetoothDeviceChromeOs::ForgetCallback( - const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, - bool success) { - // It's quite normal that this path never gets called on success; we use a - // weak pointer, and bluetoothd might send the DeviceRemoved signal before - // the method reply, in which case this object is deleted and the - // callback never takes place. Therefore don't do anything here for the - // success case. - if (!success) { - LOG(WARNING) << "Forget failed: " << address_; - error_callback.Run(); - } -} - -void BluetoothDeviceChromeOs::SearchServicesForNameErrorCallback( - const ProvidesServiceCallback& callback) { - callback.Run(false); -} - -void BluetoothDeviceChromeOs::SearchServicesForNameCallback( - const std::string& name, - const ProvidesServiceCallback& callback, - const ServiceRecordList& list) { - for (ServiceRecordList::const_iterator i = list.begin(); - i != list.end(); ++i) { - if ((*i)->name() == name) { - callback.Run(true); - return; - } - } - callback.Run(false); -} - -void BluetoothDeviceChromeOs::GetServiceRecordsForConnectErrorCallback( - const SocketCallback& callback) { - callback.Run(NULL); -} - -void BluetoothDeviceChromeOs::GetServiceRecordsForConnectCallback( - const std::string& service_uuid, - const SocketCallback& callback, - const ServiceRecordList& list) { - for (ServiceRecordList::const_iterator i = list.begin(); - i != list.end(); ++i) { - if ((*i)->uuid() == service_uuid) { - // If multiple service records are found, use the first one that works. - scoped_refptr socket( - BluetoothSocketChromeOs::CreateBluetoothSocket(**i)); - if (socket.get() != NULL) { - callback.Run(socket); - return; - } - } - } - callback.Run(NULL); -} - -void BluetoothDeviceChromeOs::OnRemoteDataCallback( - const base::Closure& callback, - const ErrorCallback& error_callback, - bool success) { - if (success) - callback.Run(); - else - error_callback.Run(); -} - -void BluetoothDeviceChromeOs::DisconnectRequested( - const dbus::ObjectPath& object_path) { - DCHECK(object_path == object_path_); -} - -void BluetoothDeviceChromeOs::Release() { - DCHECK(agent_.get()); - DVLOG(1) << "Release: " << address_; - - DCHECK(pairing_delegate_); - pairing_delegate_->DismissDisplayOrConfirm(); - pairing_delegate_ = NULL; - - pincode_callback_.Reset(); - passkey_callback_.Reset(); - confirmation_callback_.Reset(); - - agent_.reset(); -} - -void BluetoothDeviceChromeOs::RequestPinCode( - const dbus::ObjectPath& device_path, - const PinCodeCallback& callback) { - DCHECK(agent_.get()); - DVLOG(1) << "RequestPinCode: " << device_path.value(); - - DCHECK(pairing_delegate_); - DCHECK(pincode_callback_.is_null()); - pincode_callback_ = callback; - pairing_delegate_->RequestPinCode(this); -} - -void BluetoothDeviceChromeOs::RequestPasskey( - const dbus::ObjectPath& device_path, - const PasskeyCallback& callback) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - DVLOG(1) << "RequestPasskey: " << device_path.value(); - - DCHECK(pairing_delegate_); - DCHECK(passkey_callback_.is_null()); - passkey_callback_ = callback; - pairing_delegate_->RequestPasskey(this); -} - -void BluetoothDeviceChromeOs::DisplayPinCode( - const dbus::ObjectPath& device_path, - const std::string& pincode) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - DVLOG(1) << "DisplayPinCode: " << device_path.value() << " " << pincode; - - DCHECK(pairing_delegate_); - pairing_delegate_->DisplayPinCode(this, pincode); -} - -void BluetoothDeviceChromeOs::DisplayPasskey( - const dbus::ObjectPath& device_path, - uint32 passkey) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - DVLOG(1) << "DisplayPasskey: " << device_path.value() << " " << passkey; - - DCHECK(pairing_delegate_); - pairing_delegate_->DisplayPasskey(this, passkey); -} - -void BluetoothDeviceChromeOs::RequestConfirmation( - const dbus::ObjectPath& device_path, - uint32 passkey, - const ConfirmationCallback& callback) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - DVLOG(1) << "RequestConfirmation: " << device_path.value() << " " << passkey; - - DCHECK(pairing_delegate_); - DCHECK(confirmation_callback_.is_null()); - confirmation_callback_ = callback; - pairing_delegate_->ConfirmPasskey(this, passkey); -} - -void BluetoothDeviceChromeOs::Authorize(const dbus::ObjectPath& device_path, - const std::string& uuid, - const ConfirmationCallback& callback) { - DCHECK(agent_.get()); - DCHECK(device_path == object_path_); - LOG(WARNING) << "Rejected authorization for service: " << uuid - << " requested from device: " << device_path.value(); - callback.Run(REJECTED); -} - -void BluetoothDeviceChromeOs::ConfirmModeChange( - Mode mode, - const ConfirmationCallback& callback) { - DCHECK(agent_.get()); - LOG(WARNING) << "Rejected adapter-level mode change: " << mode - << " made on agent for device: " << address_; - callback.Run(REJECTED); -} - -void BluetoothDeviceChromeOs::Cancel() { - DCHECK(agent_.get()); - DVLOG(1) << "Cancel: " << address_; - - DCHECK(pairing_delegate_); - pairing_delegate_->DismissDisplayOrConfirm(); -} - - -// static -BluetoothDeviceChromeOs* BluetoothDeviceChromeOs::Create( - BluetoothAdapterChromeOs* adapter) { - return new BluetoothDeviceChromeOs(adapter); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h b/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h deleted file mode 100644 index a4202c5..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h +++ /dev/null @@ -1,369 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ - -#include -#include - -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" -#include "base/memory/weak_ptr.h" -#include "base/string16.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" -#include "chromeos/dbus/bluetooth_agent_service_provider.h" -#include "chromeos/dbus/bluetooth_device_client.h" -#include "dbus/object_path.h" - -namespace chromeos { - -class BluetoothAdapterChromeOs; -class BluetoothServiceRecord; - -struct BluetoothOutOfBandPairingData; - -// The BluetoothDeviceChromeOs class is an implementation of BluetoothDevice -// for Chrome OS platform. -class BluetoothDeviceChromeOs : public BluetoothDevice, - public BluetoothDeviceClient::Observer, - public BluetoothAgentServiceProvider::Delegate { - public: - virtual ~BluetoothDeviceChromeOs(); - - // BluetoothDevice override - virtual bool IsPaired() const OVERRIDE; - virtual const ServiceList& GetServices() const OVERRIDE; - virtual void GetServiceRecords( - const ServiceRecordsCallback& callback, - const ErrorCallback& error_callback) OVERRIDE; - virtual bool ProvidesServiceWithUUID(const std::string& uuid) const OVERRIDE; - virtual void ProvidesServiceWithName( - const std::string& name, - const ProvidesServiceCallback& callback) OVERRIDE; - virtual bool ExpectingPinCode() const OVERRIDE; - virtual bool ExpectingPasskey() const OVERRIDE; - virtual bool ExpectingConfirmation() const OVERRIDE; - virtual void Connect( - BluetoothDevice::PairingDelegate* pairing_delegate, - const base::Closure& callback, - const ErrorCallback& error_callback) OVERRIDE; - virtual void SetPinCode(const std::string& pincode) OVERRIDE; - virtual void SetPasskey(uint32 passkey) OVERRIDE; - virtual void ConfirmPairing() OVERRIDE; - virtual void RejectPairing() OVERRIDE; - virtual void CancelPairing() OVERRIDE; - virtual void Disconnect( - const base::Closure& callback, - const ErrorCallback& error_callback) OVERRIDE; - virtual void Forget(const ErrorCallback& error_callback) OVERRIDE; - virtual void ConnectToService( - const std::string& service_uuid, - const SocketCallback& callback) OVERRIDE; - virtual void SetOutOfBandPairingData( - const chromeos::BluetoothOutOfBandPairingData& data, - const base::Closure& callback, - const ErrorCallback& error_callback) OVERRIDE; - virtual void ClearOutOfBandPairingData( - const base::Closure& callback, - const ErrorCallback& error_callback) OVERRIDE; - - private: - friend class BluetoothAdapterChromeOs; - friend class MockBluetoothDevice; - - explicit BluetoothDeviceChromeOs(BluetoothAdapterChromeOs* adapter); - - // Sets the dbus object path for the device to |object_path|, indicating - // that the device has gone from being discovered to paired or bonded. - 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. - void RemoveObjectPath(); - - // Sets whether the device is visible to the owning adapter to |visible|. - void SetVisible(bool visible) { visible_ = visible; } - - // Updates device information from the properties in |properties|, device - // state properties such as |paired_| and |connected_| are ignored unless - // |update_state| is true. - void Update(const BluetoothDeviceClient::Properties* properties, - bool update_state); - - // Called by BluetoothAdapterClient when a call to CreateDevice() or - // CreatePairedDevice() succeeds, provides the new object path for the remote - // device in |device_path|. |callback| and |error_callback| are the callbacks - // provided to Connect(). - void ConnectCallback(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path); - - // Called by BluetoothAdapterClient when a call to CreateDevice() or - // CreatePairedDevice() fails with the error named |error_name| and - // optional message |error_message|, |error_callback| is the callback - // provided to Connect(). - void ConnectErrorCallback(const ErrorCallback& error_callback, - const std::string& error_name, - const std::string& error_message); - - // Called by BluetoothAdapterClient when a call to DiscoverServices() - // completes. |callback| and |error_callback| are the callbacks provided to - // GetServiceRecords. - void CollectServiceRecordsCallback( - const ServiceRecordsCallback& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path, - const BluetoothDeviceClient::ServiceMap& service_map, - bool success); - - // Called by BluetoothProperty when the call to Set() for the Trusted - // property completes. |success| indicates whether or not the request - // succeeded, |callback| and |error_callback| are the callbacks provided to - // Connect(). - void OnSetTrusted(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success); - - // Connect application-level protocols of the device to the system, called - // on a successful connection or to reconnect to a device that is already - // paired or previously connected. |error_callback| is called on failure. - // Otherwise, |callback| is called when the request is complete. - void ConnectApplications(const base::Closure& callback, - const ErrorCallback& error_callback); - - // Called by IntrospectableClient when a call to Introspect() completes. - // |success| indicates whether or not the request succeeded, |callback| and - // |error_callback| are the callbacks provided to ConnectApplications(), - // |service_name| and |device_path| specify the remote object being - // introspected and |xml_data| contains the XML-formatted protocol data. - void OnIntrospect(const base::Closure& callback, - const ErrorCallback& error_callback, - const std::string& service_name, - const dbus::ObjectPath& device_path, - const std::string& xml_data, bool success); - - // Called by BluetoothInputClient when the call to Connect() succeeds. - // |error_callback| is the callback provided to ConnectApplications(), - // |interface_name| specifies the interface being connected and - // |device_path| the remote object path. - void OnConnect(const base::Closure& callback, - const std::string& interface_name, - const dbus::ObjectPath& device_path); - - // Called by BluetoothInputClient when the call to Connect() fails. - // |error_callback| is the callback provided to ConnectApplications(), - // |interface_name| specifies the interface being connected, - // |device_path| the remote object path, - // |error_name| the error name and |error_message| the optional message. - void OnConnectError(const ErrorCallback& error_callback, - const std::string& interface_name, - const dbus::ObjectPath& device_path, - const std::string& error_name, - const std::string& error_message); - - // Called by BluetoothDeviceClient when a call to Disconnect() completes, - // |success| indicates whether or not the request succeeded, |callback| and - // |error_callback| are the callbacks provided to Disconnect() and - // |device_path| is the device disconnected. - void DisconnectCallback(const base::Closure& callback, - const ErrorCallback& error_callback, - const dbus::ObjectPath& device_path, bool success); - - // Called by BluetoothAdapterClient when a call to RemoveDevice() - // completes, |success| indicates whether or not the request succeeded, - // |error_callback| is the callback provided to Forget() and |adapter_path| is - // the d-bus object path of the adapter that performed the removal. - void ForgetCallback(const ErrorCallback& error_callback, - const dbus::ObjectPath& adapter_path, bool success); - - // Called if the call to GetServiceRecords from ProvidesServiceWithName fails. - void SearchServicesForNameErrorCallback( - const ProvidesServiceCallback& callback); - - // Called by GetServiceRecords with the list of BluetoothServiceRecords to - // search for |name|. |callback| is the callback from - // ProvidesServiceWithName. - void SearchServicesForNameCallback( - const std::string& name, - const ProvidesServiceCallback& callback, - const ServiceRecordList& list); - - // Called if the call to GetServiceRecords from Connect fails. - void GetServiceRecordsForConnectErrorCallback( - const SocketCallback& callback); - - // Called by GetServiceRecords with the list of BluetoothServiceRecords. - // Connections are attempted to each service in the list matching - // |service_uuid|, and the socket from the first successful connection is - // passed to |callback|. - void GetServiceRecordsForConnectCallback( - const std::string& service_uuid, - const SocketCallback& callback, - const ServiceRecordList& list); - - // Called by BlueoothDeviceClient in response to the AddRemoteData and - // RemoveRemoteData method calls. - void OnRemoteDataCallback(const base::Closure& callback, - const ErrorCallback& error_callback, - bool success); - - // BluetoothDeviceClient::Observer override. - // - // Called when the device with object path |object_path| is about - // to be disconnected, giving a chance for application layers to - // shut down cleanly. - virtual void DisconnectRequested( - const dbus::ObjectPath& object_path) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the agent is unregistered from the - // Bluetooth daemon, generally at the end of a pairing request. It may be - // used to perform cleanup tasks. - virtual void Release() OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires a - // PIN Code for authentication of the device with object path |device_path|, - // the agent should obtain the code from the user and call |callback| - // to provide it, or indicate rejection or cancellation of the request. - // - // PIN Codes are generally required for Bluetooth 2.0 and earlier devices - // for which there is no automatic pairing or special handling. - virtual void RequestPinCode(const dbus::ObjectPath& device_path, - const PinCodeCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires a - // Passkey for authentication of the device with object path |device_path|, - // the agent should obtain the passkey from the user (a numeric in the - // range 0-999999) and call |callback| to provide it, or indicate - // rejection or cancellation of the request. - // - // Passkeys are generally required for Bluetooth 2.1 and later devices - // which cannot provide input or display on their own, and don't accept - // passkey-less pairing. - virtual void RequestPasskey(const dbus::ObjectPath& device_path, - const PasskeyCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user enter the PIN code |pincode| into the device with object path - // |device_path| so that it may be authenticated. The Cancel() method - // will be called to dismiss the display once pairing is complete or - // cancelled. - // - // This is used for Bluetooth 2.0 and earlier keyboard devices, the - // |pincode| will always be a six-digit numeric in the range 000000-999999 - // for compatibilty with later specifications. - virtual void DisplayPinCode(const dbus::ObjectPath& device_path, - const std::string& pincode) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user enter the Passkey |passkey| into the device with object path - // |device_path| so that it may be authenticated. The Cancel() method - // will be called to dismiss the display once pairing is complete or - // cancelled. - // - // This is used for Bluetooth 2.1 and later devices that support input - // but not display, such as keyboards. The Passkey is a numeric in the - // range 0-999999 and should be always presented zero-padded to six - // digits. - virtual void DisplayPasskey(const dbus::ObjectPath& device_path, - uint32 passkey) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user confirm that the Passkey |passkey| is displayed on the screen - // of the device with object path |object_path| so that it may be - // authentication. The agent should display to the user and ask for - // confirmation, then call |callback| to provide their response (success, - // rejected or cancelled). - // - // This is used for Bluetooth 2.1 and later devices that support display, - // such as other computers or phones. The Passkey is a numeric in the - // range 0-999999 and should be always present zero-padded to six - // digits. - virtual void RequestConfirmation( - const dbus::ObjectPath& device_path, - uint32 passkey, - const ConfirmationCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user confirm that the device with object path |object_path| is - // authorized to connect to the service with UUID |uuid|. The agent should - // confirm with the user and call |callback| to provide their response - // (success, rejected or cancelled). - virtual void Authorize(const dbus::ObjectPath& device_path, - const std::string& uuid, - const ConfirmationCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called when the Bluetooth daemon requires that the - // user confirm that the device adapter may switch to mode |mode|. The - // agent should confirm with the user and call |callback| to provide - // their response (success, rejected or cancelled). - virtual void ConfirmModeChange(Mode mode, - const ConfirmationCallback& callback) OVERRIDE; - - // BluetoothAgentServiceProvider::Delegate override. - // - // This method will be called by the Bluetooth daemon to indicate that - // the request failed before a reply was returned from the device. - virtual void Cancel() OVERRIDE; - - // Creates a new BluetoothDeviceChromeOs object bound to the adapter - // |adapter|. - static BluetoothDeviceChromeOs* Create(BluetoothAdapterChromeOs* adapter); - - // The adapter that owns this device instance. - BluetoothAdapterChromeOs* adapter_; - - // The dbus object path of the device, will be empty if the device has only - // been discovered and not yet paired with. - dbus::ObjectPath object_path_; - - // The services (identified by UUIDs) that this device provides. - std::vector 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 - // Passkeys. Generally it is the object that owns this one. - BluetoothDevice::PairingDelegate* pairing_delegate_; - - // During pairing this is set to an instance of a D-Bus agent object - // intialized with our own class as its delegate. - scoped_ptr agent_; - - // During pairing these callbacks are set to those provided by method calls - // made on us by |agent_| and are called by our own method calls such as - // SetPinCode() and SetPasskey(). - PinCodeCallback pincode_callback_; - PasskeyCallback passkey_callback_; - ConfirmationCallback confirmation_callback_; - - // Used to keep track of pending application connection requests. - int connecting_applications_counter_; - - // Note: This should remain the last member so it'll be destroyed and - // invalidate its weak pointers before any other members are destroyed. - base::WeakPtrFactory weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceChromeOs); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_service_record.cc b/chrome/browser/chromeos/bluetooth/bluetooth_service_record.cc deleted file mode 100644 index b80ce29..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_service_record.cc +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" - -#include -#include - -#include "base/logging.h" -#include "base/string_number_conversions.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" -#include "third_party/libxml/chromium/libxml_utils.h" - -namespace { - -static const char* kAttributeNode = "attribute"; -static const char* kIdAttribute = "id"; -static const char* kProtocolDescriptorListId = "0x0004"; -static const char* kRfcommUuid = "0x0003"; -static const char* kSdpNameId = "0x0100"; -static const char* kSequenceNode = "sequence"; -static const char* kTextNode = "text"; -static const char* kUint8Node = "uint8"; -static const char* kUuidId = "0x0001"; -static const char* kUuidNode = "uuid"; -static const char* kValueAttribute = "value"; - -bool AdvanceToTag(XmlReader* reader, const char* node_type) { - do { - if (!reader->Read()) - return false; - } while (reader->NodeName() != node_type); - return true; -} - -bool ExtractTextValue(XmlReader* reader, std::string* value_out) { - if (AdvanceToTag(reader, kTextNode)) { - reader->NodeAttribute(kValueAttribute, value_out); - return true; - } - return false; -} - -} // namespace - -namespace chromeos { - -BluetoothServiceRecord::BluetoothServiceRecord( - const std::string& address, - const std::string& xml_data) - : address_(address), - supports_rfcomm_(false) { - - XmlReader reader; - if (!reader.Load(xml_data)) - return; - - while (AdvanceToTag(&reader, kAttributeNode)) { - std::string id; - if (reader.NodeAttribute(kIdAttribute, &id)) { - if (id == kSdpNameId) { - ExtractTextValue(&reader, &name_); - } else if (id == kProtocolDescriptorListId) { - if (AdvanceToTag(&reader, kSequenceNode)) { - ExtractChannels(&reader); - } - } else if (id == kUuidId) { - if (AdvanceToTag(&reader, kSequenceNode)) { - ExtractUuid(&reader); - } - } - } - // We don't care about anything else here, so find the closing tag - AdvanceToTag(&reader, kAttributeNode); - } -} - -void BluetoothServiceRecord::ExtractChannels(XmlReader* reader) { - const int start_depth = reader->Depth(); - do { - if (reader->NodeName() == kSequenceNode) { - if (AdvanceToTag(reader, kUuidNode)) { - std::string type; - if (reader->NodeAttribute(kValueAttribute, &type) && - type == kRfcommUuid) { - if (AdvanceToTag(reader, kUint8Node)) { - std::string channel_string; - if (reader->NodeAttribute(kValueAttribute, &channel_string)) { - std::vector channel_bytes; - if (base::HexStringToBytes(channel_string.substr(2), - &channel_bytes)) { - if (channel_bytes.size() == 1) { - rfcomm_channel_ = channel_bytes[0]; - supports_rfcomm_ = true; - } - } - } - } - } - } - } - } while (AdvanceToTag(reader, kSequenceNode) && - reader->Depth() != start_depth); -} - -void BluetoothServiceRecord::ExtractUuid(XmlReader* reader) { - const int start_depth = reader->Depth(); - do { - if (reader->NodeName() == kSequenceNode) { - if (AdvanceToTag(reader, kUuidNode)) { - if (!reader->NodeAttribute(kValueAttribute, &uuid_)) - uuid_.clear(); - } - } - } while (AdvanceToTag(reader, kSequenceNode) && - reader->Depth() != start_depth); - - uuid_ = bluetooth_utils::CanonicalUuid(uuid_); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_service_record.h b/chrome/browser/chromeos/bluetooth/bluetooth_service_record.h deleted file mode 100644 index 2e43d72..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_service_record.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SERVICE_RECORD_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SERVICE_RECORD_H_ - -#include - -#include "base/basictypes.h" - -class XmlReader; - -namespace chromeos { - -// BluetoothServiceRecord represents an SDP service record. -// -// This implementation is currently incomplete: it only supports those fields -// that have been necessary so far. -class BluetoothServiceRecord { - public: - BluetoothServiceRecord( - const std::string& address, - const std::string& xml_data); - - // The human-readable name of this service. - const std::string& name() const { return name_; } - - // The address of the BluetoothDevice providing this service. - const std::string& address() const { return address_; } - - // The UUID of the service. This field may be empty if no UUID was - // specified in the service record. - const std::string& uuid() const { return uuid_; } - - // Indicates if this service supports RFCOMM communication. - bool SupportsRfcomm() const { return supports_rfcomm_; } - - // The RFCOMM channel to use, if this service supports RFCOMM communication. - // The return value is undefined if SupportsRfcomm() returns false. - uint8_t rfcomm_channel() const { return rfcomm_channel_; } - - private: - void ExtractChannels(XmlReader* reader); - void ExtractUuid(XmlReader* reader); - - std::string address_; - std::string name_; - std::string uuid_; - - bool supports_rfcomm_; - uint8_t rfcomm_channel_; - - DISALLOW_COPY_AND_ASSIGN(BluetoothServiceRecord); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SERVICE_RECORD_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_service_record_unittest.cc b/chrome/browser/chromeos/bluetooth/bluetooth_service_record_unittest.cc deleted file mode 100644 index 11bcd98..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_service_record_unittest.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2012 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 - -#include "base/file_path.h" -#include "base/file_util.h" -#include "base/path_service.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" -#include "chrome/common/chrome_paths.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -static const char* kAddress = "01:02:03:04:05:06"; -static const char* kCustomUuid = "01234567-89ab-cdef-0123-456789abcdef"; -static const char* kSerialUuid = "00001101-0000-1000-8000-00805f9b34fb"; - -} // namespace - -namespace chromeos { - -class BluetoothServiceRecordTest : public testing::Test { - public: - FilePath GetTestDataFilePath(const char* file) { - FilePath path; - PathService::Get(chrome::DIR_TEST_DATA, &path); - path = path.AppendASCII("chromeos"); - path = path.AppendASCII("bluetooth"); - path = path.AppendASCII(file); - return path; - } -}; - -TEST_F(BluetoothServiceRecordTest, RfcommService) { - std::string xml_data; - file_util::ReadFileToString(GetTestDataFilePath("rfcomm.xml"), &xml_data); - - BluetoothServiceRecord service_record(kAddress, xml_data); - EXPECT_EQ(kAddress, service_record.address()); - EXPECT_EQ("Headset Audio Gateway", service_record.name()); - EXPECT_TRUE(service_record.SupportsRfcomm()); - EXPECT_EQ((uint8_t)12, service_record.rfcomm_channel()); - EXPECT_EQ(kCustomUuid, service_record.uuid()); -} - -TEST_F(BluetoothServiceRecordTest, ShortUuid) { - std::string xml_data; - file_util::ReadFileToString(GetTestDataFilePath("short_uuid.xml"), &xml_data); - BluetoothServiceRecord short_uuid_service_record(kAddress, xml_data); - EXPECT_EQ(kSerialUuid, short_uuid_service_record.uuid()); - - xml_data.clear(); - file_util::ReadFileToString( - GetTestDataFilePath("medium_uuid.xml"), &xml_data); - BluetoothServiceRecord medium_uuid_service_record(kAddress, xml_data); - EXPECT_EQ(kSerialUuid, medium_uuid_service_record.uuid()); -} - -TEST_F(BluetoothServiceRecordTest, CleanUuid) { - std::string xml_data; - file_util::ReadFileToString(GetTestDataFilePath("uppercase_uuid.xml"), - &xml_data); - BluetoothServiceRecord service_record(kAddress, xml_data); - EXPECT_EQ(kCustomUuid, service_record.uuid()); - - xml_data.clear(); - file_util::ReadFileToString(GetTestDataFilePath("invalid_uuid.xml"), - &xml_data); - BluetoothServiceRecord invalid_service_record(kAddress, xml_data); - EXPECT_EQ("", invalid_service_record.uuid()); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_socket.h b/chrome/browser/chromeos/bluetooth/bluetooth_socket.h deleted file mode 100644 index 326c0f7..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_socket.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_H_ - -#include "base/memory/ref_counted.h" - -namespace chromeos { - -// BluetoothSocket represents a socket to a specific service on a -// BluetoothDevice. BluetoothSocket objects are ref counted and may outlive -// both the BluetoothDevice and BluetoothAdapter that were involved in their -// creation. -class BluetoothSocket : public base::RefCounted { - public: - // TODO(youngki): Replace this with an opaque id when read/write calls are - // added. This interface is platform-independent and file descriptor is - // linux-specific hence this method has to be renamed. - virtual int fd() const = 0; - - protected: - friend class base::RefCounted; - virtual ~BluetoothSocket() {} -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.cc b/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.cc deleted file mode 100644 index f86f9c5..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.cc +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "base/logging.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" - -namespace chromeos { - -BluetoothSocketChromeOs::BluetoothSocketChromeOs( - const std::string& address, int fd) - : address_(address), - fd_(fd) { -} - -BluetoothSocketChromeOs::~BluetoothSocketChromeOs() { - close(fd_); -} - -// static -scoped_refptr BluetoothSocketChromeOs::CreateBluetoothSocket( - const BluetoothServiceRecord& service_record) { - BluetoothSocketChromeOs* bluetooth_socket = NULL; - if (service_record.SupportsRfcomm()) { - int socket_fd = socket( - AF_BLUETOOTH, SOCK_STREAM | SOCK_NONBLOCK, BTPROTO_RFCOMM); - struct sockaddr_rc socket_address = { 0 }; - socket_address.rc_family = AF_BLUETOOTH; - socket_address.rc_channel = service_record.rfcomm_channel(); - bluetooth_utils::str2ba(service_record.address(), - &socket_address.rc_bdaddr); - - int status = connect(socket_fd, (struct sockaddr *)&socket_address, - sizeof(socket_address)); - int errsv = errno; - if (status == 0 || errno == EINPROGRESS) { - bluetooth_socket = new BluetoothSocketChromeOs(service_record.address(), - socket_fd); - } else { - LOG(ERROR) << "Failed to connect bluetooth socket " - << "(" << service_record.address() << "): " - << "(" << errsv << ") " << strerror(errsv); - close(socket_fd); - } - } - // TODO(bryeung): add support for L2CAP sockets as well. - - return scoped_refptr(bluetooth_socket); -} - -int BluetoothSocketChromeOs::fd() const { - return fd_; -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h b/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h deleted file mode 100644 index 7d0328c..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_socket_chromeos.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ - -#include - -#include "base/memory/ref_counted.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" - -namespace chromeos { - -// This class is an implementation of BluetoothSocket class for Chrome OS -// platform. -class BluetoothSocketChromeOs : public BluetoothSocket { - public: - static scoped_refptr CreateBluetoothSocket( - const BluetoothServiceRecord& service_record); - - // BluetoothSocket override - virtual int fd() const OVERRIDE; - - protected: - virtual ~BluetoothSocketChromeOs(); - - private: - BluetoothSocketChromeOs(const std::string& address, int fd); - - const std::string address_; - const int fd_; - - DISALLOW_COPY_AND_ASSIGN(BluetoothSocketChromeOs); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_utils.cc b/chrome/browser/chromeos/bluetooth/bluetooth_utils.cc deleted file mode 100644 index 02643c6..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_utils.cc +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" - -#include - -#include - -#include "base/logging.h" -#include "base/string_number_conversions.h" -#include "base/string_util.h" - -namespace { -static const char* kCommonUuidPostfix = "-0000-1000-8000-00805f9b34fb"; -static const char* kCommonUuidPrefix = "0000"; -static const int kUuidSize = 36; -} // namespace - -namespace chromeos { -namespace bluetooth_utils { - -bool str2ba(const std::string& in_address, bdaddr_t* out_address) { - if (!out_address) - return false; - - memset(out_address, 0, sizeof(*out_address)); - - if (in_address.size() != 17) - return false; - - std::string numbers_only; - for (int i = 0; i < 6; ++i) { - numbers_only += in_address.substr(i * 3, 2); - } - - std::vector address_bytes; - if (base::HexStringToBytes(numbers_only, &address_bytes)) { - if (address_bytes.size() == 6) { - for (int i = 0; i < 6; ++i) { - out_address->b[5 - i] = address_bytes[i]; - } - return true; - } - } - - return false; -} - -std::string CanonicalUuid(std::string uuid) { - if (uuid.empty()) - return ""; - - if (uuid.size() < 11 && uuid.find("0x") == 0) - uuid = uuid.substr(2); - - if (!(uuid.size() == 4 || uuid.size() == 8 || uuid.size() == 36)) - return ""; - - if (uuid.size() == 4 || uuid.size() == 8) { - for (size_t i = 0; i < uuid.size(); ++i) { - if (!IsHexDigit(uuid[i])) - return ""; - } - - if (uuid.size() == 4) - return kCommonUuidPrefix + uuid + kCommonUuidPostfix; - - return uuid + kCommonUuidPostfix; - } - - std::string uuid_result(uuid); - for (int i = 0; i < kUuidSize; ++i) { - if (i == 8 || i == 13 || i == 18 || i == 23) { - if (uuid[i] != '-') - return ""; - } else { - if (!IsHexDigit(uuid[i])) - return ""; - uuid_result[i] = tolower(uuid[i]); - } - } - return uuid_result; -} - -} // namespace bluetooth_utils -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_utils.h b/chrome/browser/chromeos/bluetooth/bluetooth_utils.h deleted file mode 100644 index 78f8ff5..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_utils.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_UTILS_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_UTILS_H_ - -#include - -#include - -namespace chromeos { -namespace bluetooth_utils { - -// Converts a bluetooth address in the format "B0:D0:9C:0F:3A:2D" into a -// bdaddr_t struct. Returns true on success, false on failure. The contents -// of |out_address| are zeroed on failure. -// Note that the order is reversed upon conversion. For example, -// "B0:D0:9C:0F:3A:2D" -> {"0x2d", "0x3a", "0x0f", "0x9c", "0xd0", "0xb0"} -bool str2ba(const std::string& in_address, bdaddr_t* out_address); - -// Takes a 4, 8 or 36 character UUID, validates it and returns it in 36 -// character format with all hex digits lower case. If |uuid| is invalid, the -// empty string is returned. -// -// Valid inputs are: -// XXXX -// 0xXXXX -// XXXXXXXX -// 0xXXXXXXXX -// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX -std::string CanonicalUuid(std::string uuid); - -} // namespace bluetooth_utils -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_BLUETOOTH_UTILS_H_ - diff --git a/chrome/browser/chromeos/bluetooth/bluetooth_utils_unittest.cc b/chrome/browser/chromeos/bluetooth/bluetooth_utils_unittest.cc deleted file mode 100644 index 6dad3a0..0000000 --- a/chrome/browser/chromeos/bluetooth/bluetooth_utils_unittest.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2012 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 - -#include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace chromeos { - -TEST(BluetoothUtilsTest, str2ba) { - bdaddr_t bluetooth_address; - - EXPECT_TRUE(bluetooth_utils::str2ba("01:02:03:0A:10:A0", &bluetooth_address)); - EXPECT_EQ(1, bluetooth_address.b[5]); - EXPECT_EQ(2, bluetooth_address.b[4]); - EXPECT_EQ(3, bluetooth_address.b[3]); - EXPECT_EQ(10, bluetooth_address.b[2]); - EXPECT_EQ(16, bluetooth_address.b[1]); - EXPECT_EQ(160, bluetooth_address.b[0]); - - EXPECT_FALSE(bluetooth_utils::str2ba("obviously wrong", &bluetooth_address)); - EXPECT_FALSE(bluetooth_utils::str2ba("00:00", &bluetooth_address)); - EXPECT_FALSE(bluetooth_utils::str2ba("00:00:00:00:00:00:00", - &bluetooth_address)); - EXPECT_FALSE(bluetooth_utils::str2ba("01:02:03:0A:10:A0", NULL)); -} - -TEST(BluetoothUtilsTest, CanonicalUuid) { - // Does nothing for an already canonical UUID - EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", - bluetooth_utils::CanonicalUuid("00001101-0000-1000-8000-00805f9b34fb")); - - // Rejects misformatted - EXPECT_EQ("", bluetooth_utils::CanonicalUuid("1101a")); - EXPECT_EQ("", bluetooth_utils::CanonicalUuid("Z101")); - EXPECT_EQ("", bluetooth_utils::CanonicalUuid("0000-1101")); - EXPECT_EQ("", bluetooth_utils::CanonicalUuid("0000Z101")); - EXPECT_EQ("", - bluetooth_utils::CanonicalUuid("0001101-0000-1000-8000-00805f9b34fb")); - EXPECT_EQ("", - bluetooth_utils::CanonicalUuid("Z0001101-0000-1000-8000-00805f9b34fb")); - EXPECT_EQ("", - bluetooth_utils::CanonicalUuid("00001101 0000-1000-8000-00805f9b34fb")); - EXPECT_EQ("", - bluetooth_utils::CanonicalUuid("00001101-0000:1000-8000-00805f9b34fb")); - EXPECT_EQ("", - bluetooth_utils::CanonicalUuid("00001101-0000-1000;8000-00805f9b34fb")); - EXPECT_EQ("", - bluetooth_utils::CanonicalUuid("00001101-0000-1000-8000000805f9b34fb")); - - // Lower case - EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", - bluetooth_utils::CanonicalUuid("00001101-0000-1000-8000-00805F9B34FB")); - - // Short to full - EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", - bluetooth_utils::CanonicalUuid("1101")); - EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", - bluetooth_utils::CanonicalUuid("0x1101")); - EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", - bluetooth_utils::CanonicalUuid("00001101")); - EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", - bluetooth_utils::CanonicalUuid("0x00001101")); - - // No 0x prefix on 36 character - EXPECT_EQ("", - bluetooth_utils::CanonicalUuid("0x00001101-0000-1000-8000-00805f9b34fb")); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.cc b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.cc deleted file mode 100644 index b3e6375..0000000 --- a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.cc +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h" - -namespace chromeos { - -MockBluetoothAdapter::Observer::Observer() {} -MockBluetoothAdapter::Observer::~Observer() {} - -MockBluetoothAdapter::MockBluetoothAdapter(const std::string& address, - const std::string& name) { - address_ = address; - name_ = name; -} - -MockBluetoothAdapter::~MockBluetoothAdapter() {} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h deleted file mode 100644 index ba94c20..0000000 --- a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_TEST_MOCK_BLUETOOTH_ADAPTER_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_TEST_MOCK_BLUETOOTH_ADAPTER_H_ - -#include - -#include "base/callback.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" -#include "chromeos/dbus/bluetooth_out_of_band_client.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace chromeos { - -class MockBluetoothAdapter : public BluetoothAdapter { - public: - class Observer : public BluetoothAdapter::Observer { - public: - Observer(); - virtual ~Observer(); - - MOCK_METHOD2(AdapterPresentChanged, void(BluetoothAdapter*, bool)); - MOCK_METHOD2(AdapterPoweredChanged, void(BluetoothAdapter*, bool)); - MOCK_METHOD2(AdapterDiscoveringChanged, void(BluetoothAdapter*, bool)); - MOCK_METHOD2(DeviceAdded, void(BluetoothAdapter*, BluetoothDevice*)); - MOCK_METHOD2(DeviceChanged, void(BluetoothAdapter*, BluetoothDevice*)); - MOCK_METHOD2(DeviceRemoved, void(BluetoothAdapter*, BluetoothDevice*)); - }; - - MockBluetoothAdapter(const std::string& address, const std::string& name); - - MOCK_METHOD1(AddObserver, void(BluetoothAdapter::Observer*)); - MOCK_METHOD1(RemoveObserver, void(BluetoothAdapter::Observer*)); - MOCK_CONST_METHOD0(IsPresent, bool()); - MOCK_CONST_METHOD0(IsPowered, bool()); - MOCK_METHOD3(SetPowered, - void(bool discovering, - const base::Closure& callback, - const ErrorCallback& error_callback)); - MOCK_CONST_METHOD0(IsDiscovering, bool()); - MOCK_METHOD3(SetDiscovering, - void(bool discovering, - const base::Closure& callback, - const ErrorCallback& error_callback)); - MOCK_CONST_METHOD0(GetDevices, BluetoothAdapter::ConstDeviceList()); - MOCK_METHOD1(GetDevice, BluetoothDevice*(const std::string& address)); - MOCK_CONST_METHOD1(GetDevice, - const BluetoothDevice*(const std::string& address)); - MOCK_METHOD2( - ReadLocalOutOfBandPairingData, - void(const BluetoothOutOfBandPairingDataCallback& callback, - const ErrorCallback& error_callback)); - protected: - virtual ~MockBluetoothAdapter(); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_TEST_MOCK_BLUETOOTH_ADAPTER_H_ diff --git a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.cc b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.cc deleted file mode 100644 index 1387fd2..0000000 --- a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.cc +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2012 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 "base/utf_string_conversions.h" -#include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h" - -namespace chromeos { - -MockBluetoothDevice::MockBluetoothDevice(MockBluetoothAdapter* adapter, - const std::string& name, - const std::string& address, - bool paired, - bool bonded, - bool connected) - : name_(UTF8ToUTF16(name)), - address_(address) { - ON_CALL(*this, GetName()) - .WillByDefault(testing::Return(name_)); - ON_CALL(*this, address()) - .WillByDefault(testing::ReturnRef(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, ExpectingPinCode()) - .WillByDefault(testing::Return(false)); - ON_CALL(*this, ExpectingPasskey()) - .WillByDefault(testing::Return(false)); - ON_CALL(*this, ExpectingConfirmation()) - .WillByDefault(testing::Return(false)); - ON_CALL(*this, GetServices()) - .WillByDefault(testing::ReturnRef(service_list_)); -} - -MockBluetoothDevice::~MockBluetoothDevice() {} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h b/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h deleted file mode 100644 index 650928c..0000000 --- a/chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_BLUETOOTH_TEST_MOCK_BLUETOOTH_DEVICE_H_ -#define CHROME_BROWSER_CHROMEOS_BLUETOOTH_TEST_MOCK_BLUETOOTH_DEVICE_H_ - -#include - -#include "base/string16.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" -#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace chromeos { - -class MockBluetoothDevice : public BluetoothDevice { - public: - MockBluetoothDevice(MockBluetoothAdapter* adapter, - 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(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_METHOD2(GetServiceRecords, - void(const BluetoothDevice::ServiceRecordsCallback&, - const BluetoothDevice::ErrorCallback&)); - MOCK_CONST_METHOD1(ProvidesServiceWithUUID, bool(const std::string&)); - MOCK_METHOD2(ProvidesServiceWithName, - void(const std::string&, - const BluetoothDevice::ProvidesServiceCallback&)); - MOCK_CONST_METHOD0(ExpectingPinCode, bool()); - MOCK_CONST_METHOD0(ExpectingPasskey, bool()); - MOCK_CONST_METHOD0(ExpectingConfirmation, bool()); - MOCK_METHOD3(Connect, - void(BluetoothDevice::PairingDelegate* pairnig_delegate, - const base::Closure& callback, - const BluetoothDevice::ErrorCallback& error_callback)); - MOCK_METHOD1(SetPinCode, void(const std::string&)); - MOCK_METHOD1(SetPasskey, void(uint32)); - MOCK_METHOD0(ConfirmPairing, void()); - MOCK_METHOD0(RejectPairing, void()); - MOCK_METHOD0(CancelPairing, void()); - MOCK_METHOD2(Disconnect, - void(const base::Closure& callback, - const BluetoothDevice::ErrorCallback& error_callback)); - MOCK_METHOD1(Forget, void(const BluetoothDevice::ErrorCallback&)); - MOCK_METHOD2(ConnectToService, - void(const std::string&, - const BluetoothDevice::SocketCallback&)); - - MOCK_METHOD3(SetOutOfBandPairingData, - void(const chromeos::BluetoothOutOfBandPairingData& data, - const base::Closure& callback, - const BluetoothDevice::ErrorCallback& error_callback)); - MOCK_METHOD2(ClearOutOfBandPairingData, - void(const base::Closure& callback, - const BluetoothDevice::ErrorCallback& error_callback)); - - private: - string16 name_; - std::string address_; - BluetoothDevice::ServiceList service_list_; -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_BLUETOOTH_TEST_MOCK_BLUETOOTH_DEVICE_H_ diff --git a/chrome/browser/chromeos/extensions/bluetooth_event_router.cc b/chrome/browser/chromeos/extensions/bluetooth_event_router.cc deleted file mode 100644 index 64331bf..0000000 --- a/chrome/browser/chromeos/extensions/bluetooth_event_router.cc +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (c) 2012 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 "chrome/browser/chromeos/extensions/bluetooth_event_router.h" - -#include - -#include "base/json/json_writer.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_vector.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device_chromeos.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" -#include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" -#include "chrome/browser/extensions/event_names.h" -#include "chrome/browser/extensions/event_router.h" -#include "chrome/common/extensions/api/experimental_bluetooth.h" - -namespace experimental_bluetooth = extensions::api::experimental_bluetooth; - -namespace chromeos { - -ExtensionBluetoothEventRouter::ExtensionBluetoothEventRouter(Profile* profile) - : profile_(profile), - adapter_(chromeos::BluetoothAdapterFactory::DefaultAdapter()), - next_socket_id_(1) { - DCHECK(profile_); - DCHECK(adapter_.get()); - adapter_->AddObserver(this); -} - -ExtensionBluetoothEventRouter::~ExtensionBluetoothEventRouter() { - adapter_->RemoveObserver(this); - socket_map_.clear(); -} - -int ExtensionBluetoothEventRouter::RegisterSocket( - scoped_refptr socket) { - // If there is a socket registered with the same fd, just return it's id - for (SocketMap::const_iterator i = socket_map_.begin(); - i != socket_map_.end(); ++i) { - if (i->second->fd() == socket->fd()) { - return i->first; - } - } - int return_id = next_socket_id_++; - socket_map_[return_id] = socket; - return return_id; -} - -bool ExtensionBluetoothEventRouter::ReleaseSocket(int id) { - SocketMap::iterator socket_entry = socket_map_.find(id); - if (socket_entry == socket_map_.end()) - return false; - socket_map_.erase(socket_entry); - return true; -} - -scoped_refptr ExtensionBluetoothEventRouter::GetSocket( - int id) { - SocketMap::iterator socket_entry = socket_map_.find(id); - if (socket_entry == socket_map_.end()) - return NULL; - return socket_entry->second; -} - -void ExtensionBluetoothEventRouter::SetResponsibleForDiscovery( - bool responsible) { - responsible_for_discovery_ = responsible; -} - -bool ExtensionBluetoothEventRouter::IsResponsibleForDiscovery() const { - return responsible_for_discovery_; -} - -void ExtensionBluetoothEventRouter::SetSendDiscoveryEvents(bool should_send) { - // At the transition into sending devices, also send past devices that - // were discovered as they will not be discovered again. - if (should_send && !send_discovery_events_) { - for (DeviceList::const_iterator i = discovered_devices_.begin(); - i != discovered_devices_.end(); ++i) { - DispatchDeviceEvent(extensions::event_names::kBluetoothOnDeviceDiscovered, - **i); - } - } - - send_discovery_events_ = should_send; -} - -void ExtensionBluetoothEventRouter::DispatchDeviceEvent( - const char* event_name, const experimental_bluetooth::Device& device) { - scoped_ptr args(new ListValue()); - args->Append(device.ToValue().release()); - profile_->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, - args.Pass(), - NULL, - GURL()); -} - -void ExtensionBluetoothEventRouter::AdapterPresentChanged( - chromeos::BluetoothAdapter* adapter, bool present) { - if (adapter != adapter_.get()) { - DVLOG(1) << "Ignoring event for adapter " << adapter->address(); - return; - } - - DispatchBooleanValueEvent( - extensions::event_names::kBluetoothOnAvailabilityChanged, - present); -} - -void ExtensionBluetoothEventRouter::AdapterPoweredChanged( - chromeos::BluetoothAdapter* adapter, bool has_power) { - if (adapter != adapter_.get()) { - DVLOG(1) << "Ignoring event for adapter " << adapter->address(); - return; - } - - DispatchBooleanValueEvent( - extensions::event_names::kBluetoothOnPowerChanged, - has_power); -} - -void ExtensionBluetoothEventRouter::AdapterDiscoveringChanged( - chromeos::BluetoothAdapter* adapter, bool discovering) { - if (adapter != adapter_.get()) { - DVLOG(1) << "Ignoring event for adapter " << adapter->address(); - return; - } - - if (!discovering) { - send_discovery_events_ = false; - responsible_for_discovery_ = false; - discovered_devices_.clear(); - } - - DispatchBooleanValueEvent( - extensions::event_names::kBluetoothOnDiscoveringChanged, - discovering); -} - -void ExtensionBluetoothEventRouter::DeviceAdded( - chromeos::BluetoothAdapter* adapter, chromeos::BluetoothDevice* device) { - if (adapter != adapter_.get()) { - DVLOG(1) << "Ignoring event for adapter " << adapter->address(); - return; - } - - experimental_bluetooth::Device* extension_device = - new experimental_bluetooth::Device(); - experimental_bluetooth::BluetoothDeviceToApiDevice(*device, extension_device); - discovered_devices_.push_back(extension_device); - - if (!send_discovery_events_) - return; - - DispatchDeviceEvent(extensions::event_names::kBluetoothOnDeviceDiscovered, - *extension_device); -} - -void ExtensionBluetoothEventRouter::DispatchBooleanValueEvent( - const char* event_name, bool value) { - scoped_ptr args(new ListValue()); - args->Append(Value::CreateBooleanValue(value)); - profile_->GetExtensionEventRouter()->DispatchEventToRenderers( - event_name, args.Pass(), NULL, GURL()); -} - -} // namespace chromeos diff --git a/chrome/browser/chromeos/extensions/bluetooth_event_router.h b/chrome/browser/chromeos/extensions/bluetooth_event_router.h deleted file mode 100644 index 6715c4e..0000000 --- a/chrome/browser/chromeos/extensions/bluetooth_event_router.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2012 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 CHROME_BROWSER_CHROMEOS_EXTENSIONS_BLUETOOTH_EVENT_ROUTER_H_ -#define CHROME_BROWSER_CHROMEOS_EXTENSIONS_BLUETOOTH_EVENT_ROUTER_H_ - -#include - -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_vector.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/extensions/api/experimental_bluetooth.h" - -namespace chromeos { - -class ExtensionBluetoothEventRouter - : public chromeos::BluetoothAdapter::Observer { - public: - explicit ExtensionBluetoothEventRouter(Profile* profile); - virtual ~ExtensionBluetoothEventRouter(); - - const chromeos::BluetoothAdapter& adapter() const { return *adapter_.get(); } - - // GetMutableAdapter will never return NULL. - chromeos::BluetoothAdapter* GetMutableAdapter() { return adapter_.get(); } - - // Register the BluetoothSocket |socket| for use by the extensions system. - // This class will hold onto the socket for its lifetime, or until - // ReleaseSocket is called for the socket. Returns an id for the socket. - int RegisterSocket(scoped_refptr socket); - - // Release the BluetoothSocket corresponding to |id|. Returns true if - // the socket was found and released, false otherwise. - bool ReleaseSocket(int id); - - // Get the BluetoothSocket corresponding to |id|. - scoped_refptr GetSocket(int id); - - // Sets whether this Profile is responsible for the discovering state of the - // adapter. - void SetResponsibleForDiscovery(bool responsible); - bool IsResponsibleForDiscovery() const; - - // Sets whether or not DeviceAdded events will be dispatched to extensions. - void SetSendDiscoveryEvents(bool should_send); - - // Dispatch an event that takes a device as a parameter to all renderers. - void DispatchDeviceEvent( - const char* event_name, - const extensions::api::experimental_bluetooth::Device& device); - - // Override from chromeos::BluetoothAdapter::Observer - virtual void AdapterPresentChanged(chromeos::BluetoothAdapter* adapter, - bool present) OVERRIDE; - virtual void AdapterPoweredChanged(chromeos::BluetoothAdapter* adapter, - bool has_power) OVERRIDE; - virtual void AdapterDiscoveringChanged(chromeos::BluetoothAdapter* adapter, - bool discovering) OVERRIDE; - virtual void DeviceAdded(chromeos::BluetoothAdapter* adapter, - chromeos::BluetoothDevice* device) OVERRIDE; - - // Exposed for testing. - void SetAdapterForTest(chromeos::BluetoothAdapter* adapter) { - adapter_ = adapter; - } - private: - void DispatchBooleanValueEvent(const char* event_name, bool value); - - bool send_discovery_events_; - bool responsible_for_discovery_; - - Profile* profile_; - scoped_refptr adapter_; - - // The next id to use for referring to a BluetoothSocket. We avoid using - // the fd of the socket because we don't want to leak that information to - // the extension javascript. - int next_socket_id_; - - typedef std::map > SocketMap; - SocketMap socket_map_; - - typedef ScopedVector - DeviceList; - DeviceList discovered_devices_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionBluetoothEventRouter); -}; - -} // namespace chromeos - -#endif // CHROME_BROWSER_CHROMEOS_EXTENSIONS_BLUETOOTH_EVENT_ROUTER_H_ diff --git a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc index 6221139..eb000b1 100644 --- a/chrome/browser/chromeos/system/ash_system_tray_delegate.cc +++ b/chrome/browser/chromeos/system/ash_system_tray_delegate.cc @@ -30,9 +30,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/accessibility/accessibility_util.h" #include "chrome/browser/chromeos/audio/audio_handler.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/network_library.h" #include "chrome/browser/chromeos/drive/drive_system_service.h" @@ -72,6 +69,9 @@ #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/user_metrics.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/bluetooth_device.h" #include "grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" @@ -154,7 +154,7 @@ class SystemTrayDelegate : public ash::SystemTrayDelegate, public content::NotificationObserver, public input_method::InputMethodManager::Observer, public system::TimezoneSettings::Observer, - public BluetoothAdapter::Observer, + public device::BluetoothAdapter::Observer, public SystemKeyEventListener::CapsLockObserver, public ash::NetworkTrayDelegate { public: @@ -216,7 +216,7 @@ class SystemTrayDelegate : public ash::SystemTrayDelegate, network_icon_->SetResourceColorTheme(NetworkMenuIcon::COLOR_LIGHT); network_icon_dark_->SetResourceColorTheme(NetworkMenuIcon::COLOR_DARK); - bluetooth_adapter_ = BluetoothAdapterFactory::DefaultAdapter(); + bluetooth_adapter_ = device::BluetoothAdapterFactory::DefaultAdapter(); bluetooth_adapter_->AddObserver(this); } @@ -362,9 +362,10 @@ class SystemTrayDelegate : public ash::SystemTrayDelegate, virtual void GetAvailableBluetoothDevices( ash::BluetoothDeviceList* list) OVERRIDE { - BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices(); + device::BluetoothAdapter::DeviceList devices = + bluetooth_adapter_->GetDevices(); for (size_t i = 0; i < devices.size(); ++i) { - BluetoothDevice* device = devices[i]; + device::BluetoothDevice* device = devices[i]; if (!device->IsPaired()) continue; ash::BluetoothDeviceInfo info; @@ -376,7 +377,7 @@ class SystemTrayDelegate : public ash::SystemTrayDelegate, } virtual void ToggleBluetoothConnection(const std::string& address) OVERRIDE { - BluetoothDevice* device = bluetooth_adapter_->GetDevice(address); + device::BluetoothDevice* device = bluetooth_adapter_->GetDevice(address); if (!device) return; if (device->IsConnected()) { @@ -1155,34 +1156,34 @@ class SystemTrayDelegate : public ash::SystemTrayDelegate, } // Overridden from BluetoothAdapter::Observer. - virtual void AdapterPresentChanged(BluetoothAdapter* adapter, + virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter, bool present) OVERRIDE { NotifyRefreshBluetooth(); } - virtual void AdapterPoweredChanged(BluetoothAdapter* adapter, + virtual void AdapterPoweredChanged(device::BluetoothAdapter* adapter, bool powered) OVERRIDE { NotifyRefreshBluetooth(); } - virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter, + virtual void AdapterDiscoveringChanged(device::BluetoothAdapter* adapter, bool discovering) OVERRIDE { // TODO: Perhaps start/stop throbbing the icon, or some other visual // effects? } - virtual void DeviceAdded(BluetoothAdapter* adapter, - BluetoothDevice* device) OVERRIDE { + virtual void DeviceAdded(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE { NotifyRefreshBluetooth(); } - virtual void DeviceChanged(BluetoothAdapter* adapter, - BluetoothDevice* device) OVERRIDE { + virtual void DeviceChanged(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE { NotifyRefreshBluetooth(); } - virtual void DeviceRemoved(BluetoothAdapter* adapter, - BluetoothDevice* device) OVERRIDE { + virtual void DeviceRemoved(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE { NotifyRefreshBluetooth(); } @@ -1251,7 +1252,7 @@ class SystemTrayDelegate : public ash::SystemTrayDelegate, std::string last_connection_string_; - scoped_refptr bluetooth_adapter_; + scoped_refptr bluetooth_adapter_; BooleanPrefMember accessibility_enabled_; diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc index 12b4350..6e425a4 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api.cc @@ -10,45 +10,51 @@ #include +#include "base/memory/ref_counted.h" #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" +#include "chrome/browser/extensions/bluetooth_event_router.h" #include "chrome/browser/extensions/event_names.h" #include "chrome/browser/extensions/event_router.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/experimental_bluetooth.h" #include "content/public/browser/browser_thread.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" +#include "device/bluetooth/bluetooth_service_record.h" +#include "device/bluetooth/bluetooth_socket.h" +#include "device/bluetooth/bluetooth_utils.h" #if defined(OS_CHROMEOS) -#include "base/memory/ref_counted.h" #include "base/safe_strerror_posix.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_service_record.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_utils.h" -#include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" -#include "chromeos/dbus/bluetooth_out_of_band_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" +#endif + +using device::BluetoothAdapter; +using device::BluetoothDevice; +using device::BluetoothServiceRecord; +using device::BluetoothSocket; namespace { -chromeos::ExtensionBluetoothEventRouter* GetEventRouter(Profile* profile) { +extensions::ExtensionBluetoothEventRouter* GetEventRouter(Profile* profile) { return profile->GetExtensionService()->bluetooth_event_router(); } -const chromeos::BluetoothAdapter& GetAdapter(Profile* profile) { +const BluetoothAdapter* GetAdapter(Profile* profile) { return GetEventRouter(profile)->adapter(); } -chromeos::BluetoothAdapter* GetMutableAdapter(Profile* profile) { - chromeos::BluetoothAdapter* adapter = - GetEventRouter(profile)->GetMutableAdapter(); - CHECK(adapter); +BluetoothAdapter* GetMutableAdapter(Profile* profile) { + BluetoothAdapter* adapter = GetEventRouter(profile)->GetMutableAdapter(); return adapter; } +bool IsBluetoothSupported(Profile* profile) { + return GetAdapter(profile) != NULL; +} + } // namespace -#endif namespace { @@ -59,6 +65,8 @@ const char kCouldNotSetOutOfBandPairingData[] = const char kFailedToConnect[] = "Connection failed"; const char kInvalidDevice[] = "Invalid device"; const char kInvalidUuid[] = "Invalid UUID"; +const char kPlatformNotSupported[] = + "This operation is not supported on your platform"; const char kServiceDiscoveryFailed[] = "Service discovery failed"; const char kSocketNotFoundError[] = "Socket not found: invalid socket id"; const char kStartDiscoveryFailed[] = "Starting discovery failed"; @@ -78,25 +86,43 @@ namespace Write = extensions::api::experimental_bluetooth::Write; namespace extensions { namespace api { -#if defined(OS_CHROMEOS) - bool BluetoothIsAvailableFunction::RunImpl() { - SetResult(Value::CreateBooleanValue(GetAdapter(profile()).IsPresent())); + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + + SetResult(Value::CreateBooleanValue(GetAdapter(profile())->IsPresent())); return true; } bool BluetoothIsPoweredFunction::RunImpl() { - SetResult(Value::CreateBooleanValue(GetAdapter(profile()).IsPowered())); + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + + SetResult(Value::CreateBooleanValue(GetAdapter(profile())->IsPowered())); return true; } bool BluetoothGetAddressFunction::RunImpl() { - SetResult(Value::CreateStringValue(GetAdapter(profile()).address())); + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + + SetResult(Value::CreateStringValue(GetAdapter(profile())->address())); return true; } bool BluetoothGetNameFunction::RunImpl() { - SetResult(Value::CreateStringValue(GetAdapter(profile()).name())); + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + + SetResult(Value::CreateStringValue(GetAdapter(profile())->name())); return true; } @@ -105,7 +131,7 @@ BluetoothGetDevicesFunction::BluetoothGetDevicesFunction() device_events_sent_(0) {} void BluetoothGetDevicesFunction::DispatchDeviceSearchResult( - const chromeos::BluetoothDevice& device) { + const BluetoothDevice& device) { experimental_bluetooth::Device extension_device; experimental_bluetooth::BluetoothDeviceToApiDevice(device, &extension_device); GetEventRouter(profile())->DispatchDeviceEvent( @@ -116,8 +142,7 @@ void BluetoothGetDevicesFunction::DispatchDeviceSearchResult( } void BluetoothGetDevicesFunction::ProvidesServiceCallback( - const chromeos::BluetoothDevice* device, - bool providesService) { + const BluetoothDevice* device, bool providesService) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); CHECK(device); @@ -145,6 +170,11 @@ void BluetoothGetDevicesFunction::FinishDeviceSearch() { } bool BluetoothGetDevicesFunction::RunImpl() { + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); scoped_ptr params(GetDevices::Params::Create(*args_)); @@ -153,7 +183,7 @@ bool BluetoothGetDevicesFunction::RunImpl() { std::string uuid; if (options.uuid.get() != NULL) { - uuid = chromeos::bluetooth_utils::CanonicalUuid(*options.uuid.get()); + uuid = device::bluetooth_utils::CanonicalUuid(*options.uuid.get()); if (uuid.empty()) { SetError(kInvalidUuid); return false; @@ -162,11 +192,11 @@ bool BluetoothGetDevicesFunction::RunImpl() { CHECK_EQ(0, callbacks_pending_); - chromeos::BluetoothAdapter::DeviceList devices = + BluetoothAdapter::DeviceList devices = GetMutableAdapter(profile())->GetDevices(); - for (chromeos::BluetoothAdapter::DeviceList::iterator i = devices.begin(); + for (BluetoothAdapter::DeviceList::iterator i = devices.begin(); i != devices.end(); ++i) { - chromeos::BluetoothDevice* device = *i; + BluetoothDevice* device = *i; CHECK(device); if (!uuid.empty() && !(device->ProvidesServiceWithUUID(uuid))) @@ -197,10 +227,10 @@ bool BluetoothGetDevicesFunction::RunImpl() { void BluetoothGetServicesFunction::GetServiceRecordsCallback( base::ListValue* services, - const chromeos::BluetoothDevice::ServiceRecordList& records) { - for (chromeos::BluetoothDevice::ServiceRecordList::const_iterator i = - records.begin(); i != records.end(); ++i) { - const chromeos::BluetoothServiceRecord& record = **i; + const BluetoothDevice::ServiceRecordList& records) { + for (BluetoothDevice::ServiceRecordList::const_iterator i = records.begin(); + i != records.end(); ++i) { + const BluetoothServiceRecord& record = **i; experimental_bluetooth::ServiceRecord api_record; api_record.name = record.name(); if (!record.uuid().empty()) @@ -217,11 +247,16 @@ void BluetoothGetServicesFunction::OnErrorCallback() { } bool BluetoothGetServicesFunction::RunImpl() { + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + scoped_ptr params(GetServices::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); const experimental_bluetooth::GetServicesOptions& options = params->options; - chromeos::BluetoothDevice* device = + BluetoothDevice* device = GetMutableAdapter(profile())->GetDevice(options.device_address); if (!device) { SetError(kInvalidDevice); @@ -242,9 +277,9 @@ bool BluetoothGetServicesFunction::RunImpl() { } void BluetoothConnectFunction::ConnectToServiceCallback( - const chromeos::BluetoothDevice* device, + const BluetoothDevice* device, const std::string& service_uuid, - scoped_refptr socket) { + scoped_refptr socket) { if (socket.get()) { int socket_id = GetEventRouter(profile())->RegisterSocket(socket); @@ -262,18 +297,23 @@ void BluetoothConnectFunction::ConnectToServiceCallback( } bool BluetoothConnectFunction::RunImpl() { + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + scoped_ptr params(Connect::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); const experimental_bluetooth::ConnectOptions& options = params->options; - std::string uuid = chromeos::bluetooth_utils::CanonicalUuid( + std::string uuid = device::bluetooth_utils::CanonicalUuid( options.service_uuid); if (uuid.empty()) { SetError(kInvalidUuid); return false; } - chromeos::BluetoothDevice* device = + BluetoothDevice* device = GetMutableAdapter(profile())->GetDevice(options.device_address); if (!device) { SetError(kInvalidDevice); @@ -295,6 +335,9 @@ bool BluetoothDisconnectFunction::RunImpl() { return GetEventRouter(profile())->ReleaseSocket(options.socket_id); } +BluetoothReadFunction::BluetoothReadFunction() {} +BluetoothReadFunction::~BluetoothReadFunction() {} + bool BluetoothReadFunction::Prepare() { scoped_ptr params(Read::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); @@ -311,8 +354,11 @@ bool BluetoothReadFunction::Prepare() { } void BluetoothReadFunction::Work() { + if (!socket_.get()) + return; + +#if defined(OS_CHROMEOS) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - CHECK(socket_.get() != NULL); char* all_bytes = NULL; ssize_t buffer_size = 0; @@ -343,12 +389,16 @@ void BluetoothReadFunction::Work() { if (!success_) SetError(safe_strerror(errsv)); +#endif } bool BluetoothReadFunction::Respond() { return success_; } +BluetoothWriteFunction::BluetoothWriteFunction() {} +BluetoothWriteFunction::~BluetoothWriteFunction() {} + bool BluetoothWriteFunction::Prepare() { // TODO(bryeung): update to new-style parameter passing when ArrayBuffer // support is added @@ -377,6 +427,7 @@ void BluetoothWriteFunction::Work() { if (socket_.get() == NULL) return; +#if defined(OS_CHROMEOS) ssize_t bytes_written = write(socket_->fd(), data_to_write_->GetBuffer(), data_to_write_->GetSize()); int errsv = errno; @@ -391,6 +442,7 @@ void BluetoothWriteFunction::Work() { if (!success_) SetError(safe_strerror(errsv)); +#endif } bool BluetoothWriteFunction::Respond() { @@ -407,6 +459,11 @@ void BluetoothSetOutOfBandPairingDataFunction::OnErrorCallback() { } bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + // TODO(bryeung): update to new-style parameter passing when ArrayBuffer // support is added DictionaryValue* options; @@ -414,8 +471,7 @@ bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { std::string address; EXTENSION_FUNCTION_VALIDATE(options->GetString("deviceAddress", &address)); - chromeos::BluetoothDevice* device = - GetMutableAdapter(profile())->GetDevice(address); + BluetoothDevice* device = GetMutableAdapter(profile())->GetDevice(address); if (!device) { SetError(kInvalidDevice); return false; @@ -425,22 +481,22 @@ bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { DictionaryValue* data_in; EXTENSION_FUNCTION_VALIDATE(options->GetDictionary("data", &data_in)); - chromeos::BluetoothOutOfBandPairingData data_out; + device::BluetoothOutOfBandPairingData data_out; base::BinaryValue* tmp_data; EXTENSION_FUNCTION_VALIDATE(data_in->GetBinary("hash", &tmp_data)); EXTENSION_FUNCTION_VALIDATE( - tmp_data->GetSize() == chromeos::kBluetoothOutOfBandPairingDataSize); + tmp_data->GetSize() == device::kBluetoothOutOfBandPairingDataSize); memcpy(data_out.hash, reinterpret_cast(tmp_data->GetBuffer()), - chromeos::kBluetoothOutOfBandPairingDataSize); + device::kBluetoothOutOfBandPairingDataSize); EXTENSION_FUNCTION_VALIDATE(data_in->GetBinary("randomizer", &tmp_data)); EXTENSION_FUNCTION_VALIDATE( - tmp_data->GetSize() == chromeos::kBluetoothOutOfBandPairingDataSize); + tmp_data->GetSize() == device::kBluetoothOutOfBandPairingDataSize); memcpy(data_out.randomizer, reinterpret_cast(tmp_data->GetBuffer()), - chromeos::kBluetoothOutOfBandPairingDataSize); + device::kBluetoothOutOfBandPairingDataSize); device->SetOutOfBandPairingData( data_out, @@ -460,13 +516,13 @@ bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { } void BluetoothGetLocalOutOfBandPairingDataFunction::ReadCallback( - const chromeos::BluetoothOutOfBandPairingData& data) { + const device::BluetoothOutOfBandPairingData& data) { base::BinaryValue* hash = base::BinaryValue::CreateWithCopiedBuffer( reinterpret_cast(data.hash), - chromeos::kBluetoothOutOfBandPairingDataSize); + device::kBluetoothOutOfBandPairingDataSize); base::BinaryValue* randomizer = base::BinaryValue::CreateWithCopiedBuffer( reinterpret_cast(data.randomizer), - chromeos::kBluetoothOutOfBandPairingDataSize); + device::kBluetoothOutOfBandPairingDataSize); // TODO(bryeung): convert to experimental_bluetooth::OutOfBandPairingData // when ArrayBuffer support within objects is completed. @@ -485,6 +541,11 @@ void BluetoothGetLocalOutOfBandPairingDataFunction::ErrorCallback() { } bool BluetoothGetLocalOutOfBandPairingDataFunction::RunImpl() { + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + GetMutableAdapter(profile())->ReadLocalOutOfBandPairingData( base::Bind(&BluetoothGetLocalOutOfBandPairingDataFunction::ReadCallback, this), @@ -504,6 +565,11 @@ void BluetoothStartDiscoveryFunction::OnErrorCallback() { } bool BluetoothStartDiscoveryFunction::RunImpl() { + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + GetEventRouter(profile())->SetSendDiscoveryEvents(true); // If the adapter is already discovering, there is nothing else to do. @@ -528,6 +594,11 @@ void BluetoothStopDiscoveryFunction::OnErrorCallback() { } bool BluetoothStopDiscoveryFunction::RunImpl() { + if (!IsBluetoothSupported(profile())) { + SetError(kPlatformNotSupported); + return false; + } + GetEventRouter(profile())->SetSendDiscoveryEvents(false); if (GetEventRouter(profile())->IsResponsibleForDiscovery()) { GetMutableAdapter(profile())->SetDiscovering(false, @@ -537,102 +608,5 @@ bool BluetoothStopDiscoveryFunction::RunImpl() { return true; } -#else - -// ----------------------------------------------------------------------------- -// NIY stubs -// ----------------------------------------------------------------------------- -bool BluetoothIsAvailableFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothIsPoweredFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothGetAddressFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothGetNameFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothGetDevicesFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothGetServicesFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothConnectFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothDisconnectFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothReadFunction::Prepare() { - return true; -} - -void BluetoothReadFunction::Work() { -} - -bool BluetoothReadFunction::Respond() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothWriteFunction::Prepare() { - return true; -} - -void BluetoothWriteFunction::Work() { -} - -bool BluetoothWriteFunction::Respond() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothStartDiscoveryFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothStopDiscoveryFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothSetOutOfBandPairingDataFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -bool BluetoothGetLocalOutOfBandPairingDataFunction::RunImpl() { - NOTREACHED() << "Not implemented yet"; - return false; -} - -#endif - -BluetoothReadFunction::BluetoothReadFunction() {} -BluetoothReadFunction::~BluetoothReadFunction() {} - -BluetoothWriteFunction::BluetoothWriteFunction() {} -BluetoothWriteFunction::~BluetoothWriteFunction() {} - } // namespace api } // namespace extensions diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api.h b/chrome/browser/extensions/api/bluetooth/bluetooth_api.h index 4db078a..3ae23b1 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_api.h +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api.h @@ -7,21 +7,17 @@ #include +#include "base/memory/ref_counted.h" #include "chrome/browser/extensions/api/api_function.h" #include "chrome/browser/extensions/extension_function.h" +#include "device/bluetooth/bluetooth_device.h" -#if defined(OS_CHROMEOS) -#include "base/memory/ref_counted.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_socket.h" - -namespace chromeos { +namespace device { class BluetoothSocket; struct BluetoothOutOfBandPairingData; -} // namespace chromeos -#endif +} // namespace device namespace extensions { namespace api { @@ -74,9 +70,7 @@ class BluetoothGetDevicesFunction : public AsyncExtensionFunction { public: DECLARE_EXTENSION_FUNCTION_NAME("experimental.bluetooth.getDevices") -#if defined(OS_CHROMEOS) BluetoothGetDevicesFunction(); -#endif protected: virtual ~BluetoothGetDevicesFunction() {} @@ -85,15 +79,13 @@ class BluetoothGetDevicesFunction : public AsyncExtensionFunction { virtual bool RunImpl() OVERRIDE; private: -#if defined(OS_CHROMEOS) - void DispatchDeviceSearchResult(const chromeos::BluetoothDevice& device); - void ProvidesServiceCallback(const chromeos::BluetoothDevice* device, + void DispatchDeviceSearchResult(const device::BluetoothDevice& device); + void ProvidesServiceCallback(const device::BluetoothDevice* device, bool providesService); void FinishDeviceSearch(); int callbacks_pending_; int device_events_sent_; -#endif }; class BluetoothGetServicesFunction : public AsyncExtensionFunction { @@ -106,13 +98,11 @@ class BluetoothGetServicesFunction : public AsyncExtensionFunction { // ExtensionFunction: virtual bool RunImpl() OVERRIDE; -#if defined(OS_CHROMEOS) private: void GetServiceRecordsCallback( base::ListValue* services, - const chromeos::BluetoothDevice::ServiceRecordList& records); + const device::BluetoothDevice::ServiceRecordList& records); void OnErrorCallback(); -#endif }; class BluetoothConnectFunction : public AsyncExtensionFunction { @@ -125,12 +115,10 @@ class BluetoothConnectFunction : public AsyncExtensionFunction { virtual bool RunImpl() OVERRIDE; private: -#if defined(OS_CHROMEOS) void ConnectToServiceCallback( - const chromeos::BluetoothDevice* device, + const device::BluetoothDevice* device, const std::string& service_uuid, - scoped_refptr socket); -#endif + scoped_refptr socket); }; class BluetoothDisconnectFunction : public SyncExtensionFunction { @@ -158,10 +146,8 @@ class BluetoothReadFunction : public AsyncApiFunction { virtual void Work() OVERRIDE; private: -#if defined(OS_CHROMEOS) bool success_; - scoped_refptr socket_; -#endif + scoped_refptr socket_; }; class BluetoothWriteFunction : public AsyncApiFunction { @@ -178,11 +164,9 @@ class BluetoothWriteFunction : public AsyncApiFunction { virtual void Work() OVERRIDE; private: -#if defined(OS_CHROMEOS) bool success_; const base::BinaryValue* data_to_write_; // memory is owned by args_ - scoped_refptr socket_; -#endif + scoped_refptr socket_; }; class BluetoothSetOutOfBandPairingDataFunction @@ -194,10 +178,8 @@ class BluetoothSetOutOfBandPairingDataFunction protected: virtual ~BluetoothSetOutOfBandPairingDataFunction() {} -#if defined(OS_CHROMEOS) void OnSuccessCallback(); void OnErrorCallback(); -#endif // ExtensionFunction: virtual bool RunImpl() OVERRIDE; @@ -212,10 +194,9 @@ class BluetoothGetLocalOutOfBandPairingDataFunction protected: virtual ~BluetoothGetLocalOutOfBandPairingDataFunction() {} -#if defined(OS_CHROMEOS) - void ReadCallback(const chromeos::BluetoothOutOfBandPairingData& data); + void ReadCallback( + const device::BluetoothOutOfBandPairingData& data); void ErrorCallback(); -#endif // ExtensionFunction: virtual bool RunImpl() OVERRIDE; @@ -231,11 +212,9 @@ class BluetoothStartDiscoveryFunction : public AsyncExtensionFunction { // ExtensionFunction: virtual bool RunImpl() OVERRIDE; -#if defined(OS_CHROMEOS) private: void OnSuccessCallback(); void OnErrorCallback(); -#endif }; class BluetoothStopDiscoveryFunction : public AsyncExtensionFunction { @@ -248,11 +227,9 @@ class BluetoothStopDiscoveryFunction : public AsyncExtensionFunction { // ExtensionFunction: virtual bool RunImpl() OVERRIDE; -#if defined(OS_CHROMEOS) private: void OnSuccessCallback(); void OnErrorCallback(); -#endif }; } // namespace api diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.cc index 5503434..d7e25bc 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.cc +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.cc @@ -4,21 +4,18 @@ #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" -#if defined(OS_CHROMEOS) - #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" #include "chrome/common/extensions/api/experimental_bluetooth.h" +#include "device/bluetooth/bluetooth_device.h" namespace extensions { namespace api { namespace experimental_bluetooth { -// Fill in a Device object from a chromeos::BluetoothDevice. -void BluetoothDeviceToApiDevice( - const chromeos::BluetoothDevice& device, - Device* out) { +// Fill in a Device object from a BluetoothDevice. +void BluetoothDeviceToApiDevice(const device::BluetoothDevice& device, + Device* out) { out->name = UTF16ToUTF8(device.GetName()); out->address = device.address(); out->paired = device.IsPaired(); @@ -27,7 +24,7 @@ void BluetoothDeviceToApiDevice( } // The caller takes ownership of the returned pointer. -base::Value* BluetoothDeviceToValue(const chromeos::BluetoothDevice& device) { +base::Value* BluetoothDeviceToValue(const device::BluetoothDevice& device) { extensions::api::experimental_bluetooth::Device api_device; BluetoothDeviceToApiDevice(device, &api_device); return api_device.ToValue().release(); @@ -36,5 +33,3 @@ base::Value* BluetoothDeviceToValue(const chromeos::BluetoothDevice& device) { } // namespace experimental_bluetooth } // namespace api } // namespace extensions - -#endif diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h b/chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h index cb8d089..364a5d2 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h @@ -5,28 +5,25 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_BLUETOOTH_API_UTILS_H_ #define CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_BLUETOOTH_API_UTILS_H_ -#if defined(OS_CHROMEOS) - #include "base/values.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" #include "chrome/common/extensions/api/experimental_bluetooth.h" +#include "device/bluetooth/bluetooth_device.h" namespace extensions { namespace api { namespace experimental_bluetooth { -// Fill in a Device object from a chromeos::BluetoothDevice. +// Fill in a Device object from a BluetoothDevice. void BluetoothDeviceToApiDevice( - const chromeos::BluetoothDevice& device, + const device::BluetoothDevice& device, Device* out); // The caller takes ownership of the returned pointer. -base::Value* BluetoothDeviceToValue(const chromeos::BluetoothDevice& device); +base::Value* BluetoothDeviceToValue( + const device::BluetoothDevice& device); } // namespace experimental_bluetooth } // namespace api } // namespace extensions -#endif - #endif // CHROME_BROWSER_EXTENSIONS_API_BLUETOOTH_BLUETOOTH_API_UTILS_H_ diff --git a/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc b/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc index 29922d0..562e6c0 100644 --- a/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc +++ b/chrome/browser/extensions/api/bluetooth/bluetooth_apitest_chromeos.cc @@ -4,11 +4,8 @@ #include -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/test/mock_bluetooth_device.h" -#include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" #include "chrome/browser/extensions/api/bluetooth/bluetooth_api.h" +#include "chrome/browser/extensions/bluetooth_event_router.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_service.h" @@ -17,9 +14,17 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "chromeos/dbus/bluetooth_out_of_band_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" +#include "device/bluetooth/test/mock_bluetooth_adapter.h" +#include "device/bluetooth/test/mock_bluetooth_device.h" #include "testing/gmock/include/gmock/gmock.h" +using device::BluetoothAdapter; +using device::BluetoothDevice; +using device::BluetoothOutOfBandPairingData; +using device::MockBluetoothAdapter; +using device::MockBluetoothDevice; using extensions::Extension; namespace utils = extension_function_test_utils; @@ -41,14 +46,14 @@ class BluetoothApiTest : public ExtensionApiTest { virtual void SetUpOnMainThread() OVERRIDE { // The browser will clean this up when it is torn down - mock_adapter_ = new testing::StrictMock( + mock_adapter_ = new testing::StrictMock( kAdapterAddress, kName); event_router()->SetAdapterForTest(mock_adapter_); - device1_.reset(new testing::NiceMock( + device1_.reset(new testing::NiceMock( mock_adapter_, "d1", "11:12:13:14:15:16", true /* paired */, false /* bonded */, true /* connected */)); - device2_.reset(new testing::NiceMock( + device2_.reset(new testing::NiceMock( mock_adapter_, "d2", "21:22:23:24:25:26", false /* paired */, true /* bonded */, false /* connected */)); } @@ -87,11 +92,11 @@ class BluetoothApiTest : public ExtensionApiTest { } protected: - testing::StrictMock* mock_adapter_; - scoped_ptr > device1_; - scoped_ptr > device2_; + testing::StrictMock* mock_adapter_; + scoped_ptr > device1_; + scoped_ptr > device2_; - chromeos::ExtensionBluetoothEventRouter* event_router() { + extensions::ExtensionBluetoothEventRouter* event_router() { return browser()->profile()->GetExtensionService()-> bluetooth_event_router(); } @@ -104,12 +109,12 @@ class BluetoothApiTest : public ExtensionApiTest { static const char kOutOfBandPairingDataHash[] = "0123456789ABCDEh"; static const char kOutOfBandPairingDataRandomizer[] = "0123456789ABCDEr"; -static chromeos::BluetoothOutOfBandPairingData GetOutOfBandPairingData() { - chromeos::BluetoothOutOfBandPairingData data; +static BluetoothOutOfBandPairingData GetOutOfBandPairingData() { + BluetoothOutOfBandPairingData data; memcpy(&(data.hash), kOutOfBandPairingDataHash, - chromeos::kBluetoothOutOfBandPairingDataSize); + device::kBluetoothOutOfBandPairingDataSize); memcpy(&(data.randomizer), kOutOfBandPairingDataRandomizer, - chromeos::kBluetoothOutOfBandPairingDataSize); + device::kBluetoothOutOfBandPairingDataSize); return data; } @@ -119,16 +124,15 @@ static bool CallClosure(const base::Closure& callback) { } static void CallOutOfBandPairingDataCallback( - const chromeos::BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& - callback, - const chromeos::BluetoothAdapter::ErrorCallback& error_callback) { + const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& callback, + const BluetoothAdapter::ErrorCallback& error_callback) { callback.Run(GetOutOfBandPairingData()); } template static void CallProvidesServiceCallback( - const std::string& name, - const chromeos::BluetoothDevice::ProvidesServiceCallback& callback) { + const std::string& name, + const BluetoothDevice::ProvidesServiceCallback& callback) { callback.Run(Value); } @@ -365,7 +369,7 @@ IN_PROC_BROWSER_TEST_F(BluetoothApiTest, Events) { // Load and wait for setup ExtensionTestMessageListener listener("ready", true); - const extensions::Extension* extension = + const Extension* extension = LoadExtension(test_data_dir_.AppendASCII("bluetooth")); GURL page_url = extension->GetResourceURL("test_events.html"); ui_test_utils::NavigateToURL(browser(), page_url); @@ -387,7 +391,7 @@ IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevices) { ResultCatcher catcher; catcher.RestrictToProfile(browser()->profile()); - chromeos::BluetoothAdapter::ConstDeviceList devices; + BluetoothAdapter::ConstDeviceList devices; devices.push_back(device1_.get()); devices.push_back(device2_.get()); @@ -420,12 +424,12 @@ IN_PROC_BROWSER_TEST_F(BluetoothApiTest, GetDevicesConcurrently) { ResultCatcher catcher; catcher.RestrictToProfile(browser()->profile()); - chromeos::BluetoothAdapter::ConstDeviceList devices; + BluetoothAdapter::ConstDeviceList devices; devices.push_back(device1_.get()); // Save the callback to delay execution so that we can force the calls to // happen concurrently. This will be called after the listener is satisfied. - chromeos::BluetoothDevice::ProvidesServiceCallback callback; + BluetoothDevice::ProvidesServiceCallback callback; EXPECT_CALL(*device1_, ProvidesServiceWithName(testing::_, testing::_)) .WillOnce(testing::SaveArg<1>(&callback)); diff --git a/chrome/browser/extensions/bluetooth_event_router.cc b/chrome/browser/extensions/bluetooth_event_router.cc new file mode 100644 index 0000000..90dfefe --- /dev/null +++ b/chrome/browser/extensions/bluetooth_event_router.cc @@ -0,0 +1,176 @@ +// Copyright (c) 2012 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 "chrome/browser/extensions/bluetooth_event_router.h" + +#include + +#include "base/json/json_writer.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_vector.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" +#include "chrome/browser/extensions/event_names.h" +#include "chrome/browser/extensions/event_router.h" +#include "chrome/common/extensions/api/experimental_bluetooth.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/bluetooth_socket.h" + +namespace experimental_bluetooth = extensions::api::experimental_bluetooth; + +namespace extensions { + +ExtensionBluetoothEventRouter::ExtensionBluetoothEventRouter(Profile* profile) + : profile_(profile), + adapter_(device::BluetoothAdapterFactory::DefaultAdapter()), + next_socket_id_(1) { + DCHECK(profile_); + if (adapter_.get()) + adapter_->AddObserver(this); +} + +ExtensionBluetoothEventRouter::~ExtensionBluetoothEventRouter() { + if (adapter_.get()) + adapter_->RemoveObserver(this); + + socket_map_.clear(); +} + +int ExtensionBluetoothEventRouter::RegisterSocket( + scoped_refptr socket) { + // If there is a socket registered with the same fd, just return it's id + for (SocketMap::const_iterator i = socket_map_.begin(); + i != socket_map_.end(); ++i) { + if (i->second->fd() == socket->fd()) { + return i->first; + } + } + int return_id = next_socket_id_++; + socket_map_[return_id] = socket; + return return_id; +} + +bool ExtensionBluetoothEventRouter::ReleaseSocket(int id) { + SocketMap::iterator socket_entry = socket_map_.find(id); + if (socket_entry == socket_map_.end()) + return false; + socket_map_.erase(socket_entry); + return true; +} + +scoped_refptr +ExtensionBluetoothEventRouter::GetSocket(int id) { + SocketMap::iterator socket_entry = socket_map_.find(id); + if (socket_entry == socket_map_.end()) + return NULL; + return socket_entry->second; +} + +void ExtensionBluetoothEventRouter::SetResponsibleForDiscovery( + bool responsible) { + responsible_for_discovery_ = responsible; +} + +bool ExtensionBluetoothEventRouter::IsResponsibleForDiscovery() const { + return responsible_for_discovery_; +} + +void ExtensionBluetoothEventRouter::SetSendDiscoveryEvents(bool should_send) { + // At the transition into sending devices, also send past devices that + // were discovered as they will not be discovered again. + if (should_send && !send_discovery_events_) { + for (DeviceList::const_iterator i = discovered_devices_.begin(); + i != discovered_devices_.end(); ++i) { + DispatchDeviceEvent(extensions::event_names::kBluetoothOnDeviceDiscovered, + **i); + } + } + + send_discovery_events_ = should_send; +} + +void ExtensionBluetoothEventRouter::DispatchDeviceEvent( + const char* event_name, const experimental_bluetooth::Device& device) { + scoped_ptr args(new ListValue()); + args->Append(device.ToValue().release()); + profile_->GetExtensionEventRouter()->DispatchEventToRenderers( + event_name, + args.Pass(), + NULL, + GURL()); +} + +void ExtensionBluetoothEventRouter::AdapterPresentChanged( + device::BluetoothAdapter* adapter, bool present) { + if (adapter != adapter_.get()) { + DVLOG(1) << "Ignoring event for adapter " << adapter->address(); + return; + } + + DispatchBooleanValueEvent( + extensions::event_names::kBluetoothOnAvailabilityChanged, + present); +} + +void ExtensionBluetoothEventRouter::AdapterPoweredChanged( + device::BluetoothAdapter* adapter, bool has_power) { + if (adapter != adapter_.get()) { + DVLOG(1) << "Ignoring event for adapter " << adapter->address(); + return; + } + + DispatchBooleanValueEvent( + extensions::event_names::kBluetoothOnPowerChanged, + has_power); +} + +void ExtensionBluetoothEventRouter::AdapterDiscoveringChanged( + device::BluetoothAdapter* adapter, bool discovering) { + if (adapter != adapter_.get()) { + DVLOG(1) << "Ignoring event for adapter " << adapter->address(); + return; + } + + if (!discovering) { + send_discovery_events_ = false; + responsible_for_discovery_ = false; + discovered_devices_.clear(); + } + + DispatchBooleanValueEvent( + extensions::event_names::kBluetoothOnDiscoveringChanged, + discovering); +} + +void ExtensionBluetoothEventRouter::DeviceAdded( + device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) { + if (adapter != adapter_.get()) { + DVLOG(1) << "Ignoring event for adapter " << adapter->address(); + return; + } + + experimental_bluetooth::Device* extension_device = + new experimental_bluetooth::Device(); + experimental_bluetooth::BluetoothDeviceToApiDevice(*device, extension_device); + discovered_devices_.push_back(extension_device); + + if (!send_discovery_events_) + return; + + DispatchDeviceEvent(extensions::event_names::kBluetoothOnDeviceDiscovered, + *extension_device); +} + +void ExtensionBluetoothEventRouter::DispatchBooleanValueEvent( + const char* event_name, bool value) { + scoped_ptr args(new ListValue()); + args->Append(Value::CreateBooleanValue(value)); + profile_->GetExtensionEventRouter()->DispatchEventToRenderers( + event_name, args.Pass(), NULL, GURL()); +} + +} // namespace extensions diff --git a/chrome/browser/extensions/bluetooth_event_router.h b/chrome/browser/extensions/bluetooth_event_router.h new file mode 100644 index 0000000..36df64b --- /dev/null +++ b/chrome/browser/extensions/bluetooth_event_router.h @@ -0,0 +1,102 @@ +// Copyright (c) 2012 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 CHROME_BROWSER_EXTENSIONS_BLUETOOTH_EVENT_ROUTER_H_ +#define CHROME_BROWSER_EXTENSIONS_BLUETOOTH_EVENT_ROUTER_H_ + +#include + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_vector.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/extensions/api/experimental_bluetooth.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_socket.h" + +namespace extensions { + +class ExtensionBluetoothEventRouter + : public device::BluetoothAdapter::Observer { + public: + explicit ExtensionBluetoothEventRouter(Profile* profile); + virtual ~ExtensionBluetoothEventRouter(); + + // adapter() will return NULL if the bluetooth adapter is not supported in the + // current platform. + const device::BluetoothAdapter* adapter() const { + return adapter_.get(); + } + + // GetMutableAdapter will return NULL if the bluetooth adapter is not + // supported in the current platform. + device::BluetoothAdapter* GetMutableAdapter() { + return adapter_.get(); + } + + // Register the BluetoothSocket |socket| for use by the extensions system. + // This class will hold onto the socket for its lifetime, or until + // ReleaseSocket is called for the socket. Returns an id for the socket. + int RegisterSocket(scoped_refptr socket); + + // Release the BluetoothSocket corresponding to |id|. Returns true if + // the socket was found and released, false otherwise. + bool ReleaseSocket(int id); + + // Get the BluetoothSocket corresponding to |id|. + scoped_refptr GetSocket(int id); + + // Sets whether this Profile is responsible for the discovering state of the + // adapter. + void SetResponsibleForDiscovery(bool responsible); + bool IsResponsibleForDiscovery() const; + + // Sets whether or not DeviceAdded events will be dispatched to extensions. + void SetSendDiscoveryEvents(bool should_send); + + // Dispatch an event that takes a device as a parameter to all renderers. + void DispatchDeviceEvent( + const char* event_name, + const extensions::api::experimental_bluetooth::Device& device); + + // Override from device::BluetoothAdapter::Observer + virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter, + bool present) OVERRIDE; + virtual void AdapterPoweredChanged(device::BluetoothAdapter* adapter, + bool has_power) OVERRIDE; + virtual void AdapterDiscoveringChanged(device::BluetoothAdapter* adapter, + bool discovering) OVERRIDE; + virtual void DeviceAdded(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE; + + // Exposed for testing. + void SetAdapterForTest(device::BluetoothAdapter* adapter) { + adapter_ = adapter; + } + private: + void DispatchBooleanValueEvent(const char* event_name, bool value); + + bool send_discovery_events_; + bool responsible_for_discovery_; + + Profile* profile_; + scoped_refptr adapter_; + + // The next id to use for referring to a BluetoothSocket. We avoid using + // the fd of the socket because we don't want to leak that information to + // the extension javascript. + int next_socket_id_; + + typedef std::map > SocketMap; + SocketMap socket_map_; + + typedef ScopedVector + DeviceList; + DeviceList discovered_devices_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionBluetoothEventRouter); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_BLUETOOTH_EVENT_ROUTER_H_ diff --git a/chrome/browser/extensions/event_names.cc b/chrome/browser/extensions/event_names.cc index 9171dd0..83d60a3 100644 --- a/chrome/browser/extensions/event_names.cc +++ b/chrome/browser/extensions/event_names.cc @@ -57,7 +57,6 @@ const char kOnTerminalProcessOutput[] = "terminalPrivate.onProcessOutput"; const char kOnOffscreenTabUpdated[] = "experimental.offscreenTabs.onUpdated"; -#if defined(OS_CHROMEOS) const char kBluetoothOnAvailabilityChanged[] = "experimental.bluetooth.onAvailabilityChanged"; const char kBluetoothOnDeviceDiscovered[] = @@ -70,7 +69,6 @@ const char kBluetoothOnDiscoveringChanged[] = "experimental.bluetooth.onDiscoveringChanged"; const char kBluetoothOnPowerChanged[] = "experimental.bluetooth.onPowerChanged"; -#endif const char kOnPushMessage[] = "experimental.pushMessaging.onMessage"; diff --git a/chrome/browser/extensions/event_names.h b/chrome/browser/extensions/event_names.h index 823c478..8a7e88d 100644 --- a/chrome/browser/extensions/event_names.h +++ b/chrome/browser/extensions/event_names.h @@ -65,7 +65,6 @@ extern const char kOnTerminalProcessOutput[]; // OffscreenTabs. extern const char kOnOffscreenTabUpdated[]; -#if defined(OS_CHROMEOS) // Bluetooth. extern const char kBluetoothOnAvailabilityChanged[]; extern const char kBluetoothOnDeviceDiscovered[]; @@ -73,7 +72,6 @@ extern const char kBluetoothOnDeviceSearchFinished[]; extern const char kBluetoothOnDeviceSearchResult[]; extern const char kBluetoothOnDiscoveringChanged[]; extern const char kBluetoothOnPowerChanged[]; -#endif // Push messaging. extern const char kOnPushMessage[]; diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 18a4fd5..7446508 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -44,6 +44,7 @@ #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" #include "chrome/browser/extensions/app_notification_manager.h" #include "chrome/browser/extensions/app_sync_data.h" +#include "chrome/browser/extensions/bluetooth_event_router.h" #include "chrome/browser/extensions/browser_event_router.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/crx_installer.h" @@ -118,7 +119,6 @@ #include "webkit/database/database_util.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/cros/cros_library.h" -#include "chrome/browser/chromeos/extensions/bluetooth_event_router.h" #include "chrome/browser/chromeos/extensions/file_browser_event_router.h" #include "chrome/browser/chromeos/extensions/input_method_event_router.h" #include "chrome/browser/chromeos/extensions/media_player_event_router.h" @@ -517,14 +517,13 @@ void ExtensionService::InitEventRouters() { push_messaging_event_router_->Init(); media_galleries_private_event_router_.reset( new extensions::MediaGalleriesPrivateEventRouter(profile_)); + bluetooth_event_router_.reset( + new extensions::ExtensionBluetoothEventRouter(profile_)); #if defined(OS_CHROMEOS) FileBrowserEventRouterFactory::GetForProfile( profile_)->ObserveFileSystemEvents(); - bluetooth_event_router_.reset( - new chromeos::ExtensionBluetoothEventRouter(profile_)); - input_method_event_router_.reset( new chromeos::ExtensionInputMethodEventRouter); diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 29693d3..9bc1664 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -56,7 +56,6 @@ class Profile; class Version; namespace chromeos { -class ExtensionBluetoothEventRouter; class ExtensionInputMethodEventRouter; } @@ -69,6 +68,7 @@ class ContentSettingsStore; class CrxInstaller; class Extension; class ExtensionActionStorageManager; +class ExtensionBluetoothEventRouter; class ExtensionCookiesEventRouter; class ExtensionManagedModeEventRouter; class ExtensionSyncData; @@ -519,10 +519,11 @@ class ExtensionService return window_event_router_.get(); } -#if defined(OS_CHROMEOS) - chromeos::ExtensionBluetoothEventRouter* bluetooth_event_router() { + extensions::ExtensionBluetoothEventRouter* bluetooth_event_router() { return bluetooth_event_router_.get(); } + +#if defined(OS_CHROMEOS) chromeos::ExtensionInputMethodEventRouter* input_method_event_router() { return input_method_event_router_.get(); } @@ -861,8 +862,9 @@ class ExtensionService scoped_ptr managed_mode_event_router_; + scoped_ptr bluetooth_event_router_; + #if defined(OS_CHROMEOS) - scoped_ptr bluetooth_event_router_; scoped_ptr input_method_event_router_; #endif diff --git a/chrome/browser/ui/webui/DEPS b/chrome/browser/ui/webui/DEPS index 189f541..6461fcc 100644 --- a/chrome/browser/ui/webui/DEPS +++ b/chrome/browser/ui/webui/DEPS @@ -6,6 +6,7 @@ include_rules = [ "+sync/internal_api/public/util/weak_handle.h", # Other libraries. + "+device/bluetooth", "+third_party/angle", # For ANGLE version. "+third_party/zlib/zlib.h", # For compression level constants. ] diff --git a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc index f69fc34..e40533f 100644 --- a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc +++ b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.cc @@ -11,10 +11,10 @@ #include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter_factory.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" #include "content/public/browser/web_ui.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/bluetooth_device.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "third_party/cros_system_api/dbus/service_constants.h" @@ -124,8 +124,9 @@ void BluetoothOptionsHandler::GetLocalizedValues( // TODO(kevers): Reorder methods to match ordering in the header file. -void BluetoothOptionsHandler::AdapterPresentChanged(BluetoothAdapter* adapter, - bool present) { +void BluetoothOptionsHandler::AdapterPresentChanged( + device::BluetoothAdapter* adapter, + bool present) { DCHECK(adapter == adapter_.get()); if (present) { web_ui()->CallJavascriptFunction( @@ -140,8 +141,9 @@ void BluetoothOptionsHandler::AdapterPresentChanged(BluetoothAdapter* adapter, } } -void BluetoothOptionsHandler::AdapterPoweredChanged(BluetoothAdapter* adapter, - bool powered) { +void BluetoothOptionsHandler::AdapterPoweredChanged( + device::BluetoothAdapter* adapter, + bool powered) { DCHECK(adapter == adapter_.get()); base::FundamentalValue checked(powered); web_ui()->CallJavascriptFunction( @@ -167,7 +169,8 @@ void BluetoothOptionsHandler::RegisterMessages() { } void BluetoothOptionsHandler::InitializeHandler() { - adapter_ = BluetoothAdapterFactory::DefaultAdapter(); + adapter_ = device::BluetoothAdapterFactory::DefaultAdapter(); + DCHECK(adapter_.get()); adapter_->AddObserver(this); } @@ -216,7 +219,7 @@ void BluetoothOptionsHandler::UpdateDeviceCallback( std::string address; args->GetString(kUpdateDeviceAddressIndex, &address); - BluetoothDevice* device = adapter_->GetDevice(address); + device::BluetoothDevice* device = adapter_->GetDevice(address); if (!device) return; @@ -324,15 +327,15 @@ void BluetoothOptionsHandler::StopDiscoveryError() { void BluetoothOptionsHandler::GetPairedDevicesCallback( const ListValue* args) { - BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); + device::BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); - for (BluetoothAdapter::DeviceList::iterator iter = devices.begin(); + for (device::BluetoothAdapter::DeviceList::iterator iter = devices.begin(); iter != devices.end(); ++iter) SendDeviceNotification(*iter, NULL); } void BluetoothOptionsHandler::SendDeviceNotification( - const BluetoothDevice* device, + const device::BluetoothDevice* device, base::DictionaryValue* params) { base::DictionaryValue js_properties; js_properties.SetString("name", device->GetName()); @@ -348,19 +351,19 @@ void BluetoothOptionsHandler::SendDeviceNotification( js_properties); } -void BluetoothOptionsHandler::RequestPinCode(BluetoothDevice* device) { +void BluetoothOptionsHandler::RequestPinCode(device::BluetoothDevice* device) { DictionaryValue params; params.SetString("pairing", kEnterPinCode); SendDeviceNotification(device, ¶ms); } -void BluetoothOptionsHandler::RequestPasskey(BluetoothDevice* device) { +void BluetoothOptionsHandler::RequestPasskey(device::BluetoothDevice* device) { DictionaryValue params; params.SetString("pairing", kEnterPasskey); SendDeviceNotification(device, ¶ms); } -void BluetoothOptionsHandler::DisplayPinCode(BluetoothDevice* device, +void BluetoothOptionsHandler::DisplayPinCode(device::BluetoothDevice* device, const std::string& pincode) { DictionaryValue params; params.SetString("pairing", kRemotePinCode); @@ -368,7 +371,7 @@ void BluetoothOptionsHandler::DisplayPinCode(BluetoothDevice* device, SendDeviceNotification(device, ¶ms); } -void BluetoothOptionsHandler::DisplayPasskey(BluetoothDevice* device, +void BluetoothOptionsHandler::DisplayPasskey(device::BluetoothDevice* device, uint32 passkey) { DictionaryValue params; params.SetString("pairing", kRemotePasskey); @@ -376,7 +379,7 @@ void BluetoothOptionsHandler::DisplayPasskey(BluetoothDevice* device, SendDeviceNotification(device, ¶ms); } -void BluetoothOptionsHandler::ConfirmPasskey(BluetoothDevice* device, +void BluetoothOptionsHandler::ConfirmPasskey(device::BluetoothDevice* device, uint32 passkey) { DictionaryValue params; params.SetString("pairing", kConfirmPasskey); @@ -400,22 +403,22 @@ void BluetoothOptionsHandler::ReportError( properties); } -void BluetoothOptionsHandler::DeviceAdded(BluetoothAdapter* adapter, - BluetoothDevice* device) { +void BluetoothOptionsHandler::DeviceAdded(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) { DCHECK(adapter == adapter_.get()); DCHECK(device); SendDeviceNotification(device, NULL); } -void BluetoothOptionsHandler::DeviceChanged(BluetoothAdapter* adapter, - BluetoothDevice* device) { +void BluetoothOptionsHandler::DeviceChanged(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) { DCHECK(adapter == adapter_.get()); DCHECK(device); SendDeviceNotification(device, NULL); } -void BluetoothOptionsHandler::DeviceRemoved(BluetoothAdapter* adapter, - BluetoothDevice* device) { +void BluetoothOptionsHandler::DeviceRemoved(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) { DCHECK(adapter == adapter_.get()); DCHECK(device); diff --git a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h index b98763a..80d2d75 100644 --- a/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h +++ b/chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h @@ -11,9 +11,9 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_adapter.h" -#include "chrome/browser/chromeos/bluetooth/bluetooth_device.h" #include "chrome/browser/ui/webui/options/options_ui.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_device.h" namespace base { class DictionaryValue; @@ -23,9 +23,10 @@ namespace chromeos { namespace options { // Handler for Bluetooth options on the system options page. -class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, - public chromeos::BluetoothAdapter::Observer, - public BluetoothDevice::PairingDelegate { +class BluetoothOptionsHandler + : public ::options::OptionsPageUIHandler, + public device::BluetoothAdapter::Observer, + public device::BluetoothDevice::PairingDelegate { public: BluetoothOptionsHandler(); virtual ~BluetoothOptionsHandler(); @@ -40,10 +41,10 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, // Sends a notification to the Web UI of the status of a Bluetooth device. // |device| is the Bluetooth device. // |params| is an optional set of parameters. - void SendDeviceNotification(const BluetoothDevice* device, + void SendDeviceNotification(const device::BluetoothDevice* device, base::DictionaryValue* params); - // BluetoothDevice::PairingDelegate override. + // device::BluetoothDevice::PairingDelegate override. // // This method will be called when the Bluetooth daemon requires a // PIN Code for authentication of the device |device|, the UI will display @@ -51,9 +52,9 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, // // PIN Codes are generally required for Bluetooth 2.0 and earlier devices // for which there is no automatic pairing or special handling. - virtual void RequestPinCode(BluetoothDevice* device) OVERRIDE; + virtual void RequestPinCode(device::BluetoothDevice* device) OVERRIDE; - // BluetoothDevice::PairingDelegate override. + // device::BluetoothDevice::PairingDelegate override. // // This method will be called when the Bluetooth daemon requires a // Passkey for authentication of the device |device|, the UI will display @@ -63,9 +64,9 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, // Passkeys are generally required for Bluetooth 2.1 and later devices // which cannot provide input or display on their own, and don't accept // passkey-less pairing. - virtual void RequestPasskey(BluetoothDevice* device) OVERRIDE; + virtual void RequestPasskey(device::BluetoothDevice* device) OVERRIDE; - // BluetoothDevice::PairingDelegate override. + // device::BluetoothDevice::PairingDelegate override. // // This method will be called when the Bluetooth daemon requires that the // user enter the PIN code |pincode| into the device |device| so that it @@ -75,10 +76,10 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, // This is used for Bluetooth 2.0 and earlier keyboard devices, the // |pincode| will always be a six-digit numeric in the range 000000-999999 // for compatibilty with later specifications. - virtual void DisplayPinCode(BluetoothDevice* device, + virtual void DisplayPinCode(device::BluetoothDevice* device, const std::string& pincode) OVERRIDE; - // BluetoothDevice::PairingDelegate override. + // device::BluetoothDevice::PairingDelegate override. // // This method will be called when the Bluetooth daemon requires that the // user enter the Passkey |passkey| into the device |device| so that it @@ -89,9 +90,10 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, // but not display, such as keyboards. The Passkey is a numeric in the // range 0-999999 and should be always presented zero-padded to six // digits. - virtual void DisplayPasskey(BluetoothDevice* device, uint32 passkey) OVERRIDE; + virtual void DisplayPasskey( + device::BluetoothDevice* device, uint32 passkey) OVERRIDE; - // BluetoothDevice::PairingDelegate override. + // device::BluetoothDevice::PairingDelegate override. // // This method will be called when the Bluetooth daemon requires that the // user confirm that the Passkey |passkey| is displayed on the screen @@ -102,9 +104,10 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, // such as other computers or phones. The Passkey is a numeric in the // range 0-999999 and should be always present zero-padded to six // digits. - virtual void ConfirmPasskey(BluetoothDevice* device, uint32 passkey) OVERRIDE; + virtual void ConfirmPasskey( + device::BluetoothDevice* device, uint32 passkey) OVERRIDE; - // BluetoothDevice::PairingDelegate override. + // device::BluetoothDevice::PairingDelegate override. // // This method will be called when any previous DisplayPinCode(), // DisplayPasskey() or ConfirmPasskey() request should be concluded @@ -117,41 +120,41 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, // string if the error is not specific to a single device. void ReportError(const std::string& error, const std::string& address); - // BluetoothAdapter::Observer implementation. - virtual void AdapterPresentChanged(BluetoothAdapter* adapter, + // device::BluetoothAdapter::Observer implementation. + virtual void AdapterPresentChanged(device::BluetoothAdapter* adapter, bool present) OVERRIDE; - virtual void AdapterPoweredChanged(BluetoothAdapter* adapter, + virtual void AdapterPoweredChanged(device::BluetoothAdapter* adapter, bool powered) OVERRIDE; - virtual void DeviceAdded(BluetoothAdapter* adapter, - BluetoothDevice* device) OVERRIDE; - virtual void DeviceChanged(BluetoothAdapter* adapter, - BluetoothDevice* device) OVERRIDE; - virtual void DeviceRemoved(BluetoothAdapter* adapter, - BluetoothDevice* device) OVERRIDE; + virtual void DeviceAdded(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE; + virtual void DeviceChanged(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE; + virtual void DeviceRemoved(device::BluetoothAdapter* adapter, + device::BluetoothDevice* device) OVERRIDE; private: - // Called by BluetoothAdapter in response to a failure to change the power - // status of the adapter. + // Called by device::BluetoothAdapter in response to a failure to + // change the power status of the adapter. void EnableChangeError(); - // Called by BluetoothAdapter in response to a failure to set the adapter into - // discovery mode. + // Called by device::BluetoothAdapter in response to a failure to + // set the adapter into discovery mode. void FindDevicesError(); - // Called by BluetoothAdapter in response to a failure to remove the adapter - // from discovery mode. + // Called by device::BluetoothAdapter in response to a failure to + // remove the adapter from discovery mode. void StopDiscoveryError(); - // Called by BluetoothDevice in response to a failure to connect to the device - // with bluetooth address |address|. + // Called by device::BluetoothDevice in response to a failure to + // connect to the device with bluetooth address |address|. void ConnectError(const std::string& address); - // Called by BluetoothDevice in response to a failure to disconnect the device - // with bluetooth address |address|. + // Called by device::BluetoothDevice in response to a failure to + // disconnect the device with bluetooth address |address|. void DisconnectError(const std::string& address); - // Called by BluetoothDevice in response to a failure to disconnect and unpair - // the device with bluetooth address |address|. + // Called by device::BluetoothDevice in response to a failure to + // disconnect and unpair the device with bluetooth address |address|. void ForgetError(const std::string& address); // Called when the 'Enable bluetooth' checkbox value is changed. @@ -182,7 +185,7 @@ class BluetoothOptionsHandler : public ::options::OptionsPageUIHandler, void GetPairedDevicesCallback(const base::ListValue* args); // Default bluetooth adapter, used for all operations. - scoped_refptr adapter_; + scoped_refptr adapter_; // Weak pointer factory for generating 'this' pointers that might live longer // than this object does. diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 78ea081..731e22e 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -51,6 +51,7 @@ '../content/content.gyp:content_common', '../crypto/crypto.gyp:crypto', '../dbus/dbus.gyp:dbus', + '../device/device.gyp:device_bluetooth', '../media/media.gyp:media', '../net/net.gyp:net', '../ppapi/ppapi_internal.gyp:ppapi_ipc', # For PpapiMsg_LoadPlugin @@ -123,23 +124,6 @@ 'browser/chromeos/audio/audio_mixer_cras.h', 'browser/chromeos/background/ash_user_wallpaper_delegate.cc', 'browser/chromeos/background/ash_user_wallpaper_delegate.h', - 'browser/chromeos/bluetooth/bluetooth_adapter.cc', - 'browser/chromeos/bluetooth/bluetooth_adapter.h', - 'browser/chromeos/bluetooth/bluetooth_adapter_chromeos.cc', - 'browser/chromeos/bluetooth/bluetooth_adapter_chromeos.h', - 'browser/chromeos/bluetooth/bluetooth_adapter_factory.h', - 'browser/chromeos/bluetooth/bluetooth_adapter_factory.cc', - 'browser/chromeos/bluetooth/bluetooth_device.cc', - 'browser/chromeos/bluetooth/bluetooth_device.h', - 'browser/chromeos/bluetooth/bluetooth_device_chromeos.cc', - 'browser/chromeos/bluetooth/bluetooth_device_chromeos.h', - 'browser/chromeos/bluetooth/bluetooth_service_record.cc', - 'browser/chromeos/bluetooth/bluetooth_service_record.h', - 'browser/chromeos/bluetooth/bluetooth_socket.h', - 'browser/chromeos/bluetooth/bluetooth_socket_chromeos.cc', - 'browser/chromeos/bluetooth/bluetooth_socket_chromeos.h', - 'browser/chromeos/bluetooth/bluetooth_utils.cc', - 'browser/chromeos/bluetooth/bluetooth_utils.h', 'browser/chromeos/boot_times_loader.cc', 'browser/chromeos/boot_times_loader.h', 'browser/chromeos/choose_mobile_network_dialog.cc', @@ -274,8 +258,6 @@ 'browser/chromeos/enrollment_dialog_view.h', 'browser/chromeos/enterprise_extension_observer.cc', 'browser/chromeos/enterprise_extension_observer.h', - 'browser/chromeos/extensions/bluetooth_event_router.cc', - 'browser/chromeos/extensions/bluetooth_event_router.h', 'browser/chromeos/extensions/echo_private_api.cc', 'browser/chromeos/extensions/echo_private_api.h', 'browser/chromeos/extensions/file_browser_event_router.cc', diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index cc8d5e6..b951223 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -31,6 +31,7 @@ '../build/temp_gyp/googleurl.gyp:googleurl', '../content/content.gyp:content_browser', '../crypto/crypto.gyp:crypto', + '../device/device.gyp:device_bluetooth', '../net/net.gyp:net', '../skia/skia.gyp:skia', '../sync/sync.gyp:sync_notifier', @@ -355,6 +356,8 @@ 'browser/extensions/app_sync_bundle.h', 'browser/extensions/app_sync_data.cc', 'browser/extensions/app_sync_data.h', + 'browser/extensions/bluetooth_event_router.cc', + 'browser/extensions/bluetooth_event_router.h', 'browser/extensions/browser_action_test_util.h', 'browser/extensions/browser_action_test_util_gtk.cc', 'browser/extensions/browser_action_test_util_mac.mm', diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 63db09f..c2bb5ef 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -39,6 +39,7 @@ '../content/content.gyp:content_browser', '../content/content.gyp:content_common', '../crypto/crypto.gyp:crypto', + '../device/device.gyp:device_bluetooth', '../media/media.gyp:media', '../net/net.gyp:net_with_v8', '../ppapi/ppapi_internal.gyp:ppapi_ipc', # For PpapiMsg_LoadPlugin diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index ad41928..3589aa2 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1098,12 +1098,6 @@ 'browser/chrome_browser_application_mac_unittest.mm', 'browser/chrome_browser_main_unittest.cc', 'browser/chrome_page_zoom_unittest.cc', - 'browser/chromeos/bluetooth/bluetooth_service_record_unittest.cc', - 'browser/chromeos/bluetooth/bluetooth_utils_unittest.cc', - 'browser/chromeos/bluetooth/bluetooth_adapter_chromeos_unittest.cc', - 'browser/chromeos/bluetooth/bluetooth_adapter_devices_chromeos_unittest.cc', - 'browser/chromeos/bluetooth/test/mock_bluetooth_adapter.cc', - 'browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h', 'browser/chromeos/contacts/contact_database_unittest.cc', 'browser/chromeos/contacts/contact_manager_stub.cc', 'browser/chromeos/contacts/contact_manager_stub.h', @@ -2746,6 +2740,7 @@ '../base/base.gyp:base', '../base/base.gyp:base_i18n', '../base/base.gyp:test_support_base', + '../device/device.gyp:device_bluetooth_mocks', '../net/net.gyp:net', '../net/net.gyp:net_test_support', '../skia/skia.gyp:skia', @@ -2796,10 +2791,6 @@ 'browser/chrome_main_browsertest.cc', 'browser/chrome_plugin_browsertest.cc', 'browser/chrome_switches_browsertest.cc', - 'browser/chromeos/bluetooth/test/mock_bluetooth_adapter.cc', - 'browser/chromeos/bluetooth/test/mock_bluetooth_adapter.h', - 'browser/chromeos/bluetooth/test/mock_bluetooth_device.cc', - 'browser/chromeos/bluetooth/test/mock_bluetooth_device.h', 'browser/chromeos/contacts/contact_test_util.cc', 'browser/chromeos/contacts/gdata_contacts_service_browsertest.cc', 'browser/chromeos/cros/cros_in_process_browser_test.cc', diff --git a/chrome/test/data/chromeos/bluetooth/invalid_uuid.xml b/chrome/test/data/chromeos/bluetooth/invalid_uuid.xml deleted file mode 100644 index 2b33304..0000000 --- a/chrome/test/data/chromeos/bluetooth/invalid_uuid.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/chrome/test/data/chromeos/bluetooth/medium_uuid.xml b/chrome/test/data/chromeos/bluetooth/medium_uuid.xml deleted file mode 100644 index 432d7fe..0000000 --- a/chrome/test/data/chromeos/bluetooth/medium_uuid.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/chrome/test/data/chromeos/bluetooth/rfcomm.xml b/chrome/test/data/chromeos/bluetooth/rfcomm.xml deleted file mode 100644 index ec3bdec..0000000 --- a/chrome/test/data/chromeos/bluetooth/rfcomm.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/chrome/test/data/chromeos/bluetooth/short_uuid.xml b/chrome/test/data/chromeos/bluetooth/short_uuid.xml deleted file mode 100644 index 9ad3c9f..0000000 --- a/chrome/test/data/chromeos/bluetooth/short_uuid.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/chrome/test/data/chromeos/bluetooth/uppercase_uuid.xml b/chrome/test/data/chromeos/bluetooth/uppercase_uuid.xml deleted file mode 100644 index 4e0574f..0000000 --- a/chrome/test/data/chromeos/bluetooth/uppercase_uuid.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/chromeos/chromeos.gyp b/chromeos/chromeos.gyp index 5313d5d..519fe91 100644 --- a/chromeos/chromeos.gyp +++ b/chromeos/chromeos.gyp @@ -45,7 +45,6 @@ 'dbus/bluetooth_node_client.h', 'dbus/bluetooth_out_of_band_client.cc', 'dbus/bluetooth_out_of_band_client.h', - 'dbus/bluetooth_out_of_band_pairing_data.h', 'dbus/bluetooth_property.cc', 'dbus/bluetooth_property.h', 'dbus/cashew_client.cc', diff --git a/chromeos/dbus/DEPS b/chromeos/dbus/DEPS index d6abdda..2b3c5e1 100644 --- a/chromeos/dbus/DEPS +++ b/chromeos/dbus/DEPS @@ -1,3 +1,4 @@ include_rules = [ "+dbus", + "+device/bluetooth/bluetooth_out_of_band_pairing_data.h", ] diff --git a/chromeos/dbus/bluetooth_out_of_band_client.cc b/chromeos/dbus/bluetooth_out_of_band_client.cc index 88b243b..457cf82 100644 --- a/chromeos/dbus/bluetooth_out_of_band_client.cc +++ b/chromeos/dbus/bluetooth_out_of_band_client.cc @@ -10,11 +10,11 @@ #include "base/bind.h" #include "base/logging.h" #include "chromeos/dbus/bluetooth_adapter_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" #include "dbus/bus.h" #include "dbus/message.h" #include "dbus/object_path.h" #include "dbus/object_proxy.h" +#include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" #include "third_party/cros_system_api/dbus/service_constants.h" namespace chromeos { @@ -49,7 +49,7 @@ class BluetoothOutOfBandClientImpl: public BluetoothOutOfBandClient { virtual void AddRemoteData( const dbus::ObjectPath& object_path, const std::string& address, - const BluetoothOutOfBandPairingData& data, + const device::BluetoothOutOfBandPairingData& data, const SuccessCallback& callback) OVERRIDE { dbus::MethodCall method_call( bluetooth_outofband::kBluetoothOutOfBandInterface, @@ -57,9 +57,10 @@ class BluetoothOutOfBandClientImpl: public BluetoothOutOfBandClient { dbus::MessageWriter writer(&method_call); writer.AppendString(address); - writer.AppendArrayOfBytes(data.hash, kBluetoothOutOfBandPairingDataSize); - writer.AppendArrayOfBytes(data.randomizer, - kBluetoothOutOfBandPairingDataSize); + writer.AppendArrayOfBytes( + data.hash, device::kBluetoothOutOfBandPairingDataSize); + writer.AppendArrayOfBytes( + data.randomizer, device::kBluetoothOutOfBandPairingDataSize); dbus::ObjectProxy* object_proxy = GetObjectProxy(object_path); @@ -115,16 +116,16 @@ class BluetoothOutOfBandClientImpl: public BluetoothOutOfBandClient { void OnReadLocalData(const DataCallback& callback, dbus::Response* response) { bool success = false; - BluetoothOutOfBandPairingData data; + device::BluetoothOutOfBandPairingData data; if (response != NULL) { dbus::MessageReader reader(response); uint8_t* bytes = NULL; - size_t length = kBluetoothOutOfBandPairingDataSize; + size_t length = device::kBluetoothOutOfBandPairingDataSize; if (reader.PopArrayOfBytes(&bytes, &length)) { - if (length == kBluetoothOutOfBandPairingDataSize) { + if (length == device::kBluetoothOutOfBandPairingDataSize) { memcpy(&data.hash, bytes, length); if (reader.PopArrayOfBytes(&bytes, &length)) { - if (length == kBluetoothOutOfBandPairingDataSize) { + if (length == device::kBluetoothOutOfBandPairingDataSize) { memcpy(&data.randomizer, bytes, length); success = true; } @@ -162,7 +163,7 @@ class BluetoothOutOfBandClientStubImpl : public BluetoothOutOfBandClient { const dbus::ObjectPath& object_path, const DataCallback& callback) OVERRIDE { VLOG(1) << "ReadLocalData: " << object_path.value(); - BluetoothOutOfBandPairingData data; + device::BluetoothOutOfBandPairingData data; callback.Run(data, false); } @@ -170,7 +171,7 @@ class BluetoothOutOfBandClientStubImpl : public BluetoothOutOfBandClient { virtual void AddRemoteData( const dbus::ObjectPath& object_path, const std::string& address, - const BluetoothOutOfBandPairingData& data, + const device::BluetoothOutOfBandPairingData& data, const SuccessCallback& callback) OVERRIDE { VLOG(1) << "AddRemoteData: " << object_path.value(); callback.Run(false); diff --git a/chromeos/dbus/bluetooth_out_of_band_client.h b/chromeos/dbus/bluetooth_out_of_band_client.h index 8468528..e39cd61 100644 --- a/chromeos/dbus/bluetooth_out_of_band_client.h +++ b/chromeos/dbus/bluetooth_out_of_band_client.h @@ -16,9 +16,11 @@ namespace dbus { class Bus; } // namespace dbus -namespace chromeos { - +namespace device { struct BluetoothOutOfBandPairingData; +} // namespace device + +namespace chromeos { // BluetoothOutOfBandClient is used to manage Out Of Band Pairing // Data for the local adapter and remote devices. @@ -26,7 +28,8 @@ class CHROMEOS_EXPORT BluetoothOutOfBandClient { public: virtual ~BluetoothOutOfBandClient(); - typedef base::Callback DataCallback; typedef base::Callback SuccessCallback; @@ -41,7 +44,7 @@ class CHROMEOS_EXPORT BluetoothOutOfBandClient { virtual void AddRemoteData( const dbus::ObjectPath& object_path, const std::string& address, - const BluetoothOutOfBandPairingData& data, + const device::BluetoothOutOfBandPairingData& data, const SuccessCallback& callback) = 0; // Clears the Out Of Band Pairing Data for the device at |address|, indicating diff --git a/chromeos/dbus/bluetooth_out_of_band_pairing_data.h b/chromeos/dbus/bluetooth_out_of_band_pairing_data.h deleted file mode 100644 index 0c8e2bc..0000000 --- a/chromeos/dbus/bluetooth_out_of_band_pairing_data.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2012 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 CHROMEOS_DBUS_BLUETOOTH_OUT_OF_BAND_PAIRING_DATA_H_ -#define CHROMEOS_DBUS_BLUETOOTH_OUT_OF_BAND_PAIRING_DATA_H_ - -#include "base/basictypes.h" - -namespace chromeos { - -const size_t kBluetoothOutOfBandPairingDataSize = 16; - -// A simple structure representing the data required to perform Out Of Band -// Pairing. See -// http://mclean-linsky.net/joel/cv/Simple%20Pairing_WP_V10r00.pdf -struct BluetoothOutOfBandPairingData { - // Simple Pairing Hash C. - uint8_t hash[kBluetoothOutOfBandPairingDataSize]; - - // Simple Pairing Randomizer R. - uint8_t randomizer[kBluetoothOutOfBandPairingDataSize]; -}; - -} // namespace chromeos - -#endif // CHROMEOS_DBUS_BLUETOOTH_OUT_OF_BAND_PAIRING_DATA_H_ diff --git a/chromeos/dbus/mock_bluetooth_out_of_band_client.h b/chromeos/dbus/mock_bluetooth_out_of_band_client.h index a1291ee..9b4be7f 100644 --- a/chromeos/dbus/mock_bluetooth_out_of_band_client.h +++ b/chromeos/dbus/mock_bluetooth_out_of_band_client.h @@ -9,7 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "chromeos/dbus/bluetooth_out_of_band_client.h" -#include "chromeos/dbus/bluetooth_out_of_band_pairing_data.h" +#include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" #include "testing/gmock/include/gmock/gmock.h" namespace chromeos { @@ -25,7 +25,7 @@ class MockBluetoothOutOfBandClient : public BluetoothOutOfBandClient { MOCK_METHOD4(AddRemoteData, void(const dbus::ObjectPath&, const std::string&, - const BluetoothOutOfBandPairingData&, + const device::BluetoothOutOfBandPairingData&, const SuccessCallback&)); MOCK_METHOD3(RemoveRemoteData, void(const dbus::ObjectPath&, diff --git a/device/DEPS b/device/DEPS new file mode 100644 index 0000000..2beaf5d --- /dev/null +++ b/device/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+content/public/common", + "+content/public/test", +] diff --git a/device/bluetooth/DEPS b/device/bluetooth/DEPS new file mode 100644 index 0000000..730c30e --- /dev/null +++ b/device/bluetooth/DEPS @@ -0,0 +1,11 @@ +include_rules = [ + "+chrome/common", + "+chrome/test/base", + "+content/public/test", + "+chromeos/dbus", + "+dbus", + "+grit", + "+ui/base/l10n", + "+third_party/cros_system_api/dbus", + "+third_party/libxml/chromium", +] diff --git a/device/bluetooth/OWNERS b/device/bluetooth/OWNERS new file mode 100644 index 0000000..47f6cfa --- /dev/null +++ b/device/bluetooth/OWNERS @@ -0,0 +1,2 @@ +keybuk@chromium.org +bryeung@chromium.org diff --git a/device/bluetooth/bluetooth_adapter.cc b/device/bluetooth/bluetooth_adapter.cc new file mode 100644 index 0000000..b36cd0b --- /dev/null +++ b/device/bluetooth/bluetooth_adapter.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2012 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_adapter.h" + +#include "device/bluetooth/bluetooth_device.h" + +namespace device { + +BluetoothAdapter::~BluetoothAdapter() { +} + +const std::string& BluetoothAdapter::address() const { + return address_; +} + +const std::string& BluetoothAdapter::name() const { + return name_; +} + +BluetoothAdapter::DeviceList BluetoothAdapter::GetDevices() { + ConstDeviceList const_devices = + const_cast(this)->GetDevices(); + + DeviceList devices; + for (ConstDeviceList::const_iterator i = const_devices.begin(); + i != const_devices.end(); ++i) + devices.push_back(const_cast(*i)); + + return devices; +} + +} // namespace device diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h new file mode 100644 index 0000000..86de361 --- /dev/null +++ b/device/bluetooth/bluetooth_adapter.h @@ -0,0 +1,155 @@ +// Copyright (c) 2012 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_ADAPTER_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_ + +#include +#include + +#include "base/callback.h" +#include "base/memory/ref_counted.h" + +namespace device { + +class BluetoothDevice; + +struct BluetoothOutOfBandPairingData; + +// BluetoothAdapter represents a local Bluetooth adapter which may be used to +// interact with remote Bluetooth devices. As well as providing support for +// determining whether an adapter is present, and whether the radio is powered, +// this class also provides support for obtaining the list of remote devices +// known to the adapter, discovering new devices, and providing notification of +// updates to device information. +class BluetoothAdapter : public base::RefCounted { + public: + // Interface for observing changes from bluetooth adapters. + class Observer { + public: + virtual ~Observer() {} + + // Called when the presence of the adapter |adapter| changes, when + // |present| is true the adapter is now present, false means the adapter + // has been removed from the system. + virtual void AdapterPresentChanged(BluetoothAdapter* adapter, + bool present) {} + + // Called when the radio power state of the adapter |adapter| changes, + // when |powered| is true the adapter radio is powered, false means the + // adapter radio is off. + virtual void AdapterPoweredChanged(BluetoothAdapter* adapter, + bool powered) {} + + // Called when the discovering state of the adapter |adapter| changes, + // when |discovering| is true the adapter is seeking new devices, false + // means it is not. Note that device discovery involves both states when + // the adapter is seeking new devices and states when it is not because + // it is interrogating the devices it found. + virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter, + bool discovering) {} + + // Called when a new device |device| is added to the adapter |adapter|, + // either because it has been discovered or a connection made. |device| + // should not be cached, instead copy its address. + virtual void DeviceAdded(BluetoothAdapter* adapter, + BluetoothDevice* device) {} + + // Called when properties of the device |device| known to the adapter + // |adapter| change. |device| should not be cached, instead copy its + // address. + virtual void DeviceChanged(BluetoothAdapter* adapter, + BluetoothDevice* device) {} + + // Called when the device |device| is removed from the adapter |adapter|, + // either as a result of a discovered device being lost between discovering + // phases or pairing information deleted. |device| should not be cached. + virtual void DeviceRemoved(BluetoothAdapter* adapter, + BluetoothDevice* device) {} + }; + + // 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. + typedef base::Callback ErrorCallback; + + // The BluetoothOutOfBandPairingDataCallback is used to return + // BluetoothOutOfBandPairingData to the caller. + typedef base::Callback + BluetoothOutOfBandPairingDataCallback; + + // Adds and removes observers for events on this bluetooth adapter, + // if monitoring multiple adapters check the |adapter| parameter of + // observer methods to determine which adapter is issuing the event. + virtual void AddObserver(BluetoothAdapter::Observer* observer) = 0; + virtual void RemoveObserver( + BluetoothAdapter::Observer* observer) = 0; + + // The address of this adapter. The address format is "XX:XX:XX:XX:XX:XX", + // where each XX is a hexadecimal number. + virtual const std::string& address() const; + + // The name of the adapter. + virtual const std::string& name() const; + + // Indicates whether the adapter is actually present on the system, for + // the default adapter this indicates whether any adapter is present. An + // adapter is only considered present if the address has been obtained. + virtual bool IsPresent() const = 0; + + // Indicates whether the adapter radio is powered. + virtual bool IsPowered() const = 0; + + // Requests a change to the adapter radio power, setting |powered| to true + // will turn on the radio and false will turn it off. On success, callback + // will be called. On failure, |error_callback| will be called. + virtual void SetPowered(bool powered, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Indicates whether the adapter is currently discovering new devices, + // note that a typical discovery process has phases of this being true + // followed by phases of being false when the adapter interrogates the + // devices found. + virtual bool IsDiscovering() const = 0; + + // Requests that the adapter either begin discovering new devices when + // |discovering| is true, or cease any discovery when false. On success, + // callback will be called. On failure, |error_callback| will be called. + virtual void SetDiscovering(bool discovering, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Requests the list of devices from the adapter, all are returned + // including those currently connected and those paired. Use the + // returned device pointers to determine which they are. + typedef std::vector DeviceList; + virtual DeviceList GetDevices(); + typedef std::vector ConstDeviceList; + virtual ConstDeviceList GetDevices() const = 0; + + // Returns a pointer to the device with the given address |address| or + // NULL if no such device is known. + virtual BluetoothDevice* GetDevice(const std::string& address) = 0; + virtual const BluetoothDevice* GetDevice( + const std::string& address) const = 0; + + // Requests the local Out Of Band pairing data. + virtual void ReadLocalOutOfBandPairingData( + const BluetoothOutOfBandPairingDataCallback& callback, + const ErrorCallback& error_callback) = 0; + + protected: + friend class base::RefCounted; + virtual ~BluetoothAdapter(); + + // Address of the adapter. + std::string address_; + + // Name of the adapter. + std::string name_; +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_ diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc new file mode 100644 index 0000000..36699e5 --- /dev/null +++ b/device/bluetooth/bluetooth_adapter_chromeos.cc @@ -0,0 +1,539 @@ +// Copyright (c) 2012 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_adapter_chromeos.h" + +#include + +#include "base/bind.h" +#include "base/logging.h" +#include "base/stl_util.h" +#include "base/values.h" +#include "chromeos/dbus/bluetooth_adapter_client.h" +#include "chromeos/dbus/bluetooth_device_client.h" +#include "chromeos/dbus/bluetooth_manager_client.h" +#include "chromeos/dbus/bluetooth_out_of_band_client.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_device_chromeos.h" +#include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" + +using device::BluetoothAdapter; +using device::BluetoothDevice; +using device::BluetoothOutOfBandPairingData; + +namespace chromeos { + +BluetoothAdapterChromeOs::BluetoothAdapterChromeOs() : track_default_(false), + powered_(false), + discovering_(false), + weak_ptr_factory_(this) { + DBusThreadManager::Get()->GetBluetoothManagerClient()-> + AddObserver(this); + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + AddObserver(this); + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> + AddObserver(this); +} + +BluetoothAdapterChromeOs::~BluetoothAdapterChromeOs() { + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> + RemoveObserver(this); + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + RemoveObserver(this); + DBusThreadManager::Get()->GetBluetoothManagerClient()-> + RemoveObserver(this); + + STLDeleteValues(&devices_); +} + +void BluetoothAdapterChromeOs::AddObserver( + BluetoothAdapter::Observer* observer) { + DCHECK(observer); + observers_.AddObserver(observer); +} + +void BluetoothAdapterChromeOs::RemoveObserver( + BluetoothAdapter::Observer* observer) { + DCHECK(observer); + observers_.RemoveObserver(observer); +} + +bool BluetoothAdapterChromeOs::IsPresent() const { + return !object_path_.value().empty() && !address_.empty(); +} + +bool BluetoothAdapterChromeOs::IsPowered() const { + return powered_; +} + +void BluetoothAdapterChromeOs::SetPowered(bool powered, + const base::Closure& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + GetProperties(object_path_)->powered.Set( + powered, + base::Bind(&BluetoothAdapterChromeOs::OnSetPowered, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +bool BluetoothAdapterChromeOs::IsDiscovering() const { + return discovering_; +} + +void BluetoothAdapterChromeOs::SetDiscovering( + bool discovering, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (discovering) { + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + StartDiscovery(object_path_, + base::Bind(&BluetoothAdapterChromeOs::OnStartDiscovery, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); + } else { + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + StopDiscovery(object_path_, + base::Bind(&BluetoothAdapterChromeOs::OnStopDiscovery, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); + } +} + +BluetoothAdapter::ConstDeviceList BluetoothAdapterChromeOs::GetDevices() const { + ConstDeviceList devices; + for (DevicesMap::const_iterator iter = devices_.begin(); + iter != devices_.end(); + ++iter) + devices.push_back(iter->second); + + return devices; +} + +BluetoothDevice* BluetoothAdapterChromeOs::GetDevice( + const std::string& address) { + return const_cast( + const_cast(this)->GetDevice(address)); +} + +const BluetoothDevice* BluetoothAdapterChromeOs::GetDevice( + const std::string& address) const { + DevicesMap::const_iterator iter = devices_.find(address); + if (iter != devices_.end()) + return iter->second; + + return NULL; +} + +void BluetoothAdapterChromeOs::ReadLocalOutOfBandPairingData( + const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> + ReadLocalData(object_path_, + base::Bind(&BluetoothAdapterChromeOs::OnReadLocalData, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +void BluetoothAdapterChromeOs::TrackDefaultAdapter() { + DVLOG(1) << "Tracking default adapter"; + track_default_ = true; + DBusThreadManager::Get()->GetBluetoothManagerClient()-> + DefaultAdapter(base::Bind(&BluetoothAdapterChromeOs::AdapterCallback, + weak_ptr_factory_.GetWeakPtr())); +} + +void BluetoothAdapterChromeOs::FindAdapter(const std::string& address) { + DVLOG(1) << "Using adapter " << address; + track_default_ = false; + DBusThreadManager::Get()->GetBluetoothManagerClient()-> + FindAdapter(address, + base::Bind(&BluetoothAdapterChromeOs::AdapterCallback, + weak_ptr_factory_.GetWeakPtr())); +} + +void BluetoothAdapterChromeOs::AdapterCallback( + const dbus::ObjectPath& adapter_path, + bool success) { + if (success) { + ChangeAdapter(adapter_path); + } else if (!object_path_.value().empty()) { + RemoveAdapter(); + } +} + +void BluetoothAdapterChromeOs::DefaultAdapterChanged( + const dbus::ObjectPath& adapter_path) { + if (track_default_) + ChangeAdapter(adapter_path); +} + +void BluetoothAdapterChromeOs::AdapterRemoved( + const dbus::ObjectPath& adapter_path) { + if (adapter_path == object_path_) + RemoveAdapter(); +} + +void BluetoothAdapterChromeOs::ChangeAdapter( + const dbus::ObjectPath& adapter_path) { + if (object_path_.value().empty()) { + DVLOG(1) << "Adapter path initialized to " << adapter_path.value(); + } else if (object_path_.value() != adapter_path.value()) { + DVLOG(1) << "Adapter path changed from " << object_path_.value() + << " to " << adapter_path.value(); + + RemoveAdapter(); + } else { + DVLOG(1) << "Adapter address updated"; + } + + object_path_ = adapter_path; + + // Update properties to their new values. + BluetoothAdapterClient::Properties* properties = + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + GetProperties(object_path_); + + address_ = properties->address.value(); + name_ = properties->name.value(); + + // Delay announcing a new adapter until we have an address. + if (address_.empty()) { + DVLOG(1) << "Adapter address not yet known"; + return; + } + + PoweredChanged(properties->powered.value()); + DiscoveringChanged(properties->discovering.value()); + DevicesChanged(properties->devices.value()); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + AdapterPresentChanged(this, true)); +} + +void BluetoothAdapterChromeOs::RemoveAdapter() { + const bool adapter_was_present = IsPresent(); + + DVLOG(1) << "Adapter lost."; + PoweredChanged(false); + DiscoveringChanged(false); + ClearDevices(); + + object_path_ = dbus::ObjectPath(""); + address_.clear(); + name_.clear(); + + if (adapter_was_present) + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + AdapterPresentChanged(this, false)); +} + +void BluetoothAdapterChromeOs::OnSetPowered(const base::Closure& callback, + const ErrorCallback& error_callback, + bool success) { + if (success) + callback.Run(); + else + error_callback.Run(); +} + +void BluetoothAdapterChromeOs::PoweredChanged(bool powered) { + if (powered == powered_) + return; + + powered_ = powered; + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + AdapterPoweredChanged(this, powered_)); +} + +void BluetoothAdapterChromeOs::OnStartDiscovery( + const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, + bool success) { + if (success) { + DVLOG(1) << object_path_.value() << ": started discovery."; + + // Clear devices found in previous discovery attempts + ClearDiscoveredDevices(); + callback.Run(); + } else { + // TODO(keybuk): in future, don't run the callback if the error was just + // that we were already discovering. + error_callback.Run(); + } +} + +void BluetoothAdapterChromeOs::OnStopDiscovery( + const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, + bool success) { + if (success) { + DVLOG(1) << object_path_.value() << ": stopped discovery."; + callback.Run(); + // Leave found devices available for perusing. + } else { + // TODO(keybuk): in future, don't run the callback if the error was just + // that we weren't discovering. + error_callback.Run(); + } +} + +void BluetoothAdapterChromeOs::DiscoveringChanged(bool discovering) { + if (discovering == discovering_) + return; + + discovering_ = discovering; + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + AdapterDiscoveringChanged(this, discovering_)); +} + +void BluetoothAdapterChromeOs::OnReadLocalData( + const BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& callback, + const ErrorCallback& error_callback, + const BluetoothOutOfBandPairingData& data, + bool success) { + if (success) + callback.Run(data); + else + error_callback.Run(); +} + +void BluetoothAdapterChromeOs::AdapterPropertyChanged( + const dbus::ObjectPath& adapter_path, + const std::string& property_name) { + if (adapter_path != object_path_) + return; + + BluetoothAdapterClient::Properties* properties = + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + GetProperties(object_path_); + + if (property_name == properties->address.name()) { + ChangeAdapter(object_path_); + + } else if (!address_.empty()) { + if (property_name == properties->powered.name()) { + PoweredChanged(properties->powered.value()); + + } else if (property_name == properties->discovering.name()) { + DiscoveringChanged(properties->discovering.value()); + + } else if (property_name == properties->devices.name()) { + DevicesChanged(properties->devices.value()); + + } else if (property_name == properties->name.name()) { + name_ = properties->name.value(); + + } + } +} + +void BluetoothAdapterChromeOs::DevicePropertyChanged( + const dbus::ObjectPath& device_path, + const std::string& property_name) { + UpdateDevice(device_path); +} + +void BluetoothAdapterChromeOs::UpdateDevice( + const dbus::ObjectPath& device_path) { + BluetoothDeviceClient::Properties* properties = + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> + GetProperties(device_path); + + // When we first see a device, we may not know the address yet and need to + // wait for the DevicePropertyChanged signal before adding the device. + const std::string address = properties->address.value(); + if (address.empty()) + return; + + // The device may be already known to us, either because this is an update + // to properties, or the device going from discovered to connected and + // pairing gaining an object path in the process. In any case, we want + // to update the existing object, not create a new one. + DevicesMap::iterator iter = devices_.find(address); + BluetoothDeviceChromeOs* device; + const bool update_device = (iter != devices_.end()); + if (update_device) { + device = iter->second; + } else { + device = BluetoothDeviceChromeOs::Create(this); + devices_[address] = device; + } + + const bool was_paired = device->IsPaired(); + if (!was_paired) { + DVLOG(1) << "Assigned object path " << device_path.value() << " to device " + << address; + device->SetObjectPath(device_path); + } + device->Update(properties, true); + + if (update_device) { + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceChanged(this, device)); + } else { + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceAdded(this, device)); + } +} + +void BluetoothAdapterChromeOs::ClearDevices() { + DevicesMap replace; + devices_.swap(replace); + for (DevicesMap::iterator iter = replace.begin(); + iter != replace.end(); ++iter) { + BluetoothDeviceChromeOs* device = iter->second; + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceRemoved(this, device)); + + delete device; + } +} + +void BluetoothAdapterChromeOs::DeviceCreated( + const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path) { + if (adapter_path != object_path_) + return; + + UpdateDevice(device_path); +} + +void BluetoothAdapterChromeOs::DeviceRemoved( + const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path) { + if (adapter_path != object_path_) + return; + + DevicesMap::iterator iter = devices_.begin(); + while (iter != devices_.end()) { + BluetoothDeviceChromeOs* device = iter->second; + DevicesMap::iterator temp = iter; + ++iter; + + if (device->object_path_ != device_path) + continue; + + // 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()) { + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceRemoved(this, device)); + + DVLOG(1) << "Removed device " << device->address(); + + delete device; + devices_.erase(temp); + } else { + DVLOG(1) << "Removed object path from device " << device->address(); + device->RemoveObjectPath(); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceChanged(this, device)); + } + } +} + +void BluetoothAdapterChromeOs::DevicesChanged( + const std::vector& devices) { + for (std::vector::const_iterator iter = + devices.begin(); iter != devices.end(); ++iter) + UpdateDevice(*iter); +} + +void BluetoothAdapterChromeOs::ClearDiscoveredDevices() { + DevicesMap::iterator iter = devices_.begin(); + while (iter != devices_.end()) { + BluetoothDeviceChromeOs* device = iter->second; + DevicesMap::iterator temp = iter; + ++iter; + + if (!device->IsPaired()) { + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceRemoved(this, device)); + + delete device; + devices_.erase(temp); + } + } +} + +void BluetoothAdapterChromeOs::DeviceFound( + const dbus::ObjectPath& adapter_path, + const std::string& address, + const BluetoothDeviceClient::Properties& properties) { + if (adapter_path != object_path_) + return; + + // DeviceFound can also be called to indicate that a device we've + // paired with is now visible to the adapter during discovery, in which + // case we want to update the existing object, not create a new one. + BluetoothDeviceChromeOs* device; + DevicesMap::iterator iter = devices_.find(address); + const bool update_device = (iter != devices_.end()); + if (update_device) { + device = iter->second; + } else { + device = BluetoothDeviceChromeOs::Create(this); + devices_[address] = device; + } + + DVLOG(1) << "Device " << address << " is visible to the adapter"; + device->SetVisible(true); + device->Update(&properties, false); + + if (update_device) { + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceChanged(this, device)); + } else { + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceAdded(this, device)); + } +} + +void BluetoothAdapterChromeOs::DeviceDisappeared( + const dbus::ObjectPath& adapter_path, + const std::string& address) { + if (adapter_path != object_path_) + return; + + DevicesMap::iterator iter = devices_.find(address); + if (iter == devices_.end()) + return; + + BluetoothDeviceChromeOs* device = iter->second; + + // 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()) { + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceRemoved(this, device)); + + DVLOG(1) << "Discovered device " << device->address() + << " is no longer visible to the adapter"; + + delete device; + devices_.erase(iter); + } else { + DVLOG(1) << "Paired device " << device->address() + << " is no longer visible to the adapter"; + device->SetVisible(false); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + DeviceChanged(this, device)); + } +} + +} // namespace chromeos diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h new file mode 100644 index 0000000..18cb7aa --- /dev/null +++ b/device/bluetooth/bluetooth_adapter_chromeos.h @@ -0,0 +1,245 @@ +// Copyright (c) 2012 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_ADAPTER_CHROMEOS_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ + +#include +#include +#include + +#include "base/basictypes.h" +#include "base/callback.h" +#include "base/observer_list.h" +#include "chromeos/dbus/bluetooth_adapter_client.h" +#include "chromeos/dbus/bluetooth_device_client.h" +#include "chromeos/dbus/bluetooth_manager_client.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_adapter.h" + +namespace device { + +class BluetoothAdapterFactory; +class MockBluetoothAdapter; +struct BluetoothOutOfBandPairingData; + +} // namespace device + +namespace chromeos { + +class BluetoothDeviceChromeOs; + +// The BluetoothAdapterChromeOs class is an implementation of BluetoothAdapter +// for Chrome OS platform. +class BluetoothAdapterChromeOs + : public device::BluetoothAdapter, + public BluetoothManagerClient::Observer, + public BluetoothAdapterClient::Observer, + public BluetoothDeviceClient::Observer { + public: + // BluetoothAdapter override + virtual void AddObserver( + device::BluetoothAdapter::Observer* observer) OVERRIDE; + virtual void RemoveObserver( + device::BluetoothAdapter::Observer* observer) OVERRIDE; + virtual bool IsPresent() const OVERRIDE; + virtual bool IsPowered() const OVERRIDE; + virtual void SetPowered( + bool powered, + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual bool IsDiscovering() const OVERRIDE; + virtual void SetDiscovering( + bool discovering, + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual ConstDeviceList GetDevices() const OVERRIDE; + virtual device::BluetoothDevice* GetDevice( + const std::string& address) OVERRIDE; + virtual const device::BluetoothDevice* GetDevice( + const std::string& address) const OVERRIDE; + virtual void ReadLocalOutOfBandPairingData( + const device::BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& + callback, + const ErrorCallback& error_callback) OVERRIDE; + + private: + friend class BluetoothDeviceChromeOs; + friend class device::BluetoothAdapterFactory; + friend class device::MockBluetoothAdapter; + + BluetoothAdapterChromeOs(); + virtual ~BluetoothAdapterChromeOs(); + + // Obtains the default adapter object path from the Bluetooth Daemon + // and tracks future changes to it. + void TrackDefaultAdapter(); + + // Obtains the object paht for the adapter named by |address| from the + // Bluetooth Daemon. + void FindAdapter(const std::string& address); + + // Called by dbus:: in response to the method call sent by both + // DefaultAdapter() and FindAdapter(), |object_path| will contain the + // dbus object path of the requested adapter when |success| is true. + void AdapterCallback(const dbus::ObjectPath& adapter_path, bool success); + + // BluetoothManagerClient::Observer override. + // + // Called when the default local bluetooth adapter changes. + // |object_path| is the dbus object path of the new default adapter. + // Not called if all adapters are removed. + virtual void DefaultAdapterChanged(const dbus::ObjectPath& adapter_path) + OVERRIDE; + + // BluetoothManagerClient::Observer override. + // + // Called when a local bluetooth adapter is removed. + // |object_path| is the dbus object path of the adapter. + virtual void AdapterRemoved(const dbus::ObjectPath& adapter_path) OVERRIDE; + + // Changes the tracked adapter to the dbus object path |adapter_path|, + // clearing information from the previously tracked adapter and updating + // to the new adapter. + void ChangeAdapter(const dbus::ObjectPath& adapter_path); + + // Clears the tracked adapter information. + void RemoveAdapter(); + + // Called by dbus:: in response to the method call send by SetPowered(). + // |callback| and |error_callback| are the callbacks passed to SetPowered(). + void OnSetPowered(const base::Closure& callback, + const ErrorCallback& error_callback, + bool success); + + // Updates the tracked state of the adapter's radio power to |powered| + // and notifies observers. Called on receipt of a property changed signal, + // and directly using values obtained from properties. + void PoweredChanged(bool powered); + + // Called by dbus:: in response to the method calls send by SetDiscovering(). + // |callback| and |error_callback| are the callbacks passed to + // SetDiscovering(). + void OnStartDiscovery(const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, + bool success); + void OnStopDiscovery(const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, + bool success); + + // Updates the tracked state of the adapter's discovering state to + // |discovering| and notifies observers. Called on receipt of a property + // changed signal, and directly using values obtained from properties. + void DiscoveringChanged(bool discovering); + + // Called by dbus:: in response to the ReadLocalData method call. + void OnReadLocalData( + const device::BluetoothAdapter::BluetoothOutOfBandPairingDataCallback& + callback, + const ErrorCallback& error_callback, + const device::BluetoothOutOfBandPairingData& data, + bool success); + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |adapter_path| has a + // change in value of the property named |property_name|. + virtual void AdapterPropertyChanged(const dbus::ObjectPath& adapter_path, + const std::string& property_name) + OVERRIDE; + + // BluetoothDeviceClient::Observer override. + // + // Called when the device with object path |device_path| has a + // change in value of the property named |property_name|. + virtual void DevicePropertyChanged(const dbus::ObjectPath& device_path, + const std::string& property_name) + OVERRIDE; + + // Updates information on the device with object path |device_path|, + // adding it to the |devices_| map if not already present. + void UpdateDevice(const dbus::ObjectPath& device_path); + + // Clears the |devices_| list, notifying obsevers of the device removal. + void ClearDevices(); + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |object_path| has a + // new known device with object path |object_path|. + virtual void DeviceCreated(const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path) OVERRIDE; + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |object_path| removes + // the known device with object path |object_path|. + virtual void DeviceRemoved(const dbus::ObjectPath& adapter_path, + const dbus::ObjectPath& device_path) OVERRIDE; + + // Updates the adapter |devices_| list, adding or updating devices using + // the object paths in the|devices| list. This doesn't remove devices, + // relying instead on the DeviceRemoved() signal for that. Called on + // receipt of a property changed signal, and directly using values obtained + // from properties. + void DevicesChanged(const std::vector& devices); + + // Clears discovered devices from the |devices_| list, notifying + // observers, and leaving only those devices with a dbus object path. + void ClearDiscoveredDevices(); + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |object_path| discovers + // a new remote device with address |address| and properties + // |properties|, there is no device object path until connected. + // + // |properties| supports only value() calls, not Get() or Set(), and + // should be copied if needed. + virtual void DeviceFound( + const dbus::ObjectPath& adapter_path, + const std::string& address, + const BluetoothDeviceClient::Properties& properties) OVERRIDE; + + // BluetoothAdapterClient::Observer override. + // + // Called when the adapter with object path |object_path| can no + // longer communicate with the discovered removed device with + // address |address|. + virtual void DeviceDisappeared(const dbus::ObjectPath& object_path, + const std::string& address) OVERRIDE; + + // List of observers interested in event notifications from us. + ObserverList observers_; + + // Object path of adapter for this instance, this is fixed at creation time + // unless |track_default_| is true in which case we update it to always + // point at the default adapter. + bool track_default_; + dbus::ObjectPath object_path_; + + // Tracked adapter state, cached locally so we only send change notifications + // to observers on a genuine change. + bool powered_; + bool discovering_; + + // Devices paired with, connected to, discovered by, or visible to the + // adapter. The key is the Bluetooth address of the device and the value + // is the BluetoothDeviceChromeOs object whose lifetime is managed by the + // adapter instance. + typedef std::map DevicesMap; + DevicesMap devices_; + + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterChromeOs); +}; + +} // namespace chromeos + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_CHROMEOS_H_ diff --git a/device/bluetooth/bluetooth_adapter_chromeos_devices_unittest.cc b/device/bluetooth/bluetooth_adapter_chromeos_devices_unittest.cc new file mode 100644 index 0000000..0ff8d3d --- /dev/null +++ b/device/bluetooth/bluetooth_adapter_chromeos_devices_unittest.cc @@ -0,0 +1,168 @@ +// Copyright (c) 2012 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 "chromeos/dbus/mock_bluetooth_adapter_client.h" +#include "chromeos/dbus/mock_bluetooth_device_client.h" +#include "chromeos/dbus/mock_bluetooth_manager_client.h" +#include "chromeos/dbus/mock_dbus_thread_manager.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_chromeos.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/test/mock_bluetooth_adapter.h" +#include "testing/gtest/include/gtest/gtest.h" + +using device::BluetoothAdapter; +using device::BluetoothAdapterFactory; +using device::BluetoothDevice; +using device::MockBluetoothAdapter; +using ::testing::_; +using ::testing::Mock; +using ::testing::Return; +using ::testing::SaveArg; + +namespace chromeos { + +class BluetoothAdapterChromeOsDevicesTest : public testing::Test { + public: + virtual void SetUp() { + MockDBusThreadManager* mock_dbus_thread_manager = new MockDBusThreadManager; + + EXPECT_CALL(*mock_dbus_thread_manager, GetSystemBus()) + .WillRepeatedly(Return(reinterpret_cast(NULL))); + DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager); + + mock_manager_client_ = + mock_dbus_thread_manager->mock_bluetooth_manager_client(); + mock_adapter_client_ = + mock_dbus_thread_manager->mock_bluetooth_adapter_client(); + mock_device_client_ = + mock_dbus_thread_manager->mock_bluetooth_device_client(); + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + EXPECT_CALL(*mock_manager_client_, AddObserver(_)) + .Times(1); + EXPECT_CALL(*mock_adapter_client_, AddObserver(_)) + .Times(1); + + adapter_ = BluetoothAdapterFactory::DefaultAdapter(); + ASSERT_TRUE(adapter_.get() != NULL); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address_); + adapter_properties.powered.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path_)) + .WillRepeatedly(Return(&adapter_properties)); + + // Add an observer to the adapter; expect the usual set of changes to + // an adapter becoming present and then clear to clean up for the test. + adapter_->AddObserver(&adapter_observer_); + + EXPECT_CALL(adapter_observer_, AdapterPresentChanged(adapter_.get(), true)) + .Times(1); + EXPECT_CALL(adapter_observer_, AdapterPoweredChanged(adapter_.get(), true)) + .Times(1); + + adapter_callback.Run(adapter_path_, true); + + Mock::VerifyAndClearExpectations(mock_manager_client_); + Mock::VerifyAndClearExpectations(mock_adapter_client_); + Mock::VerifyAndClearExpectations(mock_device_client_); + Mock::VerifyAndClearExpectations(&adapter_observer_); + } + + virtual void TearDown() { + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter_.get()); + EXPECT_CALL(*mock_device_client_, RemoveObserver(adapter_chromeos)) + .Times(1); + EXPECT_CALL(*mock_adapter_client_, RemoveObserver(adapter_chromeos)) + .Times(1); + EXPECT_CALL(*mock_manager_client_, RemoveObserver(adapter_chromeos)) + .Times(1); + + adapter_ = NULL; + DBusThreadManager::Shutdown(); + } + + protected: + MockBluetoothManagerClient* mock_manager_client_; + MockBluetoothAdapterClient* mock_adapter_client_; + MockBluetoothDeviceClient* mock_device_client_; + + static const dbus::ObjectPath adapter_path_; + static const std::string adapter_address_; + scoped_refptr adapter_; + + MockBluetoothAdapter::Observer adapter_observer_; +}; + +const dbus::ObjectPath BluetoothAdapterChromeOsDevicesTest::adapter_path_( + "/fake/hci0"); +const std::string BluetoothAdapterChromeOsDevicesTest::adapter_address_ = + "CA:FE:4A:C0:FE:FE"; + +TEST_F(BluetoothAdapterChromeOsDevicesTest, DeviceRemovedAfterFound) { + const dbus::ObjectPath device_path("/fake/hci0/dev_ba_c0_11_00_00_01"); + const std::string device_address = "BA:C0:11:00:00:01"; + + MockBluetoothDeviceClient::Properties device_properties; + device_properties.address.ReplaceValue(device_address); + device_properties.name.ReplaceValue("Fake Keyboard"); + device_properties.bluetooth_class.ReplaceValue(0x2540); + + // Inform the adapter that the device has been found; + // BluetoothAdapterClient::Observer::DeviceAdded will be called, passing + // the device object. + BluetoothDevice* device; + EXPECT_CALL(adapter_observer_, DeviceAdded(adapter_.get(), _)) + .Times(1) + .WillOnce(SaveArg<1>(&device)); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter_.get()); + static_cast(adapter_chromeos) + ->DeviceFound(adapter_path_, device_address, device_properties); + + // Now inform the adapter that the device has been added and assigned an + // object path; BluetoothDeviceClient::GetProperties will be called to + // obtain the property set; and + // BluetoothAdapterClient::Observer::DeviceChanged will be called passing + // the same device object as before. + EXPECT_CALL(*mock_device_client_, GetProperties(device_path)) + .WillRepeatedly(Return(&device_properties)); + + EXPECT_CALL(adapter_observer_, DeviceChanged(adapter_chromeos, device)) + .Times(1); + + static_cast(adapter_chromeos) + ->DeviceCreated(adapter_path_, device_path); + + // Finally remove the adapter again; + // BluetoothAdapterClient::Observer::DeviceRemoved should be not called, + // instead BluetoothAdapterClient::Observer::DeviceChanged will be called. + EXPECT_CALL(adapter_observer_, DeviceRemoved(adapter_.get(), device)) + .Times(0); + EXPECT_CALL(adapter_observer_, DeviceChanged(adapter_.get(), device)) + .Times(1); + + static_cast(adapter_chromeos) + ->DeviceRemoved(adapter_path_, device_path); + + // Verify that the device is still visible, just no longer paired. + EXPECT_TRUE(device->IsVisible()); + EXPECT_FALSE(device->IsPaired()); +} + +} // namespace chromeos diff --git a/device/bluetooth/bluetooth_adapter_chromeos_unittest.cc b/device/bluetooth/bluetooth_adapter_chromeos_unittest.cc new file mode 100644 index 0000000..890d241 --- /dev/null +++ b/device/bluetooth/bluetooth_adapter_chromeos_unittest.cc @@ -0,0 +1,1557 @@ +// Copyright (c) 2012 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 "chromeos/dbus/mock_bluetooth_adapter_client.h" +#include "chromeos/dbus/mock_bluetooth_manager_client.h" +#include "chromeos/dbus/mock_dbus_thread_manager.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_chromeos.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/test/mock_bluetooth_adapter.h" +#include "testing/gtest/include/gtest/gtest.h" + +using device::BluetoothAdapter; +using device::BluetoothAdapterFactory; +using device::MockBluetoothAdapter; +using ::testing::_; +using ::testing::InSequence; +using ::testing::Return; +using ::testing::SaveArg; + +namespace chromeos { + +class BluetoothAdapterChromeOsTest : public testing::Test { + public: + virtual void SetUp() { + MockDBusThreadManager* mock_dbus_thread_manager = new MockDBusThreadManager; + + EXPECT_CALL(*mock_dbus_thread_manager, GetSystemBus()) + .WillRepeatedly(Return(reinterpret_cast(NULL))); + DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager); + + mock_manager_client_ = + mock_dbus_thread_manager->mock_bluetooth_manager_client(); + mock_adapter_client_ = + mock_dbus_thread_manager->mock_bluetooth_adapter_client(); + + set_callback_called_ = false; + error_callback_called_ = false; + } + + virtual void TearDown() { + DBusThreadManager::Shutdown(); + } + + void SetCallback() { + set_callback_called_ = true; + } + + void ErrorCallback() { + error_callback_called_ = true; + } + + protected: + MockBluetoothManagerClient* mock_manager_client_; + MockBluetoothAdapterClient* mock_adapter_client_; + + bool set_callback_called_; + bool error_callback_called_; +}; + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterNotPresent) { + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + ASSERT_TRUE(adapter.get() != NULL); + + // Call the adapter callback; make out it failed. + // BluetoothAdapter::Observer::AdapterPresentChanged must not be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) + .Times(0); + + adapter_callback.Run(dbus::ObjectPath(""), false); + + // Adapter should not be present. + EXPECT_FALSE(adapter->IsPresent()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterWithAddress) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + // BluetoothAdapter::Observer::AdapterPresentChanged will be called to + // indicate the adapter is now present. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + adapter_callback.Run(adapter_path, true); + + // Adapter should be present with the given address. + EXPECT_TRUE(adapter->IsPresent()); + EXPECT_EQ(adapter_address, adapter->address()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterWithoutAddress) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + // BluetoothAdapter::Observer::AdapterPresentChanged must not be called + // yet. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) + .Times(0); + + adapter_callback.Run(adapter_path, true); + + // Adapter should not be present yet. + EXPECT_FALSE(adapter->IsPresent()); + + // Tell the adapter the address now; + // BluetoothAdapter::Observer::AdapterPresentChanged now must be called. + adapter_properties.address.ReplaceValue(adapter_address); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.address.name()); + + // Adapter should be present with the given address. + EXPECT_TRUE(adapter->IsPresent()); + EXPECT_EQ(adapter_address, adapter->address()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterBecomesPresentWithAddress) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; make out it failed. + adapter_callback.Run(dbus::ObjectPath(""), false); + + // Tell the adapter the default adapter changed; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + // BluetoothAdapter::Observer::AdapterPresentChanged must be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->DefaultAdapterChanged(adapter_path); + + // Adapter should be present with the new address. + EXPECT_TRUE(adapter->IsPresent()); + EXPECT_EQ(adapter_address, adapter->address()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterReplacedWithAddress) { + const dbus::ObjectPath initial_adapter_path("/fake/hci0"); + const dbus::ObjectPath new_adapter_path("/fake/hci1"); + const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; + const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties initial_adapter_properties; + initial_adapter_properties.address.ReplaceValue(initial_adapter_address); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) + .WillRepeatedly(Return(&initial_adapter_properties)); + + adapter_callback.Run(initial_adapter_path, true); + + // Tell the adapter the default adapter changed; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties new_adapter_properties; + new_adapter_properties.address.ReplaceValue(new_adapter_address); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) + .WillRepeatedly(Return(&new_adapter_properties)); + + // BluetoothAdapter::Observer::AdapterPresentChanged must be called once + // with false to indicate the old adapter being removed and once with true + // to announce the new adapter. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) + .Times(1); + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->DefaultAdapterChanged(new_adapter_path); + + // Adapter should be present with the new address. + EXPECT_TRUE(adapter->IsPresent()); + EXPECT_EQ(new_adapter_address, adapter->address()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterBecomesPresentWithoutAddress) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; make out it failed. + adapter_callback.Run(dbus::ObjectPath(""), false); + + // Tell the adapter the default adapter changed; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + // BluetoothAdapter::Observer::AdapterPresentChanged must not be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) + .Times(0); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->DefaultAdapterChanged(adapter_path); + + // Adapter should not be present yet. + EXPECT_FALSE(adapter->IsPresent()); + + // Tell the adapter the address now; + // BluetoothAdapter::Observer::AdapterPresentChanged now must be called. + adapter_properties.address.ReplaceValue(adapter_address); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.address.name()); + + // Adapter should be present with the new address. + EXPECT_TRUE(adapter->IsPresent()); + EXPECT_EQ(adapter_address, adapter->address()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterReplacedWithoutAddress) { + const dbus::ObjectPath initial_adapter_path("/fake/hci0"); + const dbus::ObjectPath new_adapter_path("/fake/hci1"); + const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; + const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties initial_adapter_properties; + initial_adapter_properties.address.ReplaceValue(initial_adapter_address); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) + .WillRepeatedly(Return(&initial_adapter_properties)); + + adapter_callback.Run(initial_adapter_path, true); + + // Tell the adapter the default adapter changed; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties new_adapter_properties; + + EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) + .WillRepeatedly(Return(&new_adapter_properties)); + + // BluetoothAdapter::Observer::AdapterPresentChanged must be called to + // indicate the adapter has gone away. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->DefaultAdapterChanged(new_adapter_path); + + // Adapter should be now marked not present. + EXPECT_FALSE(adapter->IsPresent()); + + // Tell the adapter the address now; + // BluetoothAdapter::Observer::AdapterPresentChanged now must be called. + new_adapter_properties.address.ReplaceValue(new_adapter_address); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(new_adapter_path, + new_adapter_properties.address.name()); + + // Adapter should be present with the new address. + EXPECT_TRUE(adapter->IsPresent()); + EXPECT_EQ(new_adapter_address, adapter->address()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterRemoved) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Report that the adapter has been removed; + // BluetoothAdapter::Observer::AdapterPresentChanged will be called to + // indicate the adapter is no longer present. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterRemoved(adapter_path); + + // Adapter should be no longer present. + EXPECT_FALSE(adapter->IsPresent()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterWithoutAddressRemoved) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Report that the adapter has been removed; + // BluetoothAdapter::Observer::AdapterPresentChanged must not be called + // since we never should have announced it in the first place. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), _)) + .Times(0); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterRemoved(adapter_path); + + // Adapter should be still no longer present. + EXPECT_FALSE(adapter->IsPresent()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyInitiallyFalse) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.powered.ReplaceValue(false); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Adapter should have the correct property value. + EXPECT_FALSE(adapter->IsPowered()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyInitiallyTrue) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.powered.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + // BluetoothAdapter::Observer::AdapterPoweredChanged will be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) + .Times(1); + + adapter_callback.Run(adapter_path, true); + + // Adapter should have the correct property value. + EXPECT_TRUE(adapter->IsPowered()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyInitiallyTrueWithoutAddress) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set but BluetoothAdapter::Observer::AdapterPoweredChanged + // should not yet be called. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.powered.ReplaceValue(true); + + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) + .Times(0); + + adapter_callback.Run(adapter_path, true); + + // Adapter should not yet have the property value. + EXPECT_FALSE(adapter->IsPowered()); + + // Tell the adapter the address now, + // BluetoothAdapter::Observer::AdapterPresentChanged and + // BluetoothAdapter::Observer::AdapterPoweredChanged now must be called. + adapter_properties.address.ReplaceValue(adapter_address); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.address.name()); + + // Adapter should have the correct property value. + EXPECT_TRUE(adapter->IsPowered()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterPoweredPropertyChanged) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.powered.ReplaceValue(false); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Adapter should have the correct property value. + EXPECT_FALSE(adapter->IsPowered()); + + // Report that the property has been changed; + // BluetoothAdapter::Observer::AdapterPoweredChanged will be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) + .Times(1); + + adapter_properties.powered.ReplaceValue(true); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.powered.name()); + + // Adapter should have the new property values. + EXPECT_TRUE(adapter->IsPowered()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterPoweredPropertyUnchanged) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.powered.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Adapter should have the correct property value. + EXPECT_TRUE(adapter->IsPowered()); + + // Report that the property has been changed, but don't change the value; + // BluetoothAdapter::Observer::AdapterPoweredChanged should not be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) + .Times(0); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.powered.name()); + + // Adapter should still have the same property values. + EXPECT_TRUE(adapter->IsPowered()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyChangedWithoutAddress) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set but BluetoothAdapter::Observer::AdapterPoweredChanged + // should not yet be called. + MockBluetoothAdapterClient::Properties adapter_properties; + + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) + .Times(0); + + adapter_callback.Run(adapter_path, true); + + // Tell the adapter that its powered property changed, the observer + // method should still not be called because there is no address for + // the adapter so it is not present. + adapter_properties.powered.ReplaceValue(true); + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), _)) + .Times(0); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.powered.name()); + + // Adapter should not yet have the property value. + EXPECT_FALSE(adapter->IsPowered()); + + // Tell the adapter the address now, + // BluetoothAdapter::Observer::AdapterPresentChanged and + // BluetoothAdapter::Observer::AdapterPoweredChanged now must be called. + adapter_properties.address.ReplaceValue(adapter_address); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) + .Times(1); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.address.name()); + + // Adapter should now have the correct property value. + EXPECT_TRUE(adapter->IsPowered()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyResetOnReplace) { + const dbus::ObjectPath initial_adapter_path("/fake/hci0"); + const dbus::ObjectPath new_adapter_path("/fake/hci1"); + const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; + const std::string new_adapter_address = "00:C0:11:CO:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties initial_adapter_properties; + initial_adapter_properties.address.ReplaceValue(initial_adapter_address); + initial_adapter_properties.powered.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) + .WillRepeatedly(Return(&initial_adapter_properties)); + + adapter_callback.Run(initial_adapter_path, true); + + // Tell the adapter the default adapter changed; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties new_adapter_properties; + new_adapter_properties.address.ReplaceValue(new_adapter_address); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) + .WillRepeatedly(Return(&new_adapter_properties)); + + // BluetoothAdapter::Observer::AdapterPoweredChanged will be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + { + InSequence s; + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) + .Times(1); + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + } + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), false)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->DefaultAdapterChanged(new_adapter_path); + + // Adapter should have the new property value. + EXPECT_FALSE(adapter->IsPowered()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyResetOnReplaceWhenTrue) { + const dbus::ObjectPath initial_adapter_path("/fake/hci0"); + const dbus::ObjectPath new_adapter_path("/fake/hci1"); + const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; + const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties initial_adapter_properties; + initial_adapter_properties.address.ReplaceValue(initial_adapter_address); + initial_adapter_properties.powered.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) + .WillRepeatedly(Return(&initial_adapter_properties)); + + adapter_callback.Run(initial_adapter_path, true); + + // Tell the adapter the default adapter changed; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties new_adapter_properties; + new_adapter_properties.address.ReplaceValue(new_adapter_address); + new_adapter_properties.powered.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) + .WillRepeatedly(Return(&new_adapter_properties)); + + // BluetoothAdapter::Observer::AdapterPoweredChanged will be called once + // to set the value to false for the previous adapter and once to set the + // value to true for the new adapter. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + { + InSequence s; + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) + .Times(1); + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + } + + { + InSequence s; + + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), false)) + .Times(1); + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), true)) + .Times(1); + } + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->DefaultAdapterChanged(new_adapter_path); + + // Adapter should have the new property value. + EXPECT_TRUE(adapter->IsPowered()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterPoweredPropertyResetOnRemove) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.powered.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Report that the adapter has been removed; + // BluetoothAdapter::Observer::AdapterPoweredChanged will be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) + .Times(1); + EXPECT_CALL(adapter_observer, AdapterPoweredChanged(adapter.get(), false)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterRemoved(adapter_path); + + // Adapter should have the new property value. + EXPECT_FALSE(adapter->IsPowered()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterSetPowered) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Request that the powered property be changed; + // MockBluetoothAdapterClient::Set should be called, passing the address + // of the powered property and a callback to receive the response. + dbus::PropertySet::SetCallback set_callback; + EXPECT_CALL(adapter_properties, Set(&adapter_properties.powered, _)) + .WillOnce(SaveArg<1>(&set_callback)); + + adapter->SetPowered(true, + base::Bind(&BluetoothAdapterChromeOsTest::SetCallback, + base::Unretained(this)), + base::Bind(&BluetoothAdapterChromeOsTest::ErrorCallback, + base::Unretained(this))); + + // Reply to the callback to indicate success, the set callback we provided + // should be called but the properties should not be refetched. + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .Times(0); + + set_callback.Run(true); + + EXPECT_TRUE(set_callback_called_); + EXPECT_FALSE(error_callback_called_); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterSetPoweredError) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Request that the powered property be changed; + // MockBluetoothAdapterClient::Set should be called, passing the address + // of the powered property and a callback to receive the response. + dbus::PropertySet::SetCallback set_callback; + EXPECT_CALL(adapter_properties, Set(&adapter_properties.powered, _)) + .WillOnce(SaveArg<1>(&set_callback)); + + adapter->SetPowered(true, + base::Bind(&BluetoothAdapterChromeOsTest::SetCallback, + base::Unretained(this)), + base::Bind(&BluetoothAdapterChromeOsTest::ErrorCallback, + base::Unretained(this))); + + // Reply to the callback to indicate failure, the error callback we provided + // should be called but the properties should not be refetched. + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .Times(0); + + set_callback.Run(false); + + EXPECT_FALSE(set_callback_called_); + EXPECT_TRUE(error_callback_called_); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyInitiallyFalse) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.discovering.ReplaceValue(false); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Adapter should have the correct property value. + EXPECT_FALSE(adapter->IsDiscovering()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyInitiallyTrue) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.discovering.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) + .Times(1); + + adapter_callback.Run(adapter_path, true); + + // Adapter should have the correct property value. + EXPECT_TRUE(adapter->IsDiscovering()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyInitiallyTrueWithoutAddress) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set but BluetoothAdapter::Observer::AdapterDiscoveringChanged + // should not yet be called. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.discovering.ReplaceValue(true); + + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) + .Times(0); + + adapter_callback.Run(adapter_path, true); + + // Adapter should not yet have the property value. + EXPECT_FALSE(adapter->IsDiscovering()); + + // Tell the adapter the address now, + // BluetoothAdapter::Observer::AdapterPresentChanged and + // BluetoothAdapter::Observer::AdapterDiscoveringChanged now must be called. + adapter_properties.address.ReplaceValue(adapter_address); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.address.name()); + + // Adapter should have the correct property value. + EXPECT_TRUE(adapter->IsDiscovering()); +} + +TEST_F(BluetoothAdapterChromeOsTest, DefaultAdapterDiscoveringPropertyChanged) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.discovering.ReplaceValue(false); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Adapter should have the correct property value. + EXPECT_FALSE(adapter->IsDiscovering()); + + // Report that the property has been changed; + // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) + .Times(1); + + adapter_properties.discovering.ReplaceValue(true); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.discovering.name()); + + // Adapter should have the new property values. + EXPECT_TRUE(adapter->IsDiscovering()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyUnchanged) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.discovering.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Adapter should have the correct property value. + EXPECT_TRUE(adapter->IsDiscovering()); + + // Report that the property has been changed, but don't change the value; + // BluetoothAdapter::Observer::AdapterDiscoveringChanged should not be + // called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) + .Times(0); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.discovering.name()); + + // Adapter should still have the same property values. + EXPECT_TRUE(adapter->IsDiscovering()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyChangedWithoutAddress) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set but BluetoothAdapter::Observer::AdapterDiscoveringChanged + // should not yet be called. + MockBluetoothAdapterClient::Properties adapter_properties; + + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) + .Times(0); + + adapter_callback.Run(adapter_path, true); + + // Tell the adapter that its discovering property changed, the observer + // method should still not be called because there is no address for + // the adapter so it is not present. + adapter_properties.discovering.ReplaceValue(true); + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), _)) + .Times(0); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.discovering.name()); + + // Adapter should not yet have the property value. + EXPECT_FALSE(adapter->IsDiscovering()); + + // Tell the adapter the address now, + // BluetoothAdapter::Observer::AdapterPresentChanged and + // BluetoothAdapter::Observer::AdapterDiscoveringChanged now must be called. + adapter_properties.address.ReplaceValue(adapter_address); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), true)) + .Times(1); + + static_cast(adapter_chromeos) + ->AdapterPropertyChanged(adapter_path, + adapter_properties.address.name()); + + // Adapter should now have the correct property value. + EXPECT_TRUE(adapter->IsDiscovering()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyResetOnReplace) { + const dbus::ObjectPath initial_adapter_path("/fake/hci0"); + const dbus::ObjectPath new_adapter_path("/fake/hci1"); + const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; + const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties initial_adapter_properties; + initial_adapter_properties.address.ReplaceValue(initial_adapter_address); + initial_adapter_properties.discovering.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) + .WillRepeatedly(Return(&initial_adapter_properties)); + + adapter_callback.Run(initial_adapter_path, true); + + // Tell the adapter the default adapter changed; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties new_adapter_properties; + new_adapter_properties.address.ReplaceValue(new_adapter_address); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) + .WillRepeatedly(Return(&new_adapter_properties)); + + // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + { + InSequence s; + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) + .Times(1); + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + } + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), false)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->DefaultAdapterChanged(new_adapter_path); + + // Adapter should have the new property value. + EXPECT_FALSE(adapter->IsDiscovering()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyResetOnReplaceWhenTrue) { + const dbus::ObjectPath initial_adapter_path("/fake/hci0"); + const dbus::ObjectPath new_adapter_path("/fake/hci1"); + const std::string initial_adapter_address = "CA:FE:4A:C0:FE:FE"; + const std::string new_adapter_address = "BA:C0:11:CO:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties initial_adapter_properties; + initial_adapter_properties.address.ReplaceValue(initial_adapter_address); + initial_adapter_properties.discovering.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(initial_adapter_path)) + .WillRepeatedly(Return(&initial_adapter_properties)); + + adapter_callback.Run(initial_adapter_path, true); + + // Tell the adapter the default adapter changed; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties new_adapter_properties; + new_adapter_properties.address.ReplaceValue(new_adapter_address); + new_adapter_properties.discovering.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(new_adapter_path)) + .WillRepeatedly(Return(&new_adapter_properties)); + + // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called once + // to set the value to false for the previous adapter and once to set the + // value to true for the new adapter. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + { + InSequence s; + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) + .Times(1); + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), true)) + .Times(1); + } + + { + InSequence s; + + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), + false)) + .Times(1); + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), + true)) + .Times(1); + } + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->DefaultAdapterChanged(new_adapter_path); + + // Adapter should have the new property value. + EXPECT_TRUE(adapter->IsDiscovering()); +} + +TEST_F(BluetoothAdapterChromeOsTest, + DefaultAdapterDiscoveringPropertyResetOnRemove) { + const dbus::ObjectPath adapter_path("/fake/hci0"); + const std::string adapter_address = "CA:FE:4A:C0:FE:FE"; + + // Create the default adapter instance; + // BluetoothManagerClient::DefaultAdapter will be called once, passing + // a callback to obtain the adapter path. + BluetoothManagerClient::AdapterCallback adapter_callback; + EXPECT_CALL(*mock_manager_client_, DefaultAdapter(_)) + .WillOnce(SaveArg<0>(&adapter_callback)); + + scoped_refptr adapter = + BluetoothAdapterFactory::DefaultAdapter(); + + // Call the adapter callback; + // BluetoothAdapterClient::GetProperties will be called once to obtain + // the property set. + MockBluetoothAdapterClient::Properties adapter_properties; + adapter_properties.address.ReplaceValue(adapter_address); + adapter_properties.discovering.ReplaceValue(true); + + EXPECT_CALL(*mock_adapter_client_, GetProperties(adapter_path)) + .WillRepeatedly(Return(&adapter_properties)); + + adapter_callback.Run(adapter_path, true); + + // Report that the adapter has been removed; + // BluetoothAdapter::Observer::AdapterDiscoveringChanged will be called. + MockBluetoothAdapter::Observer adapter_observer; + adapter->AddObserver(&adapter_observer); + + EXPECT_CALL(adapter_observer, AdapterPresentChanged(adapter.get(), false)) + .Times(1); + EXPECT_CALL(adapter_observer, AdapterDiscoveringChanged(adapter.get(), false)) + .Times(1); + + BluetoothAdapterChromeOs* adapter_chromeos = + static_cast(adapter.get()); + + static_cast(adapter_chromeos) + ->AdapterRemoved(adapter_path); + + // Adapter should have the new property value. + EXPECT_FALSE(adapter->IsDiscovering()); +} + +} // namespace chromeos diff --git a/device/bluetooth/bluetooth_adapter_factory.cc b/device/bluetooth/bluetooth_adapter_factory.cc new file mode 100644 index 0000000..03d633f --- /dev/null +++ b/device/bluetooth/bluetooth_adapter_factory.cc @@ -0,0 +1,55 @@ +// Copyright (c) 2012 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_adapter_factory.h" + +#include "base/lazy_instance.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "device/bluetooth/bluetooth_adapter.h" + +#if defined(OS_CHROMEOS) +#include "device/bluetooth/bluetooth_adapter_chromeos.h" +#endif + +namespace { + +// Shared default adapter instance, we don't want to keep this class around +// if nobody is using it so use a WeakPtr and create the object when needed; +// since Google C++ Style (and clang's static analyzer) forbids us having +// exit-time destructors we use a leaky lazy instance for it. +base::LazyInstance >::Leaky + default_adapter = LAZY_INSTANCE_INITIALIZER; + +} // namespace + +namespace device { + +// static +scoped_refptr BluetoothAdapterFactory::DefaultAdapter() { + if (!default_adapter.Get().get()) { +#if defined(OS_CHROMEOS) + chromeos::BluetoothAdapterChromeOs* new_adapter = + new chromeos::BluetoothAdapterChromeOs; + new_adapter->TrackDefaultAdapter(); + default_adapter.Get() = new_adapter->weak_ptr_factory_.GetWeakPtr(); +#endif + } + + return scoped_refptr(default_adapter.Get()); +} + +// static +BluetoothAdapter* BluetoothAdapterFactory::Create(const std::string& address) { + BluetoothAdapter* adapter = NULL; +#if defined(OS_CHROMEOS) + chromeos::BluetoothAdapterChromeOs* adapter_chromeos = + new chromeos::BluetoothAdapterChromeOs; + adapter_chromeos->FindAdapter(address); + adapter = adapter_chromeos; +#endif + return adapter; +} + +} // namespace device diff --git a/device/bluetooth/bluetooth_adapter_factory.h b/device/bluetooth/bluetooth_adapter_factory.h new file mode 100644 index 0000000..82e1e6f --- /dev/null +++ b/device/bluetooth/bluetooth_adapter_factory.h @@ -0,0 +1,33 @@ +// Copyright (c) 2012 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_ADAPTER_FACTORY_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_FACTORY_H_ + +#include + +#include "base/memory/ref_counted.h" + +namespace device { + +class BluetoothAdapter; + +// BluetoothAdapterFactory is a class that contains static methods, which +// instantiate either a specific bluetooth adapter, or the generic "default +// adapter" which may change depending on availability. +class BluetoothAdapterFactory { + public: + // Returns the shared instance for the default adapter, whichever that may + // be at the time. Check the returned scoped_refptr does not point to NULL and + // use IsPresent() and the AdapterPresentChanged() observer method to + // determine whether an adapter is actually available or not. + static scoped_refptr DefaultAdapter(); + + // Creates an instance for a specific adapter at address |address|. + static BluetoothAdapter* Create(const std::string& address); +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_FACTORY_H_ diff --git a/device/bluetooth/bluetooth_device.cc b/device/bluetooth/bluetooth_device.cc new file mode 100644 index 0000000..378c6ce --- /dev/null +++ b/device/bluetooth/bluetooth_device.cc @@ -0,0 +1,170 @@ +// Copyright (c) 2012 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_device.h" + +#include "base/utf_string_conversions.h" +#include "grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" + +namespace device { + +BluetoothDevice::BluetoothDevice() + : bluetooth_class_(0), + visible_(false), + bonded_(false), + connected_(false) { +} + +BluetoothDevice::~BluetoothDevice() { +} + +const std::string& BluetoothDevice::address() const { + return address_; +} + +string16 BluetoothDevice::GetName() const { + if (!name_.empty()) { + return UTF8ToUTF16(name_); + } else { + return GetAddressWithLocalizedDeviceTypeName(); + } +} + +string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const { + string16 address = UTF8ToUTF16(address_); + BluetoothDevice::DeviceType device_type = GetDeviceType(); + switch (device_type) { + case DEVICE_COMPUTER: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER, + address); + case DEVICE_PHONE: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE, + address); + case DEVICE_MODEM: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM, + address); + case DEVICE_AUDIO: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO, + address); + case DEVICE_CAR_AUDIO: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO, + address); + case DEVICE_VIDEO: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO, + address); + case DEVICE_JOYSTICK: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK, + address); + case DEVICE_GAMEPAD: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD, + address); + case DEVICE_KEYBOARD: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD, + address); + case DEVICE_MOUSE: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE, + address); + case DEVICE_TABLET: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET, + address); + case DEVICE_KEYBOARD_MOUSE_COMBO: + return l10n_util::GetStringFUTF16( + IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address); + default: + return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN, address); + } +} + +BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const { + // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm + 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) { + case 0x01: + case 0x02: + case 0x03: + // Cellular, cordless and smart phones. + return DEVICE_PHONE; + case 0x04: + case 0x05: + // Modems: wired or voice gateway and common ISDN access. + return DEVICE_MODEM; + } + break; + case 0x04: + // Audio major device class. + switch ((bluetooth_class_ & 0xfc) >> 2) { + case 0x08: + // Car audio. + return DEVICE_CAR_AUDIO; + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + case 0x010: + // Video devices. + return DEVICE_VIDEO; + default: + return DEVICE_AUDIO; + } + break; + case 0x05: + // Peripheral major device class. + switch ((bluetooth_class_ & 0xc0) >> 6) { + case 0x00: + // "Not a keyboard or pointing device." + switch ((bluetooth_class_ & 0x01e) >> 2) { + case 0x01: + // Joystick. + return DEVICE_JOYSTICK; + case 0x02: + // Gamepad. + return DEVICE_GAMEPAD; + default: + return DEVICE_PERIPHERAL; + } + break; + case 0x01: + // Keyboard. + return DEVICE_KEYBOARD; + case 0x02: + // Pointing device. + switch ((bluetooth_class_ & 0x01e) >> 2) { + case 0x05: + // Digitizer tablet. + return DEVICE_TABLET; + default: + // Mouse. + return DEVICE_MOUSE; + } + break; + case 0x03: + // Combo device. + return DEVICE_KEYBOARD_MOUSE_COMBO; + } + break; + } + + return DEVICE_UNKNOWN; +} + +bool BluetoothDevice::IsVisible() const { + return visible_; +} + +bool BluetoothDevice::IsBonded() const { + return bonded_; +} + +bool BluetoothDevice::IsConnected() const { + return connected_; +} + +} // namespace device diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h new file mode 100644 index 0000000..90e420b --- /dev/null +++ b/device/bluetooth/bluetooth_device.h @@ -0,0 +1,318 @@ +// Copyright (c) 2012 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_DEVICE_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_ + +#include +#include + +#include "base/callback.h" +#include "base/string16.h" +#include "base/memory/ref_counted.h" + +namespace device { + +class BluetoothServiceRecord; +class BluetoothSocket; + +struct BluetoothOutOfBandPairingData; + +// BluetoothDevice represents a remote Bluetooth device, both its properties and +// capabilities as discovered by a local adapter and actions that may be +// performed on the remove device such as pairing, connection and disconnection. +// +// 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. +// +// Since the lifecycle of BluetoothDevice instances is managed by +// BluetoothAdapter, that class rather than this provides observer methods +// for devices coming and going, as well as properties being updated. +class BluetoothDevice { + public: + // Possible values that may be returned by GetDeviceType(), representing + // different types of bluetooth device that we support or are aware of + // decoded from the bluetooth class information. + enum DeviceType { + DEVICE_UNKNOWN, + DEVICE_COMPUTER, + DEVICE_PHONE, + DEVICE_MODEM, + DEVICE_AUDIO, + DEVICE_CAR_AUDIO, + DEVICE_VIDEO, + DEVICE_PERIPHERAL, + DEVICE_JOYSTICK, + DEVICE_GAMEPAD, + DEVICE_KEYBOARD, + DEVICE_MOUSE, + DEVICE_TABLET, + DEVICE_KEYBOARD_MOUSE_COMBO + }; + + // Interface for observing changes from bluetooth devices. + class Observer { + public: + virtual ~Observer() {} + + // TODO(keybuk): add observers for pairing and connection. + }; + + // Interface for negotiating pairing of bluetooth devices. + class PairingDelegate { + public: + virtual ~PairingDelegate() {} + + // This method will be called when the Bluetooth daemon requires a + // PIN Code for authentication of the device |device|, the delegate should + // obtain the code from the user and call SetPinCode() on the device to + // provide it, or RejectPairing() or CancelPairing() to reject or cancel + // the request. + // + // PIN Codes are generally required for Bluetooth 2.0 and earlier devices + // for which there is no automatic pairing or special handling. + virtual void RequestPinCode(BluetoothDevice* device) = 0; + + // This method will be called when the Bluetooth daemon requires a + // Passkey for authentication of the device |device|, the delegate should + // obtain the passkey from the user (a numeric in the range 0-999999) and + // call SetPasskey() on the device to provide it, or RejectPairing() or + // CancelPairing() to reject or cancel the request. + // + // Passkeys are generally required for Bluetooth 2.1 and later devices + // which cannot provide input or display on their own, and don't accept + // passkey-less pairing. + virtual void RequestPasskey(BluetoothDevice* device) = 0; + + // This method will be called when the Bluetooth daemon requires that the + // user enter the PIN code |pincode| into the device |device| so that it + // may be authenticated. The DismissDisplayOrConfirm() method + // will be called to dismiss the display once pairing is complete or + // cancelled. + // + // This is used for Bluetooth 2.0 and earlier keyboard devices, the + // |pincode| will always be a six-digit numeric in the range 000000-999999 + // for compatibilty with later specifications. + virtual void DisplayPinCode(BluetoothDevice* device, + const std::string& pincode) = 0; + + // This method will be called when the Bluetooth daemon requires that the + // user enter the Passkey |passkey| into the device |device| so that it + // may be authenticated. The DismissDisplayOrConfirm() method will be + // called to dismiss the display once pairing is complete or cancelled. + // + // This is used for Bluetooth 2.1 and later devices that support input + // but not display, such as keyboards. The Passkey is a numeric in the + // range 0-999999 and should be always presented zero-padded to six + // digits. + virtual void DisplayPasskey(BluetoothDevice* device, + uint32 passkey) = 0; + + // This method will be called when the Bluetooth daemon requires that the + // user confirm that the Passkey |passkey| is displayed on the screen + // of the device |device| so that it may be authenticated. The delegate + // should display to the user and ask for confirmation, then call + // ConfirmPairing() on the device to confirm, RejectPairing() on the device + // to reject or CancelPairing() on the device to cancel authentication + // for any other reason. + // + // This is used for Bluetooth 2.1 and later devices that support display, + // such as other computers or phones. The Passkey is a numeric in the + // range 0-999999 and should be always present zero-padded to six + // digits. + virtual void ConfirmPasskey(BluetoothDevice* device, + uint32 passkey) = 0; + + // This method will be called when any previous DisplayPinCode(), + // DisplayPasskey() or ConfirmPasskey() request should be concluded + // and removed from the user. + virtual void DismissDisplayOrConfirm() = 0; + }; + + virtual ~BluetoothDevice(); + + // 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; + + // Returns the name of the device suitable for displaying, this may + // be a synthesied string containing the address and localized type name + // if the device has no obtained name. + virtual string16 GetName() const; + + // Returns the type of the device, limited to those we support or are + // aware of, by decoding the bluetooth class information. The returned + // values are unique, and do not overlap, so DEVICE_KEYBOARD is not also + // DEVICE_PERIPHERAL. + DeviceType GetDeviceType() const; + + // Indicates whether the device is paired to the adapter, whether or not + // that pairing is permanent or temporary. + 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 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; + + // Returns the services (as UUID strings) that this device provides. + typedef std::vector ServiceList; + virtual const 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. + typedef base::Callback ErrorCallback; + + // Returns the services (as BluetoothServiceRecord objects) that this device + // provides. + typedef ScopedVector ServiceRecordList; + typedef base::Callback ServiceRecordsCallback; + virtual void GetServiceRecords(const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback) = 0; + + // Indicates whether this device provides the given service. |uuid| should + // be in canonical form (see utils::CanonicalUuid). + virtual bool ProvidesServiceWithUUID(const std::string& uuid) const = 0; + + // The ProvidesServiceCallback is used by ProvidesServiceWithName to indicate + // whether or not a matching service was found. + typedef base::Callback ProvidesServiceCallback; + + // Indicates whether this device provides the given service. + virtual void ProvidesServiceWithName( + const std::string& name, + const ProvidesServiceCallback& callback) = 0; + + // Indicates whether the device is currently pairing and expecting a + // PIN Code to be returned. + virtual bool ExpectingPinCode() const = 0; + + // Indicates whether the device is currently pairing and expecting a + // Passkey to be returned. + virtual bool ExpectingPasskey() const = 0; + + // Indicates whether the device is currently pairing and expecting + // confirmation of a displayed passkey. + virtual bool ExpectingConfirmation() const = 0; + + // SocketCallback is used by ConnectToService to return a BluetoothSocket to + // the caller, or NULL if there was an error. The socket will remain open + // until the last reference to the returned BluetoothSocket is released. + typedef base::Callback)> + SocketCallback; + + // Initiates a connection to the device, pairing first if necessary. + // + // Method calls will be made on the supplied object |pairing_delegate| + // to indicate what display, and in response should make method calls + // back to the device object. Not all devices require user responses + // during pairing, so it is normal for |pairing_delegate| to receive no + // calls. To explicitly force a low-security connection without bonding, + // pass NULL, though this is ignored if the device is already paired. + // + // If the request fails, |error_callback| will be called; otherwise, + // |callback| is called when the request is complete. + virtual void Connect(PairingDelegate* pairing_delegate, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Sends the PIN code |pincode| to the remote device during pairing. + // + // PIN Codes are generally required for Bluetooth 2.0 and earlier devices + // for which there is no automatic pairing or special handling. + virtual void SetPinCode(const std::string& pincode) = 0; + + // Sends the Passkey |passkey| to the remote device during pairing. + // + // Passkeys are generally required for Bluetooth 2.1 and later devices + // which cannot provide input or display on their own, and don't accept + // passkey-less pairing, and are a numeric in the range 0-999999. + virtual void SetPasskey(uint32 passkey) = 0; + + // Confirms to the remote device during pairing that a passkey provided by + // the ConfirmPasskey() delegate call is displayed on both devices. + virtual void ConfirmPairing() = 0; + + // Rejects a pairing or connection request from a remote device. + virtual void RejectPairing() = 0; + + // Cancels a pairing or connection attempt to a remote device. + virtual void CancelPairing() = 0; + + // Disconnects the device, terminating the low-level ACL connection + // and any application connections using it. Link keys and other pairing + // information are not discarded, and the device object is not deleted. + // If the request fails, |error_callback| will be called; otherwise, + // |callback| is called when the request is complete. + virtual void Disconnect(const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Disconnects the device, terminating the low-level ACL connection + // and any application connections using it, and then discards link keys + // and other pairing information. The device object remainds valid until + // returing from the calling function, after which it should be assumed to + // have been deleted. If the request fails, |error_callback| will be called. + // There is no callback for success beause this object is often deleted + // before that callback would be called. + virtual void Forget(const ErrorCallback& error_callback) = 0; + + // Attempts to open a socket to a service matching |uuid| on this device. If + // the connection is successful, |callback| is called with a BluetoothSocket. + // Otherwise |callback| is called with NULL. The socket is closed as soon as + // all references to the BluetoothSocket are released. Note that the + // BluetoothSocket object can outlive both this BluetoothDevice and the + // BluetoothAdapter for this device. + virtual void ConnectToService(const std::string& service_uuid, + const SocketCallback& 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( + const BluetoothOutOfBandPairingData& data, + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + // Clears the Out Of Band pairing data for this device. Exactly one of + // |callback| or |error_callback| will be run. + virtual void ClearOutOfBandPairingData( + const base::Closure& callback, + const ErrorCallback& error_callback) = 0; + + 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_; + + // 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_; + + private: + // Returns a localized string containing the device's bluetooth address and + // a device type for display when |name_| is empty. + string16 GetAddressWithLocalizedDeviceTypeName() const; +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_H_ diff --git a/device/bluetooth/bluetooth_device_chromeos.cc b/device/bluetooth/bluetooth_device_chromeos.cc new file mode 100644 index 0000000..2a09cac --- /dev/null +++ b/device/bluetooth/bluetooth_device_chromeos.cc @@ -0,0 +1,690 @@ +// Copyright (c) 2012 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_device_chromeos.h" + +#include +#include +#include + +#include "base/bind.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "base/memory/scoped_vector.h" +#include "base/memory/weak_ptr.h" +#include "base/string16.h" +#include "base/string_util.h" +#include "base/values.h" +#include "chromeos/dbus/bluetooth_adapter_client.h" +#include "chromeos/dbus/bluetooth_agent_service_provider.h" +#include "chromeos/dbus/bluetooth_device_client.h" +#include "chromeos/dbus/bluetooth_input_client.h" +#include "chromeos/dbus/bluetooth_out_of_band_client.h" +#include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/introspectable_client.h" +#include "dbus/bus.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_adapter_chromeos.h" +#include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" +#include "device/bluetooth/bluetooth_service_record.h" +#include "device/bluetooth/bluetooth_socket_chromeos.h" +#include "device/bluetooth/bluetooth_utils.h" +#include "third_party/cros_system_api/dbus/service_constants.h" + +using device::BluetoothDevice; +using device::BluetoothOutOfBandPairingData; +using device::BluetoothServiceRecord; +using device::BluetoothSocket; + +namespace chromeos { + +BluetoothDeviceChromeOs::BluetoothDeviceChromeOs( + BluetoothAdapterChromeOs* adapter) + : BluetoothDevice(), + adapter_(adapter), + pairing_delegate_(NULL), + connecting_applications_counter_(0), + weak_ptr_factory_(this) { +} + +BluetoothDeviceChromeOs::~BluetoothDeviceChromeOs() { +} + +bool BluetoothDeviceChromeOs::IsPaired() const { + return !object_path_.value().empty(); +} + +const BluetoothDevice::ServiceList& +BluetoothDeviceChromeOs::GetServices() const { + return service_uuids_; +} + +void BluetoothDeviceChromeOs::GetServiceRecords( + const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> + DiscoverServices( + object_path_, + "", // empty pattern to browse all services + base::Bind(&BluetoothDeviceChromeOs::CollectServiceRecordsCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +bool BluetoothDeviceChromeOs::ProvidesServiceWithUUID( + const std::string& uuid) const { + const BluetoothDevice::ServiceList& services = GetServices(); + for (BluetoothDevice::ServiceList::const_iterator iter = services.begin(); + iter != services.end(); + ++iter) { + if (device::bluetooth_utils::CanonicalUuid(*iter) == uuid) + return true; + } + return false; +} + +void BluetoothDeviceChromeOs::ProvidesServiceWithName( + const std::string& name, + const ProvidesServiceCallback& callback) { + GetServiceRecords( + base::Bind(&BluetoothDeviceChromeOs::SearchServicesForNameCallback, + weak_ptr_factory_.GetWeakPtr(), + name, + callback), + base::Bind(&BluetoothDeviceChromeOs::SearchServicesForNameErrorCallback, + weak_ptr_factory_.GetWeakPtr(), + callback)); +} + +bool BluetoothDeviceChromeOs::ExpectingPinCode() const { + return !pincode_callback_.is_null(); +} + +bool BluetoothDeviceChromeOs::ExpectingPasskey() const { + return !passkey_callback_.is_null(); +} + +bool BluetoothDeviceChromeOs::ExpectingConfirmation() const { + return !confirmation_callback_.is_null(); +} + +void BluetoothDeviceChromeOs::Connect(PairingDelegate* pairing_delegate, + const base::Closure& callback, + const ErrorCallback& error_callback) { + if (IsPaired() || IsBonded() || IsConnected()) { + // Connection to already paired or connected device. + ConnectApplications(callback, error_callback); + + } else if (!pairing_delegate) { + // No pairing delegate supplied, initiate low-security connection only. + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + CreateDevice(adapter_->object_path_, + address_, + base::Bind(&BluetoothDeviceChromeOs::ConnectCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback), + base::Bind(&BluetoothDeviceChromeOs::ConnectErrorCallback, + weak_ptr_factory_.GetWeakPtr(), + error_callback)); + } else { + // Initiate high-security connection with pairing. + DCHECK(!pairing_delegate_); + pairing_delegate_ = pairing_delegate; + + // The agent path is relatively meaningless, we use the device address + // to generate it as we only support one pairing attempt at a time for + // a given bluetooth device. + DCHECK(agent_.get() == NULL); + + std::string agent_path_basename; + ReplaceChars(address_, ":", "_", &agent_path_basename); + dbus::ObjectPath agent_path("/org/chromium/bluetooth_agent/" + + agent_path_basename); + + dbus::Bus* system_bus = DBusThreadManager::Get()->GetSystemBus(); + if (system_bus) { + agent_.reset(BluetoothAgentServiceProvider::Create(system_bus, + agent_path, + this)); + } else { + agent_.reset(NULL); + } + + DVLOG(1) << "Pairing: " << address_; + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + CreatePairedDevice( + adapter_->object_path_, + address_, + agent_path, + bluetooth_agent::kDisplayYesNoCapability, + base::Bind(&BluetoothDeviceChromeOs::ConnectCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback), + base::Bind(&BluetoothDeviceChromeOs::ConnectErrorCallback, + weak_ptr_factory_.GetWeakPtr(), + error_callback)); + } +} + +void BluetoothDeviceChromeOs::SetPinCode(const std::string& pincode) { + if (!agent_.get() || pincode_callback_.is_null()) + return; + + pincode_callback_.Run(SUCCESS, pincode); + pincode_callback_.Reset(); +} + +void BluetoothDeviceChromeOs::SetPasskey(uint32 passkey) { + if (!agent_.get() || passkey_callback_.is_null()) + return; + + passkey_callback_.Run(SUCCESS, passkey); + passkey_callback_.Reset(); +} + +void BluetoothDeviceChromeOs::ConfirmPairing() { + if (!agent_.get() || confirmation_callback_.is_null()) + return; + + confirmation_callback_.Run(SUCCESS); + confirmation_callback_.Reset(); +} + +void BluetoothDeviceChromeOs::RejectPairing() { + if (!agent_.get()) + return; + + if (!pincode_callback_.is_null()) { + pincode_callback_.Run(REJECTED, ""); + pincode_callback_.Reset(); + } + if (!passkey_callback_.is_null()) { + passkey_callback_.Run(REJECTED, 0); + passkey_callback_.Reset(); + } + if (!confirmation_callback_.is_null()) { + confirmation_callback_.Run(REJECTED); + confirmation_callback_.Reset(); + } +} + +void BluetoothDeviceChromeOs::CancelPairing() { + if (!agent_.get()) + return; + + if (!pincode_callback_.is_null()) { + pincode_callback_.Run(CANCELLED, ""); + pincode_callback_.Reset(); + } + if (!passkey_callback_.is_null()) { + passkey_callback_.Run(CANCELLED, 0); + passkey_callback_.Reset(); + } + if (!confirmation_callback_.is_null()) { + confirmation_callback_.Run(CANCELLED); + confirmation_callback_.Reset(); + } +} + +void BluetoothDeviceChromeOs::Disconnect(const base::Closure& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> + Disconnect(object_path_, + base::Bind(&BluetoothDeviceChromeOs::DisconnectCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); + +} + +void BluetoothDeviceChromeOs::Forget(const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothAdapterClient()-> + RemoveDevice(adapter_->object_path_, + object_path_, + base::Bind(&BluetoothDeviceChromeOs::ForgetCallback, + weak_ptr_factory_.GetWeakPtr(), + error_callback)); +} + +void BluetoothDeviceChromeOs::ConnectToService(const std::string& service_uuid, + const SocketCallback& callback) { + GetServiceRecords( + base::Bind(&BluetoothDeviceChromeOs::GetServiceRecordsForConnectCallback, + weak_ptr_factory_.GetWeakPtr(), + service_uuid, + callback), + base::Bind( + &BluetoothDeviceChromeOs::GetServiceRecordsForConnectErrorCallback, + weak_ptr_factory_.GetWeakPtr(), + callback)); +} + +void BluetoothDeviceChromeOs::SetOutOfBandPairingData( + const BluetoothOutOfBandPairingData& data, + const base::Closure& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> + AddRemoteData( + object_path_, + address(), + data, + base::Bind(&BluetoothDeviceChromeOs::OnRemoteDataCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +void BluetoothDeviceChromeOs::ClearOutOfBandPairingData( + const base::Closure& callback, + const ErrorCallback& error_callback) { + DBusThreadManager::Get()->GetBluetoothOutOfBandClient()-> + RemoveRemoteData( + object_path_, + address(), + base::Bind(&BluetoothDeviceChromeOs::OnRemoteDataCallback, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +void BluetoothDeviceChromeOs::SetObjectPath( + const dbus::ObjectPath& object_path) { + DCHECK(object_path_ == dbus::ObjectPath("")); + object_path_ = object_path; +} + +void BluetoothDeviceChromeOs::RemoveObjectPath() { + DCHECK(object_path_ != dbus::ObjectPath("")); + object_path_ = dbus::ObjectPath(""); +} + +void BluetoothDeviceChromeOs::Update( + const BluetoothDeviceClient::Properties* properties, + bool update_state) { + std::string address = properties->address.value(); + std::string name = properties->name.value(); + uint32 bluetooth_class = properties->bluetooth_class.value(); + const std::vector& uuids = properties->uuids.value(); + + if (!address.empty()) + address_ = address; + if (!name.empty()) + name_ = name; + if (bluetooth_class) + bluetooth_class_ = bluetooth_class; + if (!uuids.empty()) { + service_uuids_.clear(); + service_uuids_.assign(uuids.begin(), uuids.end()); + } + + if (update_state) { + // 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(); + connected_ = properties->connected.value(); + } +} + +void BluetoothDeviceChromeOs::ConnectCallback( + const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path) { + DVLOG(1) << "Connection successful: " << device_path.value(); + if (object_path_.value().empty()) { + object_path_ = device_path; + } else { + LOG_IF(WARNING, object_path_ != device_path) + << "Conflicting device paths for objects, result gave: " + << device_path.value() << " but signal gave: " + << object_path_.value(); + } + + // Mark the device trusted so it can connect to us automatically, and + // we can connect after rebooting. This information is part of the + // pairing information of the device, and is unique to the combination + // of our bluetooth address and the device's bluetooth address. A + // different host needs a new pairing, so it's not useful to sync. + DBusThreadManager::Get()->GetBluetoothDeviceClient()-> + GetProperties(object_path_)->trusted.Set( + true, + base::Bind(&BluetoothDeviceChromeOs::OnSetTrusted, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); + + // Connect application-layer protocols. + ConnectApplications(callback, error_callback); +} + +void BluetoothDeviceChromeOs::ConnectErrorCallback( + const ErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message) { + LOG(WARNING) << "Connection failed: " << address_ + << ": " << error_name << ": " << error_message; + error_callback.Run(); +} + +void BluetoothDeviceChromeOs::CollectServiceRecordsCallback( + const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path, + const BluetoothDeviceClient::ServiceMap& service_map, + bool success) { + if (!success) { + error_callback.Run(); + return; + } + + ScopedVector records; + for (BluetoothDeviceClient::ServiceMap::const_iterator i = + service_map.begin(); i != service_map.end(); ++i) { + records.push_back( + new BluetoothServiceRecord(address(), i->second)); + } + callback.Run(records); +} + +void BluetoothDeviceChromeOs::OnSetTrusted(const base::Closure& callback, + const ErrorCallback& error_callback, + bool success) { + if (success) { + callback.Run(); + } else { + LOG(WARNING) << "Failed to set device as trusted: " << address_; + error_callback.Run(); + } +} + +void BluetoothDeviceChromeOs::ConnectApplications( + const base::Closure& callback, + const ErrorCallback& error_callback) { + // Introspect the device object to determine supported applications. + DBusThreadManager::Get()->GetIntrospectableClient()-> + Introspect(bluetooth_device::kBluetoothDeviceServiceName, + object_path_, + base::Bind(&BluetoothDeviceChromeOs::OnIntrospect, + weak_ptr_factory_.GetWeakPtr(), + callback, + error_callback)); +} + +void BluetoothDeviceChromeOs::OnIntrospect(const base::Closure& callback, + const ErrorCallback& error_callback, + const std::string& service_name, + const dbus::ObjectPath& device_path, + const std::string& xml_data, + bool success) { + if (!success) { + LOG(WARNING) << "Failed to determine supported applications: " << address_; + error_callback.Run(); + return; + } + + // The introspection data for the device object may list one or more + // additional D-Bus interfaces that BlueZ supports for this particular + // device. Send appropraite Connect calls for each of those interfaces + // to connect all of the application protocols for this device. + std::vector interfaces = + IntrospectableClient::GetInterfacesFromIntrospectResult(xml_data); + + DCHECK_EQ(0, connecting_applications_counter_); + connecting_applications_counter_ = 0; + for (std::vector::iterator iter = interfaces.begin(); + iter != interfaces.end(); ++iter) { + if (*iter == bluetooth_input::kBluetoothInputInterface) { + connecting_applications_counter_++; + // Supports Input interface. + DBusThreadManager::Get()->GetBluetoothInputClient()-> + Connect(object_path_, + base::Bind(&BluetoothDeviceChromeOs::OnConnect, + weak_ptr_factory_.GetWeakPtr(), + callback, + *iter), + base::Bind(&BluetoothDeviceChromeOs::OnConnectError, + weak_ptr_factory_.GetWeakPtr(), + error_callback, *iter)); + } + } + + // If OnConnect has been called for every call to Connect above, then this + // will decrement the counter to -1. In that case, call the callback + // directly as it has not been called by any of the OnConnect callbacks. + // This is safe because OnIntrospect and OnConnect run on the same thread. + connecting_applications_counter_--; + if (connecting_applications_counter_ == -1) + callback.Run(); +} + +void BluetoothDeviceChromeOs::OnConnect(const base::Closure& callback, + const std::string& interface_name, + const dbus::ObjectPath& device_path) { + DVLOG(1) << "Application connection successful: " << device_path.value() + << ": " << interface_name; + + connecting_applications_counter_--; + // |callback| should only be called once, meaning it cannot be called before + // all requests have been started. The extra decrement after all requests + // have been started, and the check for -1 instead of 0 below, insure only a + // single call to |callback| will occur (provided OnConnect and OnIntrospect + // run on the same thread, which is true). + if (connecting_applications_counter_ == -1) { + connecting_applications_counter_ = 0; + callback.Run(); + } +} + +void BluetoothDeviceChromeOs::OnConnectError( + const ErrorCallback& error_callback, + const std::string& interface_name, + const dbus::ObjectPath& device_path, + const std::string& error_name, + const std::string& error_message) { + LOG(WARNING) << "Connection failed: " << address_ << ": " << interface_name + << ": " << error_name << ": " << error_message; + error_callback.Run(); +} + +void BluetoothDeviceChromeOs::DisconnectCallback( + const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path, + bool success) { + DCHECK(device_path == object_path_); + if (success) { + DVLOG(1) << "Disconnection successful: " << address_; + callback.Run(); + } else { + LOG(WARNING) << "Disconnection failed: " << address_; + error_callback.Run(); + } +} + +void BluetoothDeviceChromeOs::ForgetCallback( + const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, + bool success) { + // It's quite normal that this path never gets called on success; we use a + // weak pointer, and bluetoothd might send the DeviceRemoved signal before + // the method reply, in which case this object is deleted and the + // callback never takes place. Therefore don't do anything here for the + // success case. + if (!success) { + LOG(WARNING) << "Forget failed: " << address_; + error_callback.Run(); + } +} + +void BluetoothDeviceChromeOs::SearchServicesForNameErrorCallback( + const ProvidesServiceCallback& callback) { + callback.Run(false); +} + +void BluetoothDeviceChromeOs::SearchServicesForNameCallback( + const std::string& name, + const ProvidesServiceCallback& callback, + const ServiceRecordList& list) { + for (ServiceRecordList::const_iterator i = list.begin(); + i != list.end(); ++i) { + if ((*i)->name() == name) { + callback.Run(true); + return; + } + } + callback.Run(false); +} + +void BluetoothDeviceChromeOs::GetServiceRecordsForConnectErrorCallback( + const SocketCallback& callback) { + callback.Run(NULL); +} + +void BluetoothDeviceChromeOs::GetServiceRecordsForConnectCallback( + const std::string& service_uuid, + const SocketCallback& callback, + const ServiceRecordList& list) { + for (ServiceRecordList::const_iterator i = list.begin(); + i != list.end(); ++i) { + if ((*i)->uuid() == service_uuid) { + // If multiple service records are found, use the first one that works. + scoped_refptr socket( + BluetoothSocketChromeOs::CreateBluetoothSocket(**i)); + if (socket.get() != NULL) { + callback.Run(socket); + return; + } + } + } + callback.Run(NULL); +} + +void BluetoothDeviceChromeOs::OnRemoteDataCallback( + const base::Closure& callback, + const ErrorCallback& error_callback, + bool success) { + if (success) + callback.Run(); + else + error_callback.Run(); +} + +void BluetoothDeviceChromeOs::DisconnectRequested( + const dbus::ObjectPath& object_path) { + DCHECK(object_path == object_path_); +} + +void BluetoothDeviceChromeOs::Release() { + DCHECK(agent_.get()); + DVLOG(1) << "Release: " << address_; + + DCHECK(pairing_delegate_); + pairing_delegate_->DismissDisplayOrConfirm(); + pairing_delegate_ = NULL; + + pincode_callback_.Reset(); + passkey_callback_.Reset(); + confirmation_callback_.Reset(); + + agent_.reset(); +} + +void BluetoothDeviceChromeOs::RequestPinCode( + const dbus::ObjectPath& device_path, + const PinCodeCallback& callback) { + DCHECK(agent_.get()); + DVLOG(1) << "RequestPinCode: " << device_path.value(); + + DCHECK(pairing_delegate_); + DCHECK(pincode_callback_.is_null()); + pincode_callback_ = callback; + pairing_delegate_->RequestPinCode(this); +} + +void BluetoothDeviceChromeOs::RequestPasskey( + const dbus::ObjectPath& device_path, + const PasskeyCallback& callback) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + DVLOG(1) << "RequestPasskey: " << device_path.value(); + + DCHECK(pairing_delegate_); + DCHECK(passkey_callback_.is_null()); + passkey_callback_ = callback; + pairing_delegate_->RequestPasskey(this); +} + +void BluetoothDeviceChromeOs::DisplayPinCode( + const dbus::ObjectPath& device_path, + const std::string& pincode) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + DVLOG(1) << "DisplayPinCode: " << device_path.value() << " " << pincode; + + DCHECK(pairing_delegate_); + pairing_delegate_->DisplayPinCode(this, pincode); +} + +void BluetoothDeviceChromeOs::DisplayPasskey( + const dbus::ObjectPath& device_path, + uint32 passkey) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + DVLOG(1) << "DisplayPasskey: " << device_path.value() << " " << passkey; + + DCHECK(pairing_delegate_); + pairing_delegate_->DisplayPasskey(this, passkey); +} + +void BluetoothDeviceChromeOs::RequestConfirmation( + const dbus::ObjectPath& device_path, + uint32 passkey, + const ConfirmationCallback& callback) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + DVLOG(1) << "RequestConfirmation: " << device_path.value() << " " << passkey; + + DCHECK(pairing_delegate_); + DCHECK(confirmation_callback_.is_null()); + confirmation_callback_ = callback; + pairing_delegate_->ConfirmPasskey(this, passkey); +} + +void BluetoothDeviceChromeOs::Authorize(const dbus::ObjectPath& device_path, + const std::string& uuid, + const ConfirmationCallback& callback) { + DCHECK(agent_.get()); + DCHECK(device_path == object_path_); + LOG(WARNING) << "Rejected authorization for service: " << uuid + << " requested from device: " << device_path.value(); + callback.Run(REJECTED); +} + +void BluetoothDeviceChromeOs::ConfirmModeChange( + Mode mode, + const ConfirmationCallback& callback) { + DCHECK(agent_.get()); + LOG(WARNING) << "Rejected adapter-level mode change: " << mode + << " made on agent for device: " << address_; + callback.Run(REJECTED); +} + +void BluetoothDeviceChromeOs::Cancel() { + DCHECK(agent_.get()); + DVLOG(1) << "Cancel: " << address_; + + DCHECK(pairing_delegate_); + pairing_delegate_->DismissDisplayOrConfirm(); +} + + +// static +BluetoothDeviceChromeOs* BluetoothDeviceChromeOs::Create( + BluetoothAdapterChromeOs* adapter) { + return new BluetoothDeviceChromeOs(adapter); +} + +} // namespace chromeos diff --git a/device/bluetooth/bluetooth_device_chromeos.h b/device/bluetooth/bluetooth_device_chromeos.h new file mode 100644 index 0000000..4b2d3b5 --- /dev/null +++ b/device/bluetooth/bluetooth_device_chromeos.h @@ -0,0 +1,375 @@ +// Copyright (c) 2012 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_DEVICE_CHROMEOS_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ + +#include +#include + +#include "base/basictypes.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "base/memory/weak_ptr.h" +#include "base/string16.h" +#include "chromeos/dbus/bluetooth_agent_service_provider.h" +#include "chromeos/dbus/bluetooth_device_client.h" +#include "dbus/object_path.h" +#include "device/bluetooth/bluetooth_device.h" + +namespace device { + +class BluetoothServiceRecord; +class MockBluetoothDevice; +struct BluetoothOutOfBandPairingData; + +} // namespace device + +namespace chromeos { + +class BluetoothAdapterChromeOs; + +// The BluetoothDeviceChromeOs class is an implementation of BluetoothDevice +// for Chrome OS platform. +class BluetoothDeviceChromeOs + : public device::BluetoothDevice, + public BluetoothDeviceClient::Observer, + public BluetoothAgentServiceProvider::Delegate { + public: + virtual ~BluetoothDeviceChromeOs(); + + // BluetoothDevice override + virtual bool IsPaired() const OVERRIDE; + virtual const ServiceList& GetServices() const OVERRIDE; + virtual void GetServiceRecords( + const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual bool ProvidesServiceWithUUID(const std::string& uuid) const OVERRIDE; + virtual void ProvidesServiceWithName( + const std::string& name, + const ProvidesServiceCallback& callback) OVERRIDE; + virtual bool ExpectingPinCode() const OVERRIDE; + virtual bool ExpectingPasskey() const OVERRIDE; + virtual bool ExpectingConfirmation() const OVERRIDE; + virtual void Connect( + device::BluetoothDevice::PairingDelegate* pairing_delegate, + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual void SetPinCode(const std::string& pincode) OVERRIDE; + virtual void SetPasskey(uint32 passkey) OVERRIDE; + virtual void ConfirmPairing() OVERRIDE; + virtual void RejectPairing() OVERRIDE; + virtual void CancelPairing() OVERRIDE; + virtual void Disconnect( + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual void Forget(const ErrorCallback& error_callback) OVERRIDE; + virtual void ConnectToService( + const std::string& service_uuid, + const SocketCallback& callback) OVERRIDE; + virtual void SetOutOfBandPairingData( + const device::BluetoothOutOfBandPairingData& data, + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + virtual void ClearOutOfBandPairingData( + const base::Closure& callback, + const ErrorCallback& error_callback) OVERRIDE; + + private: + friend class BluetoothAdapterChromeOs; + friend class device::MockBluetoothDevice; + + explicit BluetoothDeviceChromeOs(BluetoothAdapterChromeOs* adapter); + + // Sets the dbus object path for the device to |object_path|, indicating + // that the device has gone from being discovered to paired or bonded. + 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. + void RemoveObjectPath(); + + // Sets whether the device is visible to the owning adapter to |visible|. + void SetVisible(bool visible) { visible_ = visible; } + + // Updates device information from the properties in |properties|, device + // state properties such as |paired_| and |connected_| are ignored unless + // |update_state| is true. + void Update(const BluetoothDeviceClient::Properties* properties, + bool update_state); + + // Called by BluetoothAdapterClient when a call to CreateDevice() or + // CreatePairedDevice() succeeds, provides the new object path for the remote + // device in |device_path|. |callback| and |error_callback| are the callbacks + // provided to Connect(). + void ConnectCallback(const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path); + + // Called by BluetoothAdapterClient when a call to CreateDevice() or + // CreatePairedDevice() fails with the error named |error_name| and + // optional message |error_message|, |error_callback| is the callback + // provided to Connect(). + void ConnectErrorCallback(const ErrorCallback& error_callback, + const std::string& error_name, + const std::string& error_message); + + // Called by BluetoothAdapterClient when a call to DiscoverServices() + // completes. |callback| and |error_callback| are the callbacks provided to + // GetServiceRecords. + void CollectServiceRecordsCallback( + const ServiceRecordsCallback& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path, + const BluetoothDeviceClient::ServiceMap& service_map, + bool success); + + // Called by BluetoothProperty when the call to Set() for the Trusted + // property completes. |success| indicates whether or not the request + // succeeded, |callback| and |error_callback| are the callbacks provided to + // Connect(). + void OnSetTrusted(const base::Closure& callback, + const ErrorCallback& error_callback, + bool success); + + // Connect application-level protocols of the device to the system, called + // on a successful connection or to reconnect to a device that is already + // paired or previously connected. |error_callback| is called on failure. + // Otherwise, |callback| is called when the request is complete. + void ConnectApplications(const base::Closure& callback, + const ErrorCallback& error_callback); + + // Called by IntrospectableClient when a call to Introspect() completes. + // |success| indicates whether or not the request succeeded, |callback| and + // |error_callback| are the callbacks provided to ConnectApplications(), + // |service_name| and |device_path| specify the remote object being + // introspected and |xml_data| contains the XML-formatted protocol data. + void OnIntrospect(const base::Closure& callback, + const ErrorCallback& error_callback, + const std::string& service_name, + const dbus::ObjectPath& device_path, + const std::string& xml_data, bool success); + + // Called by BluetoothInputClient when the call to Connect() succeeds. + // |error_callback| is the callback provided to ConnectApplications(), + // |interface_name| specifies the interface being connected and + // |device_path| the remote object path. + void OnConnect(const base::Closure& callback, + const std::string& interface_name, + const dbus::ObjectPath& device_path); + + // Called by BluetoothInputClient when the call to Connect() fails. + // |error_callback| is the callback provided to ConnectApplications(), + // |interface_name| specifies the interface being connected, + // |device_path| the remote object path, + // |error_name| the error name and |error_message| the optional message. + void OnConnectError(const ErrorCallback& error_callback, + const std::string& interface_name, + const dbus::ObjectPath& device_path, + const std::string& error_name, + const std::string& error_message); + + // Called by BluetoothDeviceClient when a call to Disconnect() completes, + // |success| indicates whether or not the request succeeded, |callback| and + // |error_callback| are the callbacks provided to Disconnect() and + // |device_path| is the device disconnected. + void DisconnectCallback(const base::Closure& callback, + const ErrorCallback& error_callback, + const dbus::ObjectPath& device_path, bool success); + + // Called by BluetoothAdapterClient when a call to RemoveDevice() + // completes, |success| indicates whether or not the request succeeded, + // |error_callback| is the callback provided to Forget() and |adapter_path| is + // the d-bus object path of the adapter that performed the removal. + void ForgetCallback(const ErrorCallback& error_callback, + const dbus::ObjectPath& adapter_path, bool success); + + // Called if the call to GetServiceRecords from ProvidesServiceWithName fails. + void SearchServicesForNameErrorCallback( + const ProvidesServiceCallback& callback); + + // Called by GetServiceRecords with the list of BluetoothServiceRecords to + // search for |name|. |callback| is the callback from + // ProvidesServiceWithName. + void SearchServicesForNameCallback( + const std::string& name, + const ProvidesServiceCallback& callback, + const ServiceRecordList& list); + + // Called if the call to GetServiceRecords from Connect fails. + void GetServiceRecordsForConnectErrorCallback( + const SocketCallback& callback); + + // Called by GetServiceRecords with the list of BluetoothServiceRecords. + // Connections are attempted to each service in the list matching + // |service_uuid|, and the socket from the first successful connection is + // passed to |callback|. + void GetServiceRecordsForConnectCallback( + const std::string& service_uuid, + const SocketCallback& callback, + const ServiceRecordList& list); + + // Called by BlueoothDeviceClient in response to the AddRemoteData and + // RemoveRemoteData method calls. + void OnRemoteDataCallback(const base::Closure& callback, + const ErrorCallback& error_callback, + bool success); + + // BluetoothDeviceClient::Observer override. + // + // Called when the device with object path |object_path| is about + // to be disconnected, giving a chance for application layers to + // shut down cleanly. + virtual void DisconnectRequested( + const dbus::ObjectPath& object_path) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the agent is unregistered from the + // Bluetooth daemon, generally at the end of a pairing request. It may be + // used to perform cleanup tasks. + virtual void Release() OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires a + // PIN Code for authentication of the device with object path |device_path|, + // the agent should obtain the code from the user and call |callback| + // to provide it, or indicate rejection or cancellation of the request. + // + // PIN Codes are generally required for Bluetooth 2.0 and earlier devices + // for which there is no automatic pairing or special handling. + virtual void RequestPinCode(const dbus::ObjectPath& device_path, + const PinCodeCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires a + // Passkey for authentication of the device with object path |device_path|, + // the agent should obtain the passkey from the user (a numeric in the + // range 0-999999) and call |callback| to provide it, or indicate + // rejection or cancellation of the request. + // + // Passkeys are generally required for Bluetooth 2.1 and later devices + // which cannot provide input or display on their own, and don't accept + // passkey-less pairing. + virtual void RequestPasskey(const dbus::ObjectPath& device_path, + const PasskeyCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user enter the PIN code |pincode| into the device with object path + // |device_path| so that it may be authenticated. The Cancel() method + // will be called to dismiss the display once pairing is complete or + // cancelled. + // + // This is used for Bluetooth 2.0 and earlier keyboard devices, the + // |pincode| will always be a six-digit numeric in the range 000000-999999 + // for compatibilty with later specifications. + virtual void DisplayPinCode(const dbus::ObjectPath& device_path, + const std::string& pincode) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user enter the Passkey |passkey| into the device with object path + // |device_path| so that it may be authenticated. The Cancel() method + // will be called to dismiss the display once pairing is complete or + // cancelled. + // + // This is used for Bluetooth 2.1 and later devices that support input + // but not display, such as keyboards. The Passkey is a numeric in the + // range 0-999999 and should be always presented zero-padded to six + // digits. + virtual void DisplayPasskey(const dbus::ObjectPath& device_path, + uint32 passkey) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user confirm that the Passkey |passkey| is displayed on the screen + // of the device with object path |object_path| so that it may be + // authentication. The agent should display to the user and ask for + // confirmation, then call |callback| to provide their response (success, + // rejected or cancelled). + // + // This is used for Bluetooth 2.1 and later devices that support display, + // such as other computers or phones. The Passkey is a numeric in the + // range 0-999999 and should be always present zero-padded to six + // digits. + virtual void RequestConfirmation( + const dbus::ObjectPath& device_path, + uint32 passkey, + const ConfirmationCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user confirm that the device with object path |object_path| is + // authorized to connect to the service with UUID |uuid|. The agent should + // confirm with the user and call |callback| to provide their response + // (success, rejected or cancelled). + virtual void Authorize(const dbus::ObjectPath& device_path, + const std::string& uuid, + const ConfirmationCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called when the Bluetooth daemon requires that the + // user confirm that the device adapter may switch to mode |mode|. The + // agent should confirm with the user and call |callback| to provide + // their response (success, rejected or cancelled). + virtual void ConfirmModeChange(Mode mode, + const ConfirmationCallback& callback) OVERRIDE; + + // BluetoothAgentServiceProvider::Delegate override. + // + // This method will be called by the Bluetooth daemon to indicate that + // the request failed before a reply was returned from the device. + virtual void Cancel() OVERRIDE; + + // Creates a new BluetoothDeviceChromeOs object bound to the adapter + // |adapter|. + static BluetoothDeviceChromeOs* Create(BluetoothAdapterChromeOs* adapter); + + // The adapter that owns this device instance. + BluetoothAdapterChromeOs* adapter_; + + // The dbus object path of the device, will be empty if the device has only + // been discovered and not yet paired with. + dbus::ObjectPath object_path_; + + // The services (identified by UUIDs) that this device provides. + std::vector 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 + // Passkeys. Generally it is the object that owns this one. + device::BluetoothDevice::PairingDelegate* pairing_delegate_; + + // During pairing this is set to an instance of a D-Bus agent object + // intialized with our own class as its delegate. + scoped_ptr agent_; + + // During pairing these callbacks are set to those provided by method calls + // made on us by |agent_| and are called by our own method calls such as + // SetPinCode() and SetPasskey(). + PinCodeCallback pincode_callback_; + PasskeyCallback passkey_callback_; + ConfirmationCallback confirmation_callback_; + + // Used to keep track of pending application connection requests. + int connecting_applications_counter_; + + // Note: This should remain the last member so it'll be destroyed and + // invalidate its weak pointers before any other members are destroyed. + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceChromeOs); +}; + +} // namespace chromeos + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_CHROMEOS_H_ diff --git a/device/bluetooth/bluetooth_out_of_band_pairing_data.h b/device/bluetooth/bluetooth_out_of_band_pairing_data.h new file mode 100644 index 0000000..1b45bb0 --- /dev/null +++ b/device/bluetooth/bluetooth_out_of_band_pairing_data.h @@ -0,0 +1,27 @@ +// Copyright (c) 2012 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_OUT_OF_BAND_PAIRING_DATA_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_OUT_OF_BAND_PAIRING_DATA_H_ + +#include "base/basictypes.h" + +namespace device { + +const size_t kBluetoothOutOfBandPairingDataSize = 16; + +// A simple structure representing the data required to perform Out Of Band +// Pairing. See +// http://mclean-linsky.net/joel/cv/Simple%20Pairing_WP_V10r00.pdf +struct BluetoothOutOfBandPairingData { + // Simple Pairing Hash C. + uint8 hash[kBluetoothOutOfBandPairingDataSize]; + + // Simple Pairing Randomizer R. + uint8 randomizer[kBluetoothOutOfBandPairingDataSize]; +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_OUT_OF_BAND_PAIRING_DATA_H_ diff --git a/device/bluetooth/bluetooth_service_record.cc b/device/bluetooth/bluetooth_service_record.cc new file mode 100644 index 0000000..0ea18d7 --- /dev/null +++ b/device/bluetooth/bluetooth_service_record.cc @@ -0,0 +1,122 @@ +// Copyright (c) 2012 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_service_record.h" + +#include +#include + +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "device/bluetooth/bluetooth_utils.h" +#include "third_party/libxml/chromium/libxml_utils.h" + +namespace { + +static const char* kAttributeNode = "attribute"; +static const char* kIdAttribute = "id"; +static const char* kProtocolDescriptorListId = "0x0004"; +static const char* kRfcommUuid = "0x0003"; +static const char* kSdpNameId = "0x0100"; +static const char* kSequenceNode = "sequence"; +static const char* kTextNode = "text"; +static const char* kUint8Node = "uint8"; +static const char* kUuidId = "0x0001"; +static const char* kUuidNode = "uuid"; +static const char* kValueAttribute = "value"; + +bool AdvanceToTag(XmlReader* reader, const char* node_type) { + do { + if (!reader->Read()) + return false; + } while (reader->NodeName() != node_type); + return true; +} + +bool ExtractTextValue(XmlReader* reader, std::string* value_out) { + if (AdvanceToTag(reader, kTextNode)) { + reader->NodeAttribute(kValueAttribute, value_out); + return true; + } + return false; +} + +} // namespace + +namespace device { + +BluetoothServiceRecord::BluetoothServiceRecord( + const std::string& address, + const std::string& xml_data) + : address_(address), + supports_rfcomm_(false) { + + XmlReader reader; + if (!reader.Load(xml_data)) + return; + + while (AdvanceToTag(&reader, kAttributeNode)) { + std::string id; + if (reader.NodeAttribute(kIdAttribute, &id)) { + if (id == kSdpNameId) { + ExtractTextValue(&reader, &name_); + } else if (id == kProtocolDescriptorListId) { + if (AdvanceToTag(&reader, kSequenceNode)) { + ExtractChannels(&reader); + } + } else if (id == kUuidId) { + if (AdvanceToTag(&reader, kSequenceNode)) { + ExtractUuid(&reader); + } + } + } + // We don't care about anything else here, so find the closing tag + AdvanceToTag(&reader, kAttributeNode); + } +} + +void BluetoothServiceRecord::ExtractChannels(XmlReader* reader) { + const int start_depth = reader->Depth(); + do { + if (reader->NodeName() == kSequenceNode) { + if (AdvanceToTag(reader, kUuidNode)) { + std::string type; + if (reader->NodeAttribute(kValueAttribute, &type) && + type == kRfcommUuid) { + if (AdvanceToTag(reader, kUint8Node)) { + std::string channel_string; + if (reader->NodeAttribute(kValueAttribute, &channel_string)) { + std::vector channel_bytes; + if (base::HexStringToBytes(channel_string.substr(2), + &channel_bytes)) { + if (channel_bytes.size() == 1) { + rfcomm_channel_ = channel_bytes[0]; + supports_rfcomm_ = true; + } + } + } + } + } + } + } + } while (AdvanceToTag(reader, kSequenceNode) && + reader->Depth() != start_depth); +} + +void BluetoothServiceRecord::ExtractUuid(XmlReader* reader) { + const int start_depth = reader->Depth(); + do { + if (reader->NodeName() == kSequenceNode) { + if (AdvanceToTag(reader, kUuidNode)) { + if (!reader->NodeAttribute(kValueAttribute, &uuid_)) + uuid_.clear(); + } + } + } while (AdvanceToTag(reader, kSequenceNode) && + reader->Depth() != start_depth); + + uuid_ = device::bluetooth_utils::CanonicalUuid(uuid_); +} + +} // namespace device diff --git a/device/bluetooth/bluetooth_service_record.h b/device/bluetooth/bluetooth_service_record.h new file mode 100644 index 0000000..e04d73a --- /dev/null +++ b/device/bluetooth/bluetooth_service_record.h @@ -0,0 +1,59 @@ +// Copyright (c) 2012 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_SERVICE_RECORD_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_SERVICE_RECORD_H_ + +#include + +#include "base/basictypes.h" + +class XmlReader; + +namespace device { + +// BluetoothServiceRecord represents an SDP service record. +// +// This implementation is currently incomplete: it only supports those fields +// that have been necessary so far. +class BluetoothServiceRecord { + public: + BluetoothServiceRecord( + const std::string& address, + const std::string& xml_data); + + // The human-readable name of this service. + const std::string& name() const { return name_; } + + // The address of the BluetoothDevice providing this service. + const std::string& address() const { return address_; } + + // The UUID of the service. This field may be empty if no UUID was + // specified in the service record. + const std::string& uuid() const { return uuid_; } + + // Indicates if this service supports RFCOMM communication. + bool SupportsRfcomm() const { return supports_rfcomm_; } + + // The RFCOMM channel to use, if this service supports RFCOMM communication. + // The return value is undefined if SupportsRfcomm() returns false. + uint8 rfcomm_channel() const { return rfcomm_channel_; } + + private: + void ExtractChannels(XmlReader* reader); + void ExtractUuid(XmlReader* reader); + + std::string address_; + std::string name_; + std::string uuid_; + + bool supports_rfcomm_; + uint8 rfcomm_channel_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothServiceRecord); +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_SERVICE_RECORD_H_ diff --git a/device/bluetooth/bluetooth_service_record_unittest.cc b/device/bluetooth/bluetooth_service_record_unittest.cc new file mode 100644 index 0000000..b59474f5 --- /dev/null +++ b/device/bluetooth/bluetooth_service_record_unittest.cc @@ -0,0 +1,78 @@ +// Copyright (c) 2012 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 + +#include "base/base_paths.h" +#include "base/basictypes.h" +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/path_service.h" +#include "device/bluetooth/bluetooth_service_record.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +static const char* kAddress = "01:02:03:04:05:06"; +static const char* kCustomUuid = "01234567-89ab-cdef-0123-456789abcdef"; +static const char* kSerialUuid = "00001101-0000-1000-8000-00805f9b34fb"; + +} // namespace + +namespace device { + +class BluetoothServiceRecordTest : public testing::Test { + public: + FilePath GetTestDataFilePath(const char* file) { + FilePath path; + PathService::Get(base::DIR_SOURCE_ROOT, &path); + path = path.AppendASCII("device"); + path = path.AppendASCII("test"); + path = path.AppendASCII("data"); + path = path.AppendASCII("bluetooth"); + path = path.AppendASCII(file); + return path; + } +}; + +TEST_F(BluetoothServiceRecordTest, RfcommService) { + std::string xml_data; + file_util::ReadFileToString(GetTestDataFilePath("rfcomm.xml"), &xml_data); + + BluetoothServiceRecord service_record(kAddress, xml_data); + EXPECT_EQ(kAddress, service_record.address()); + EXPECT_EQ("Headset Audio Gateway", service_record.name()); + EXPECT_TRUE(service_record.SupportsRfcomm()); + EXPECT_EQ((uint8)12, service_record.rfcomm_channel()); + EXPECT_EQ(kCustomUuid, service_record.uuid()); +} + +TEST_F(BluetoothServiceRecordTest, ShortUuid) { + std::string xml_data; + file_util::ReadFileToString(GetTestDataFilePath("short_uuid.xml"), &xml_data); + BluetoothServiceRecord short_uuid_service_record(kAddress, xml_data); + EXPECT_EQ(kSerialUuid, short_uuid_service_record.uuid()); + + xml_data.clear(); + file_util::ReadFileToString( + GetTestDataFilePath("medium_uuid.xml"), &xml_data); + BluetoothServiceRecord medium_uuid_service_record(kAddress, xml_data); + EXPECT_EQ(kSerialUuid, medium_uuid_service_record.uuid()); +} + +TEST_F(BluetoothServiceRecordTest, CleanUuid) { + std::string xml_data; + file_util::ReadFileToString(GetTestDataFilePath("uppercase_uuid.xml"), + &xml_data); + BluetoothServiceRecord service_record(kAddress, xml_data); + EXPECT_EQ(kCustomUuid, service_record.uuid()); + + xml_data.clear(); + file_util::ReadFileToString(GetTestDataFilePath("invalid_uuid.xml"), + &xml_data); + BluetoothServiceRecord invalid_service_record(kAddress, xml_data); + EXPECT_EQ("", invalid_service_record.uuid()); +} + +} // namespace device diff --git a/device/bluetooth/bluetooth_socket.h b/device/bluetooth/bluetooth_socket.h new file mode 100644 index 0000000..b444110 --- /dev/null +++ b/device/bluetooth/bluetooth_socket.h @@ -0,0 +1,30 @@ +// Copyright (c) 2012 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_SOCKET_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_H_ + +#include "base/memory/ref_counted.h" + +namespace device { + +// BluetoothSocket represents a socket to a specific service on a +// BluetoothDevice. BluetoothSocket objects are ref counted and may outlive +// both the BluetoothDevice and BluetoothAdapter that were involved in their +// creation. +class BluetoothSocket : public base::RefCounted { + public: + // TODO(youngki): Replace this with an opaque id when read/write calls are + // added. This interface is platform-independent and file descriptor is + // linux-specific hence this method has to be renamed. + virtual int fd() const = 0; + + protected: + friend class base::RefCounted; + virtual ~BluetoothSocket() {} +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_H_ diff --git a/device/bluetooth/bluetooth_socket_chromeos.cc b/device/bluetooth/bluetooth_socket_chromeos.cc new file mode 100644 index 0000000..7e75a9d --- /dev/null +++ b/device/bluetooth/bluetooth_socket_chromeos.cc @@ -0,0 +1,71 @@ +// Copyright (c) 2012 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_socket_chromeos.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "base/logging.h" +#include "device/bluetooth/bluetooth_service_record.h" +#include "device/bluetooth/bluetooth_utils.h" + +using device::BluetoothServiceRecord; +using device::BluetoothSocket; + +namespace chromeos { + +BluetoothSocketChromeOs::BluetoothSocketChromeOs( + const std::string& address, int fd) + : address_(address), + fd_(fd) { +} + +BluetoothSocketChromeOs::~BluetoothSocketChromeOs() { + close(fd_); +} + +// static +scoped_refptr BluetoothSocketChromeOs::CreateBluetoothSocket( + const BluetoothServiceRecord& service_record) { + BluetoothSocketChromeOs* bluetooth_socket = NULL; + if (service_record.SupportsRfcomm()) { + int socket_fd = socket( + AF_BLUETOOTH, SOCK_STREAM | SOCK_NONBLOCK, BTPROTO_RFCOMM); + struct sockaddr_rc socket_address = { 0 }; + socket_address.rc_family = AF_BLUETOOTH; + socket_address.rc_channel = service_record.rfcomm_channel(); + device::bluetooth_utils::str2ba(service_record.address(), + &socket_address.rc_bdaddr); + + int status = connect(socket_fd, (struct sockaddr *)&socket_address, + sizeof(socket_address)); + int errsv = errno; + if (status == 0 || errno == EINPROGRESS) { + bluetooth_socket = new BluetoothSocketChromeOs(service_record.address(), + socket_fd); + } else { + LOG(ERROR) << "Failed to connect bluetooth socket " + << "(" << service_record.address() << "): " + << "(" << errsv << ") " << strerror(errsv); + close(socket_fd); + } + } + // TODO(bryeung): add support for L2CAP sockets as well. + + return scoped_refptr(bluetooth_socket); +} + +int BluetoothSocketChromeOs::fd() const { + return fd_; +} + +} // namespace chromeos diff --git a/device/bluetooth/bluetooth_socket_chromeos.h b/device/bluetooth/bluetooth_socket_chromeos.h new file mode 100644 index 0000000..0685830 --- /dev/null +++ b/device/bluetooth/bluetooth_socket_chromeos.h @@ -0,0 +1,45 @@ +// Copyright (c) 2012 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_SOCKET_CHROMEOS_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ + +#include + +#include "base/memory/ref_counted.h" +#include "device/bluetooth/bluetooth_socket.h" + +namespace device { + +class BluetoothServiceRecord; + +} // namespace device + +namespace chromeos { + +// This class is an implementation of BluetoothSocket class for Chrome OS +// platform. +class BluetoothSocketChromeOs : public device::BluetoothSocket { + public: + static scoped_refptr CreateBluetoothSocket( + const device::BluetoothServiceRecord& service_record); + + // BluetoothSocket override + virtual int fd() const OVERRIDE; + + protected: + virtual ~BluetoothSocketChromeOs(); + + private: + BluetoothSocketChromeOs(const std::string& address, int fd); + + const std::string address_; + const int fd_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothSocketChromeOs); +}; + +} // namespace chromeos + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_SOCKET_CHROMEOS_H_ diff --git a/device/bluetooth/bluetooth_utils.cc b/device/bluetooth/bluetooth_utils.cc new file mode 100644 index 0000000..6d06409 --- /dev/null +++ b/device/bluetooth/bluetooth_utils.cc @@ -0,0 +1,92 @@ +// Copyright (c) 2012 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_utils.h" + +#include + +#if defined(OS_CHROMEOS) +#include +#endif + +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "base/string_util.h" + +namespace { +static const char* kCommonUuidPostfix = "-0000-1000-8000-00805f9b34fb"; +static const char* kCommonUuidPrefix = "0000"; +static const int kUuidSize = 36; +} // namespace + +namespace device { +namespace bluetooth_utils { + +#if defined(OS_CHROMEOS) +bool str2ba(const std::string& in_address, bdaddr_t* out_address) { + if (!out_address) + return false; + + memset(out_address, 0, sizeof(*out_address)); + + if (in_address.size() != 17) + return false; + + std::string numbers_only; + for (int i = 0; i < 6; ++i) { + numbers_only += in_address.substr(i * 3, 2); + } + + std::vector address_bytes; + if (base::HexStringToBytes(numbers_only, &address_bytes)) { + if (address_bytes.size() == 6) { + for (int i = 0; i < 6; ++i) { + out_address->b[5 - i] = address_bytes[i]; + } + return true; + } + } + + return false; +} +#endif + +std::string CanonicalUuid(std::string uuid) { + if (uuid.empty()) + return ""; + + if (uuid.size() < 11 && uuid.find("0x") == 0) + uuid = uuid.substr(2); + + if (!(uuid.size() == 4 || uuid.size() == 8 || uuid.size() == 36)) + return ""; + + if (uuid.size() == 4 || uuid.size() == 8) { + for (size_t i = 0; i < uuid.size(); ++i) { + if (!IsHexDigit(uuid[i])) + return ""; + } + + if (uuid.size() == 4) + return kCommonUuidPrefix + uuid + kCommonUuidPostfix; + + return uuid + kCommonUuidPostfix; + } + + std::string uuid_result(uuid); + for (int i = 0; i < kUuidSize; ++i) { + if (i == 8 || i == 13 || i == 18 || i == 23) { + if (uuid[i] != '-') + return ""; + } else { + if (!IsHexDigit(uuid[i])) + return ""; + uuid_result[i] = tolower(uuid[i]); + } + } + return uuid_result; +} + +} // namespace bluetooth_utils +} // namespace device diff --git a/device/bluetooth/bluetooth_utils.h b/device/bluetooth/bluetooth_utils.h new file mode 100644 index 0000000..f796d5d --- /dev/null +++ b/device/bluetooth/bluetooth_utils.h @@ -0,0 +1,42 @@ +// Copyright (c) 2012 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_UTILS_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_UTILS_H_ + +#include + +#if defined(OS_CHROMEOS) +#include +#endif + +namespace device { +namespace bluetooth_utils { + +#if defined(OS_CHROMEOS) +// Converts a bluetooth address in the format "B0:D0:9C:0F:3A:2D" into a +// bdaddr_t struct. Returns true on success, false on failure. The contents +// of |out_address| are zeroed on failure. +// Note that the order is reversed upon conversion. For example, +// "B0:D0:9C:0F:3A:2D" -> {"0x2d", "0x3a", "0x0f", "0x9c", "0xd0", "0xb0"} +bool str2ba(const std::string& in_address, bdaddr_t* out_address); +#endif + +// Takes a 4, 8 or 36 character UUID, validates it and returns it in 36 +// character format with all hex digits lower case. If |uuid| is invalid, the +// empty string is returned. +// +// Valid inputs are: +// XXXX +// 0xXXXX +// XXXXXXXX +// 0xXXXXXXXX +// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX +std::string CanonicalUuid(std::string uuid); + +} // namespace bluetooth_utils +} // namespace device + +#endif // DEVICE_BLUETOOTH_BLUETOOTH_UTILS_H_ + diff --git a/device/bluetooth/bluetooth_utils_unittest.cc b/device/bluetooth/bluetooth_utils_unittest.cc new file mode 100644 index 0000000..0e05f8e --- /dev/null +++ b/device/bluetooth/bluetooth_utils_unittest.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2012 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. + +#if defined(OS_CHROMEOS) +#include +#endif + +#include "device/bluetooth/bluetooth_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace device { + +#if defined(OS_CHROMEOS) +TEST(BluetoothUtilsTest, str2ba) { + bdaddr_t bluetooth_address; + + EXPECT_TRUE(bluetooth_utils::str2ba("01:02:03:0A:10:A0", &bluetooth_address)); + EXPECT_EQ(1, bluetooth_address.b[5]); + EXPECT_EQ(2, bluetooth_address.b[4]); + EXPECT_EQ(3, bluetooth_address.b[3]); + EXPECT_EQ(10, bluetooth_address.b[2]); + EXPECT_EQ(16, bluetooth_address.b[1]); + EXPECT_EQ(160, bluetooth_address.b[0]); + + EXPECT_FALSE(bluetooth_utils::str2ba("obviously wrong", &bluetooth_address)); + EXPECT_FALSE(bluetooth_utils::str2ba("00:00", &bluetooth_address)); + EXPECT_FALSE( + bluetooth_utils::str2ba("00:00:00:00:00:00:00", &bluetooth_address)); + EXPECT_FALSE(bluetooth_utils::str2ba("01:02:03:0A:10:A0", NULL)); +} +#endif + +TEST(BluetoothUtilsTest, CanonicalUuid) { + // Does nothing for an already canonical UUID + EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", + bluetooth_utils::CanonicalUuid("00001101-0000-1000-8000-00805f9b34fb")); + + // Rejects misformatted + EXPECT_EQ("", bluetooth_utils::CanonicalUuid("1101a")); + EXPECT_EQ("", bluetooth_utils::CanonicalUuid("Z101")); + EXPECT_EQ("", bluetooth_utils::CanonicalUuid("0000-1101")); + EXPECT_EQ("", bluetooth_utils::CanonicalUuid("0000Z101")); + EXPECT_EQ("", + bluetooth_utils::CanonicalUuid("0001101-0000-1000-8000-00805f9b34fb")); + EXPECT_EQ("", + bluetooth_utils::CanonicalUuid("Z0001101-0000-1000-8000-00805f9b34fb")); + EXPECT_EQ("", + bluetooth_utils::CanonicalUuid("00001101 0000-1000-8000-00805f9b34fb")); + EXPECT_EQ("", + bluetooth_utils::CanonicalUuid("00001101-0000:1000-8000-00805f9b34fb")); + EXPECT_EQ("", + bluetooth_utils::CanonicalUuid("00001101-0000-1000;8000-00805f9b34fb")); + EXPECT_EQ("", + bluetooth_utils::CanonicalUuid("00001101-0000-1000-8000000805f9b34fb")); + + // Lower case + EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", + bluetooth_utils::CanonicalUuid("00001101-0000-1000-8000-00805F9B34FB")); + + // Short to full + EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", + bluetooth_utils::CanonicalUuid("1101")); + EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", + bluetooth_utils::CanonicalUuid("0x1101")); + EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", + bluetooth_utils::CanonicalUuid("00001101")); + EXPECT_EQ("00001101-0000-1000-8000-00805f9b34fb", + bluetooth_utils::CanonicalUuid("0x00001101")); + + // No 0x prefix on 36 character + EXPECT_EQ("", + bluetooth_utils::CanonicalUuid("0x00001101-0000-1000-8000-00805f9b34fb")); +} + +} // namespace device diff --git a/device/bluetooth/test/mock_bluetooth_adapter.cc b/device/bluetooth/test/mock_bluetooth_adapter.cc new file mode 100644 index 0000000..cae8829 --- /dev/null +++ b/device/bluetooth/test/mock_bluetooth_adapter.cc @@ -0,0 +1,20 @@ +// Copyright (c) 2012 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/test/mock_bluetooth_adapter.h" + +namespace device { + +MockBluetoothAdapter::Observer::Observer() {} +MockBluetoothAdapter::Observer::~Observer() {} + +MockBluetoothAdapter::MockBluetoothAdapter(const std::string& address, + const std::string& name) { + address_ = address; + name_ = name; +} + +MockBluetoothAdapter::~MockBluetoothAdapter() {} + +} // namespace device diff --git a/device/bluetooth/test/mock_bluetooth_adapter.h b/device/bluetooth/test/mock_bluetooth_adapter.h new file mode 100644 index 0000000..33f7afb --- /dev/null +++ b/device/bluetooth/test/mock_bluetooth_adapter.h @@ -0,0 +1,61 @@ +// Copyright (c) 2012 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_TEST_MOCK_BLUETOOTH_ADAPTER_H_ +#define DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_ADAPTER_H_ + +#include + +#include "base/callback.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_device.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace device { + +class MockBluetoothAdapter : public BluetoothAdapter { + public: + class Observer : public BluetoothAdapter::Observer { + public: + Observer(); + virtual ~Observer(); + + MOCK_METHOD2(AdapterPresentChanged, void(BluetoothAdapter*, bool)); + MOCK_METHOD2(AdapterPoweredChanged, void(BluetoothAdapter*, bool)); + MOCK_METHOD2(AdapterDiscoveringChanged, void(BluetoothAdapter*, bool)); + MOCK_METHOD2(DeviceAdded, void(BluetoothAdapter*, BluetoothDevice*)); + MOCK_METHOD2(DeviceChanged, void(BluetoothAdapter*, BluetoothDevice*)); + MOCK_METHOD2(DeviceRemoved, void(BluetoothAdapter*, BluetoothDevice*)); + }; + + MockBluetoothAdapter(const std::string& address, const std::string& name); + + MOCK_METHOD1(AddObserver, void(BluetoothAdapter::Observer*)); + MOCK_METHOD1(RemoveObserver, void(BluetoothAdapter::Observer*)); + MOCK_CONST_METHOD0(IsPresent, bool()); + MOCK_CONST_METHOD0(IsPowered, bool()); + MOCK_METHOD3(SetPowered, + void(bool discovering, + const base::Closure& callback, + const ErrorCallback& error_callback)); + MOCK_CONST_METHOD0(IsDiscovering, bool()); + MOCK_METHOD3(SetDiscovering, + void(bool discovering, + const base::Closure& callback, + const ErrorCallback& error_callback)); + MOCK_CONST_METHOD0(GetDevices, BluetoothAdapter::ConstDeviceList()); + MOCK_METHOD1(GetDevice, BluetoothDevice*(const std::string& address)); + MOCK_CONST_METHOD1(GetDevice, + const BluetoothDevice*(const std::string& address)); + MOCK_METHOD2( + ReadLocalOutOfBandPairingData, + void(const BluetoothOutOfBandPairingDataCallback& callback, + const ErrorCallback& error_callback)); + protected: + virtual ~MockBluetoothAdapter(); +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_ADAPTER_H_ diff --git a/device/bluetooth/test/mock_bluetooth_device.cc b/device/bluetooth/test/mock_bluetooth_device.cc new file mode 100644 index 0000000..f2f358d --- /dev/null +++ b/device/bluetooth/test/mock_bluetooth_device.cc @@ -0,0 +1,41 @@ +// Copyright (c) 2012 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 "base/utf_string_conversions.h" +#include "device/bluetooth/test/mock_bluetooth_adapter.h" +#include "device/bluetooth/test/mock_bluetooth_device.h" + +namespace device { + +MockBluetoothDevice::MockBluetoothDevice(MockBluetoothAdapter* adapter, + const std::string& name, + const std::string& address, + bool paired, + bool bonded, + bool connected) + : name_(UTF8ToUTF16(name)), + address_(address) { + ON_CALL(*this, GetName()) + .WillByDefault(testing::Return(name_)); + ON_CALL(*this, address()) + .WillByDefault(testing::ReturnRef(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, ExpectingPinCode()) + .WillByDefault(testing::Return(false)); + ON_CALL(*this, ExpectingPasskey()) + .WillByDefault(testing::Return(false)); + ON_CALL(*this, ExpectingConfirmation()) + .WillByDefault(testing::Return(false)); + ON_CALL(*this, GetServices()) + .WillByDefault(testing::ReturnRef(service_list_)); +} + +MockBluetoothDevice::~MockBluetoothDevice() {} + +} // namespace device diff --git a/device/bluetooth/test/mock_bluetooth_device.h b/device/bluetooth/test/mock_bluetooth_device.h new file mode 100644 index 0000000..e917a30 --- /dev/null +++ b/device/bluetooth/test/mock_bluetooth_device.h @@ -0,0 +1,79 @@ +// Copyright (c) 2012 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_TEST_MOCK_BLUETOOTH_DEVICE_H_ +#define DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_DEVICE_H_ + +#include + +#include "base/string16.h" +#include "device/bluetooth/bluetooth_device.h" +#include "device/bluetooth/bluetooth_out_of_band_pairing_data.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace device { + +class MockBluetoothAdapter; + +class MockBluetoothDevice : public BluetoothDevice { + public: + MockBluetoothDevice(MockBluetoothAdapter* adapter, + 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(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_METHOD2(GetServiceRecords, + void(const BluetoothDevice::ServiceRecordsCallback&, + const BluetoothDevice::ErrorCallback&)); + MOCK_CONST_METHOD1(ProvidesServiceWithUUID, bool(const std::string&)); + MOCK_METHOD2(ProvidesServiceWithName, + void(const std::string&, + const BluetoothDevice::ProvidesServiceCallback&)); + MOCK_CONST_METHOD0(ExpectingPinCode, bool()); + MOCK_CONST_METHOD0(ExpectingPasskey, bool()); + MOCK_CONST_METHOD0(ExpectingConfirmation, bool()); + MOCK_METHOD3(Connect, + void(BluetoothDevice::PairingDelegate* pairnig_delegate, + const base::Closure& callback, + const BluetoothDevice::ErrorCallback& error_callback)); + MOCK_METHOD1(SetPinCode, void(const std::string&)); + MOCK_METHOD1(SetPasskey, void(uint32)); + MOCK_METHOD0(ConfirmPairing, void()); + MOCK_METHOD0(RejectPairing, void()); + MOCK_METHOD0(CancelPairing, void()); + MOCK_METHOD2(Disconnect, + void(const base::Closure& callback, + const BluetoothDevice::ErrorCallback& error_callback)); + MOCK_METHOD1(Forget, void(const BluetoothDevice::ErrorCallback&)); + MOCK_METHOD2(ConnectToService, + void(const std::string&, + const BluetoothDevice::SocketCallback&)); + + MOCK_METHOD3(SetOutOfBandPairingData, + void(const BluetoothOutOfBandPairingData& data, + const base::Closure& callback, + const BluetoothDevice::ErrorCallback& error_callback)); + MOCK_METHOD2(ClearOutOfBandPairingData, + void(const base::Closure& callback, + const BluetoothDevice::ErrorCallback& error_callback)); + + private: + string16 name_; + std::string address_; + BluetoothDevice::ServiceList service_list_; +}; + +} // namespace device + +#endif // DEVICE_BLUETOOTH_TEST_MOCK_BLUETOOTH_DEVICE_H_ diff --git a/device/device.gyp b/device/device.gyp new file mode 100644 index 0000000..4b4c1ad --- /dev/null +++ b/device/device.gyp @@ -0,0 +1,111 @@ +# Copyright (c) 2012 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. + +{ + 'variables': { + }, + 'targets': [ + { + 'target_name': 'device_bluetooth', + 'type': '<(library)', + 'dependencies': [ + '../chrome/chrome_resources.gyp:chrome_strings', + '../third_party/libxml/libxml.gyp:libxml', + '../ui/ui.gyp:ui' + ], + 'sources': [ + 'bluetooth/bluetooth_adapter.cc', + 'bluetooth/bluetooth_adapter.h', + 'bluetooth/bluetooth_adapter_chromeos.cc', + 'bluetooth/bluetooth_adapter_chromeos.h', + 'bluetooth/bluetooth_adapter_factory.cc', + 'bluetooth/bluetooth_adapter_factory.h', + 'bluetooth/bluetooth_device.cc', + 'bluetooth/bluetooth_device.h', + 'bluetooth/bluetooth_device_chromeos.cc', + 'bluetooth/bluetooth_device_chromeos.h', + 'bluetooth/bluetooth_out_of_band_pairing_data.h', + 'bluetooth/bluetooth_service_record.cc', + 'bluetooth/bluetooth_service_record.h', + 'bluetooth/bluetooth_socket.h', + 'bluetooth/bluetooth_socket_chromeos.cc', + 'bluetooth/bluetooth_socket_chromeos.h', + 'bluetooth/bluetooth_utils.cc', + 'bluetooth/bluetooth_utils.h', + ], + 'conditions': [ + ['chromeos==0', { + 'sources!': [ + # ChromeOs-only; exclude on other platforms. + 'bluetooth/bluetooth_adapter_chromeos.cc', + 'bluetooth/bluetooth_adapter_chromeos.h', + 'bluetooth/bluetooth_device_chromeos.cc', + 'bluetooth/bluetooth_device_chromeos.h', + 'bluetooth/bluetooth_socket_chromeos.cc', + 'bluetooth/bluetooth_socket_chromeos.h', + ] + }, { # chromeos==1 + 'dependencies': [ + '../build/linux/system.gyp:dbus-glib', + '../chromeos/chromeos.gyp:chromeos', + '../dbus/dbus.gyp:dbus', + ] + }], + ], + }, + { + 'target_name': 'device_bluetooth_mocks', + 'type': '<(library)', + 'dependencies': [ + 'device_bluetooth', + '../testing/gmock.gyp:gmock', + ], + 'sources': [ + 'bluetooth/test/mock_bluetooth_adapter.cc', + 'bluetooth/test/mock_bluetooth_adapter.h', + 'bluetooth/test/mock_bluetooth_device.cc', + 'bluetooth/test/mock_bluetooth_device.h', + ], + 'include_dirs': [ + '..', + ], + }, + { + 'target_name': 'device_unittests', + 'type': '<(gtest_target_type)', + 'dependencies': [ + 'device_bluetooth', + 'device_bluetooth_mocks', + '../base/base.gyp:test_support_base', + '../content/content.gyp:test_support_content', + '../testing/gmock.gyp:gmock', + '../testing/gtest.gyp:gtest', + ], + 'sources': [ + 'bluetooth/bluetooth_adapter_chromeos_unittest.cc', + 'bluetooth/bluetooth_adapter_chromeos_devices_unittest.cc', + 'bluetooth/bluetooth_service_record_unittest.cc', + 'bluetooth/bluetooth_utils_unittest.cc', + 'test/device_test_suite.cc', + 'test/device_test_suite.h', + 'test/run_all_unittests.cc', + ], + 'conditions': [ + ['chromeos==0', { + 'sources!': [ + # ChromeOs-only; exclude on other platforms. + 'bluetooth/bluetooth_adapter_chromeos_unittest.cc', + 'bluetooth/bluetooth_adapter_chromeos_devices_unittest.cc', + ] + }, { # chromeos==1 + 'dependencies': [ + '../build/linux/system.gyp:dbus-glib', + '../chromeos/chromeos.gyp:chromeos_test_support', + '../dbus/dbus.gyp:dbus', + ] + }], + ], + }, + ], +} diff --git a/device/test/data/bluetooth/invalid_uuid.xml b/device/test/data/bluetooth/invalid_uuid.xml new file mode 100644 index 0000000..2b33304 --- /dev/null +++ b/device/test/data/bluetooth/invalid_uuid.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/device/test/data/bluetooth/medium_uuid.xml b/device/test/data/bluetooth/medium_uuid.xml new file mode 100644 index 0000000..432d7fe --- /dev/null +++ b/device/test/data/bluetooth/medium_uuid.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/device/test/data/bluetooth/rfcomm.xml b/device/test/data/bluetooth/rfcomm.xml new file mode 100644 index 0000000..ec3bdec --- /dev/null +++ b/device/test/data/bluetooth/rfcomm.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/device/test/data/bluetooth/short_uuid.xml b/device/test/data/bluetooth/short_uuid.xml new file mode 100644 index 0000000..9ad3c9f --- /dev/null +++ b/device/test/data/bluetooth/short_uuid.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/device/test/data/bluetooth/uppercase_uuid.xml b/device/test/data/bluetooth/uppercase_uuid.xml new file mode 100644 index 0000000..4e0574f --- /dev/null +++ b/device/test/data/bluetooth/uppercase_uuid.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/device/test/device_test_suite.cc b/device/test/device_test_suite.cc new file mode 100644 index 0000000..6556076 --- /dev/null +++ b/device/test/device_test_suite.cc @@ -0,0 +1,18 @@ +// Copyright (c) 2012 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/test/device_test_suite.h" + +#include "content/public/common/content_client.h" + +DeviceTestSuite::DeviceTestSuite(int argc, char** argv) + : content::ContentTestSuiteBase(argc, argv) { +} + +DeviceTestSuite::~DeviceTestSuite() { +} + +content::ContentClient* DeviceTestSuite::CreateClientForInitialization() { + return new content::ContentClient(); +} diff --git a/device/test/device_test_suite.h b/device/test/device_test_suite.h new file mode 100644 index 0000000..15059ab --- /dev/null +++ b/device/test/device_test_suite.h @@ -0,0 +1,19 @@ +// Copyright (c) 2012 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_TEST_DEVICE_TEST_SUITE_H_ +#define DEVICE_TEST_DEVICE_TEST_SUITE_H_ + +#include "content/public/test/content_test_suite_base.h" + +class DeviceTestSuite : public content::ContentTestSuiteBase { + public: + DeviceTestSuite(int argc, char** argv); + virtual ~DeviceTestSuite(); + + protected: + virtual content::ContentClient* CreateClientForInitialization() OVERRIDE; +}; + +#endif // DEVICE_TEST_DEVICE_TEST_SUITE_H_ diff --git a/device/test/run_all_unittests.cc b/device/test/run_all_unittests.cc new file mode 100644 index 0000000..36e6e51 --- /dev/null +++ b/device/test/run_all_unittests.cc @@ -0,0 +1,10 @@ +// Copyright (c) 2011 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 "content/public/test/unittest_test_suite.h" +#include "device/test/device_test_suite.h" + +int main(int argc, char **argv) { + return content::UnitTestTestSuite(new DeviceTestSuite(argc, argv)).Run(); +} -- cgit v1.1