1e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// found in the LICENSE file. 4e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chromeos/dbus/bluetooth_gatt_manager_client.h" 6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/bind.h" 8e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/memory/weak_ptr.h" 9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "dbus/bus.h" 10e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "dbus/message.h" 11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "dbus/object_proxy.h" 12e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "third_party/cros_system_api/dbus/service_constants.h" 13e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 14e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace chromeos { 15e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char BluetoothGattManagerClient::kNoResponseError[] = 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "org.chromium.Error.NoResponse"; 18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// The BluetoothGattManagerClient implementation used in production. 20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass BluetoothGattManagerClientImpl : public BluetoothGattManagerClient { 21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public: 22e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch BluetoothGattManagerClientImpl() 23e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch : object_proxy_(NULL), 24e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch weak_ptr_factory_(this) { 25e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 26e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual ~BluetoothGattManagerClientImpl() { 28e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 29e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 30e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // BluetoothGattManagerClient override. 31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual void RegisterService(const dbus::ObjectPath& service_path, 32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const Options& options, 33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const base::Closure& callback, 34e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const ErrorCallback& error_callback) OVERRIDE { 35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::MethodCall method_call( 36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bluetooth_gatt_manager::kBluetoothGattManagerInterface, 37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bluetooth_gatt_manager::kRegisterService); 38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::MessageWriter writer(&method_call); 40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch writer.AppendObjectPath(service_path); 41e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 42e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // TODO(armansito): The parameters of the Options dictionary are undefined 43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // but the method signature still requires a value dictionary. Pass an 44e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // empty dictionary and fill in the contents later once this is defined. 45e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::MessageWriter array_writer(NULL); 46e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch writer.OpenArray("{sv}", &array_writer); 47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch writer.CloseContainer(&array_writer); 48e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(object_proxy_); 50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_proxy_->CallMethodWithErrorCallback( 51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch &method_call, 52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::Bind(&BluetoothGattManagerClientImpl::OnSuccess, 54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch weak_ptr_factory_.GetWeakPtr(), callback), 55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::Bind(&BluetoothGattManagerClientImpl::OnError, 56e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch weak_ptr_factory_.GetWeakPtr(), error_callback)); 57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // BluetoothGattManagerClient override. 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual void UnregisterService(const dbus::ObjectPath& service_path, 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const base::Closure& callback, 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const ErrorCallback& error_callback) OVERRIDE { 63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::MethodCall method_call( 64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bluetooth_gatt_manager::kBluetoothGattManagerInterface, 65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bluetooth_gatt_manager::kUnregisterService); 66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::MessageWriter writer(&method_call); 68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch writer.AppendObjectPath(service_path); 69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(object_proxy_); 71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_proxy_->CallMethodWithErrorCallback( 72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch &method_call, 73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::Bind(&BluetoothGattManagerClientImpl::OnSuccess, 75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch weak_ptr_factory_.GetWeakPtr(), callback), 76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::Bind(&BluetoothGattManagerClientImpl::OnError, 77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch weak_ptr_factory_.GetWeakPtr(), error_callback)); 78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch protected: 81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // chromeos::DBusClient override. 82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual void Init(dbus::Bus* bus) OVERRIDE { 83e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(bus); 84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch object_proxy_ = bus->GetObjectProxy( 85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bluetooth_gatt_manager::kBluetoothGattManagerServiceName, 86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::ObjectPath( 87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bluetooth_gatt_manager::kBluetoothGattManagerInterface)); 88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch private: 91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Called when a response for a successful method call is received. 92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void OnSuccess(const base::Closure& callback, dbus::Response* response) { 93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(response); 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callback.Run(); 95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Called when a response for a failed method call is received. 98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void OnError(const ErrorCallback& error_callback, 99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::ErrorResponse* response) { 100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Error response has optional error message argument. 101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch std::string error_name; 102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch std::string error_message; 103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (response) { 104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::MessageReader reader(response); 105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error_name = response->GetErrorName(); 106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch reader.PopString(&error_message); 107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } else { 108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error_name = kNoResponseError; 109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch error_callback.Run(error_name, error_message); 111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // The proxy to the remote GATT manager object. 114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch dbus::ObjectProxy* object_proxy_; 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Weak pointer factory for generating 'this' pointers that might live longer 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // than we do. 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Note: This should remain the last member so it'll be destroyed and 119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // invalidate its weak pointers before any other members are destroyed. 120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::WeakPtrFactory<BluetoothGattManagerClientImpl> weak_ptr_factory_; 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DISALLOW_COPY_AND_ASSIGN(BluetoothGattManagerClientImpl); 123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}; 124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochBluetoothGattManagerClient::BluetoothGattManagerClient() { 126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochBluetoothGattManagerClient::~BluetoothGattManagerClient() { 129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// static 132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochBluetoothGattManagerClient* BluetoothGattManagerClient::Create() { 133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return new BluetoothGattManagerClientImpl(); 134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} // namespace chromeos 137