17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chromeos/dbus/bluetooth_adapter_client.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/bus.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/message.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_manager.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_path.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_proxy.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos {
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char BluetoothAdapterClient::kNoResponseError[] =
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    "org.chromium.Error.NoResponse";
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const char BluetoothAdapterClient::kUnknownAdapterError[] =
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    "org.chromium.Error.UnknownAdapter";
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothAdapterClient::Properties::Properties(
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dbus::ObjectProxy* object_proxy,
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& interface_name,
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const PropertyChangedCallback& callback)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : dbus::PropertySet(object_proxy, interface_name, callback) {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kAddressProperty, &address);
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kNameProperty, &name);
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kAliasProperty, &alias);
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kClassProperty, &bluetooth_class);
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kPoweredProperty, &powered);
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kDiscoverableProperty, &discoverable);
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kPairableProperty, &pairable);
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kPairableTimeoutProperty,
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &pairable_timeout);
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kDiscoverableTimeoutProperty,
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   &discoverable_timeout);
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering);
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids);
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias);
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothAdapterClient::Properties::~Properties() {
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// The BluetoothAdapterClient implementation used in production.
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BluetoothAdapterClientImpl
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public BluetoothAdapterClient,
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      public dbus::ObjectManager::Interface {
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BluetoothAdapterClientImpl()
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : object_manager_(NULL), weak_ptr_factory_(this) {}
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~BluetoothAdapterClientImpl() {
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    object_manager_->UnregisterInterface(
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        bluetooth_adapter::kBluetoothAdapterInterface);
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // BluetoothAdapterClient override.
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void AddObserver(BluetoothAdapterClient::Observer* observer)
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      OVERRIDE {
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(observer);
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observers_.AddObserver(observer);
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // BluetoothAdapterClient override.
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void RemoveObserver(BluetoothAdapterClient::Observer* observer)
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      OVERRIDE {
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(observer);
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observers_.RemoveObserver(observer);
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns the list of adapter object paths known to the system.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual std::vector<dbus::ObjectPath> GetAdapters() OVERRIDE {
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return object_manager_->GetObjectsWithInterface(
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        bluetooth_adapter::kBluetoothAdapterInterface);
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // dbus::ObjectManager::Interface override.
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual dbus::PropertySet* CreateProperties(
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dbus::ObjectProxy* object_proxy,
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const dbus::ObjectPath& object_path,
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& interface_name) OVERRIDE {
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Properties* properties = new Properties(
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        object_proxy,
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        interface_name,
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged,
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   object_path));
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return static_cast<dbus::PropertySet*>(properties);
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // BluetoothAdapterClient override.
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      OVERRIDE {
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return static_cast<Properties*>(
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        object_manager_->GetProperties(
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            object_path,
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            bluetooth_adapter::kBluetoothAdapterInterface));
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // BluetoothAdapterClient override.
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void StartDiscovery(const dbus::ObjectPath& object_path,
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              const base::Closure& callback,
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              const ErrorCallback& error_callback) OVERRIDE {
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dbus::MethodCall method_call(
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        bluetooth_adapter::kBluetoothAdapterInterface,
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        bluetooth_adapter::kStartDiscovery);
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dbus::ObjectProxy* object_proxy =
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        object_manager_->GetObjectProxy(object_path);
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!object_proxy) {
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_callback.Run(kUnknownAdapterError, "");
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    object_proxy->CallMethodWithErrorCallback(
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &method_call,
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), callback),
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothAdapterClientImpl::OnError,
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), error_callback));
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // BluetoothAdapterClient override.
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void StopDiscovery(const dbus::ObjectPath& object_path,
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const base::Closure& callback,
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const ErrorCallback& error_callback) OVERRIDE {
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dbus::MethodCall method_call(
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        bluetooth_adapter::kBluetoothAdapterInterface,
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        bluetooth_adapter::kStopDiscovery);
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dbus::ObjectProxy* object_proxy =
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        object_manager_->GetObjectProxy(object_path);
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!object_proxy) {
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_callback.Run(kUnknownAdapterError, "");
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    object_proxy->CallMethodWithErrorCallback(
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &method_call,
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), callback),
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothAdapterClientImpl::OnError,
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), error_callback));
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // BluetoothAdapterClient override.
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void RemoveDevice(const dbus::ObjectPath& object_path,
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const dbus::ObjectPath& device_path,
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const base::Closure& callback,
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const ErrorCallback& error_callback) OVERRIDE {
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dbus::MethodCall method_call(
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        bluetooth_adapter::kBluetoothAdapterInterface,
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        bluetooth_adapter::kRemoveDevice);
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dbus::MessageWriter writer(&method_call);
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    writer.AppendObjectPath(device_path);
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dbus::ObjectProxy* object_proxy =
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        object_manager_->GetObjectProxy(object_path);
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!object_proxy) {
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_callback.Run(kUnknownAdapterError, "");
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    object_proxy->CallMethodWithErrorCallback(
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &method_call,
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothAdapterClientImpl::OnSuccess,
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), callback),
1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothAdapterClientImpl::OnError,
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(), error_callback));
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected:
181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    object_manager_ = bus->GetObjectManager(
183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        bluetooth_object_manager::kBluetoothObjectManagerServiceName,
184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        dbus::ObjectPath(
185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)            bluetooth_object_manager::kBluetoothObjectManagerServicePath));
186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    object_manager_->RegisterInterface(
187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        bluetooth_adapter::kBluetoothAdapterInterface, this);
188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called by dbus::ObjectManager when an object with the adapter interface
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is created. Informs observers.
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ObjectAdded(const dbus::ObjectPath& object_path,
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           const std::string& interface_name) OVERRIDE {
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      AdapterAdded(object_path));
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called by dbus::ObjectManager when an object with the adapter interface
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is removed. Informs observers.
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const std::string& interface_name) OVERRIDE {
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      AdapterRemoved(object_path));
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called by dbus::PropertySet when a property value is changed,
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // either by result of a signal or response to a GetAll() or Get()
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // call. Informs observers.
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OnPropertyChanged(const dbus::ObjectPath& object_path,
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const std::string& property_name) {
2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_,
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      AdapterPropertyChanged(object_path, property_name));
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called when a response for successful method call is received.
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OnSuccess(const base::Closure& callback,
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 dbus::Response* response) {
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(response);
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.Run();
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called when a response for a failed method call is received.
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OnError(const ErrorCallback& error_callback,
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               dbus::ErrorResponse* response) {
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Error response has optional error message argument.
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string error_name;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string error_message;
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (response) {
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dbus::MessageReader reader(response);
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_name = response->GetErrorName();
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      reader.PopString(&error_message);
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_name = kNoResponseError;
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      error_message = "";
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    error_callback.Run(error_name, error_message);
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dbus::ObjectManager* object_manager_;
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // List of observers interested in event notifications from us.
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<BluetoothAdapterClient::Observer> observers_;
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Weak pointer factory for generating 'this' pointers that might live longer
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // than we do.
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Note: This should remain the last member so it'll be destroyed and
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // invalidate its weak pointers before any other members are destroyed.
2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::WeakPtrFactory<BluetoothAdapterClientImpl>
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_ptr_factory_;
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl);
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothAdapterClient::BluetoothAdapterClient() {
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothAdapterClient::~BluetoothAdapterClient() {
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)BluetoothAdapterClient* BluetoothAdapterClient::Create() {
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return new BluetoothAdapterClientImpl;
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace chromeos
266