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