123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// found in the LICENSE file.
423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chromeos/dbus/bluetooth_gatt_service_client.h"
623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/bind.h"
823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/memory/weak_ptr.h"
923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/observer_list.h"
1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "dbus/bus.h"
1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "dbus/object_manager.h"
1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace chromeos {
1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)BluetoothGattServiceClient::Properties::Properties(
1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    dbus::ObjectProxy* object_proxy,
1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& interface_name,
1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const PropertyChangedCallback&callback)
2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    : dbus::PropertySet(object_proxy, interface_name, callback) {
2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  RegisterProperty(bluetooth_gatt_service::kUUIDProperty, &uuid);
2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  RegisterProperty(bluetooth_gatt_service::kIncludesProperty, &includes);
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RegisterProperty(bluetooth_gatt_service::kDeviceProperty, &device);
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RegisterProperty(bluetooth_gatt_service::kPrimaryProperty, &primary);
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RegisterProperty(bluetooth_gatt_service::kCharacteristicsProperty,
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   &characteristics);
2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)BluetoothGattServiceClient::Properties::~Properties() {
3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// The BluetoothGattServiceClient implementation used in production.
3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)class BluetoothGattServiceClientImpl : public BluetoothGattServiceClient,
3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                       public dbus::ObjectManager::Interface {
3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) public:
3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  BluetoothGattServiceClientImpl()
3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      : object_manager_(NULL),
3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        weak_ptr_factory_(this) {
3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual ~BluetoothGattServiceClientImpl() {
4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    object_manager_->UnregisterInterface(
4323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        bluetooth_gatt_service::kBluetoothGattServiceInterface);
4423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // BluetoothGattServiceClientImpl override.
4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void AddObserver(
4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      BluetoothGattServiceClient::Observer* observer) OVERRIDE {
4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(observer);
5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    observers_.AddObserver(observer);
5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
5223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // BluetoothGattServiceClientImpl override.
5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void RemoveObserver(
5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      BluetoothGattServiceClient::Observer* observer) OVERRIDE {
5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(observer);
5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    observers_.RemoveObserver(observer);
5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
5923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // BluetoothGattServiceClientImpl override.
6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual std::vector<dbus::ObjectPath> GetServices() OVERRIDE {
6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(object_manager_);
6323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return object_manager_->GetObjectsWithInterface(
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        bluetooth_gatt_service::kBluetoothGattServiceInterface);
6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
6723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // BluetoothGattServiceClientImpl override.
6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual Properties* GetProperties(
6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      const dbus::ObjectPath& object_path) OVERRIDE {
7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    DCHECK(object_manager_);
7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return static_cast<Properties*>(
7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        object_manager_->GetProperties(
7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)            object_path,
7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)            bluetooth_gatt_service::kBluetoothGattServiceInterface));
7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // dbus::ObjectManager::Interface override.
7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual dbus::PropertySet* CreateProperties(
7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      dbus::ObjectProxy *object_proxy,
8023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      const dbus::ObjectPath& object_path,
8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      const std::string& interface_name) OVERRIDE {
8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    Properties* properties = new Properties(
8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        object_proxy,
8423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        interface_name,
8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        base::Bind(&BluetoothGattServiceClientImpl::OnPropertyChanged,
8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                   object_path));
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return static_cast<dbus::PropertySet*>(properties);
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // dbus::ObjectManager::Interface override.
9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void ObjectAdded(const dbus::ObjectPath& object_path,
9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                           const std::string& interface_name) OVERRIDE {
9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    VLOG(2) << "Remote GATT service added: " << object_path.value();
9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_,
9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                      GattServiceAdded(object_path));
9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // dbus::ObjectManager::Interface override.
10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                             const std::string& interface_name) OVERRIDE {
10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    VLOG(2) << "Remote GATT service removed: " << object_path.value();
10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_,
10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                      GattServiceRemoved(object_path));
10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) protected:
10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // chromeos::DBusClient override.
10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    object_manager_ = bus->GetObjectManager(
11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        bluetooth_object_manager::kBluetoothObjectManagerServiceName,
11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        dbus::ObjectPath(
11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)            bluetooth_object_manager::kBluetoothObjectManagerServicePath));
11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    object_manager_->RegisterInterface(
11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        bluetooth_gatt_service::kBluetoothGattServiceInterface, this);
11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) private:
11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Called by dbus::PropertySet when a property value is changed, either by
12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // result of a signal or response to a GetAll() or Get() call. Informs
12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // observers.
12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  virtual void OnPropertyChanged(const dbus::ObjectPath& object_path,
12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 const std::string& property_name) {
12423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    VLOG(2) << "Remote GATT service property changed: " << object_path.value()
12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)            << ": " << property_name;
12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothGattServiceClient::Observer, observers_,
12723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                      GattServicePropertyChanged(object_path, property_name));
12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  dbus::ObjectManager* object_manager_;
13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // List of observers interested in event notifications from us.
13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ObserverList<BluetoothGattServiceClient::Observer> observers_;
13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Weak pointer factory for generating 'this' pointers that might live longer
13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // than we do.
13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Note: This should remain the last member so it'll be destroyed and
13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // invalidate its weak pointers before any other members are destroyed.
13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::WeakPtrFactory<BluetoothGattServiceClientImpl> weak_ptr_factory_;
14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceClientImpl);
14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)};
14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)BluetoothGattServiceClient::BluetoothGattServiceClient() {
14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
14623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)BluetoothGattServiceClient::~BluetoothGattServiceClient() {
14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
14923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// static
15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)BluetoothGattServiceClient* BluetoothGattServiceClient::Create() {
15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return new BluetoothGattServiceClientImpl();
15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}  // namespace chromeos
156