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