1// Copyright 2013 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_input_client.h"
6
7#include <map>
8
9#include "base/logging.h"
10#include "base/stl_util.h"
11#include "chromeos/dbus/fake_bluetooth_input_client.h"
12#include "dbus/bus.h"
13#include "dbus/message.h"
14#include "dbus/object_manager.h"
15#include "dbus/object_path.h"
16#include "dbus/object_proxy.h"
17#include "third_party/cros_system_api/dbus/service_constants.h"
18
19namespace chromeos {
20
21BluetoothInputClient::Properties::Properties(
22    dbus::ObjectProxy* object_proxy,
23    const std::string& interface_name,
24    const PropertyChangedCallback& callback)
25    : dbus::PropertySet(object_proxy, interface_name, callback) {
26  RegisterProperty(bluetooth_input::kReconnectModeProperty, &reconnect_mode);
27}
28
29BluetoothInputClient::Properties::~Properties() {
30}
31
32
33// The BluetoothInputClient implementation used in production.
34class BluetoothInputClientImpl
35    : public BluetoothInputClient,
36      public dbus::ObjectManager::Interface {
37 public:
38  explicit BluetoothInputClientImpl(dbus::Bus* bus)
39      : bus_(bus),
40        weak_ptr_factory_(this) {
41    object_manager_ = bus_->GetObjectManager(
42        bluetooth_object_manager::kBluetoothObjectManagerServiceName,
43        dbus::ObjectPath(
44            bluetooth_object_manager::kBluetoothObjectManagerServicePath));
45    object_manager_->RegisterInterface(
46        bluetooth_input::kBluetoothInputInterface, this);
47  }
48
49  virtual ~BluetoothInputClientImpl() {
50    object_manager_->UnregisterInterface(
51        bluetooth_input::kBluetoothInputInterface);
52  }
53
54  // BluetoothInputClient override.
55  virtual void AddObserver(BluetoothInputClient::Observer* observer)
56      OVERRIDE {
57    DCHECK(observer);
58    observers_.AddObserver(observer);
59  }
60
61  // BluetoothInputClient override.
62  virtual void RemoveObserver(BluetoothInputClient::Observer* observer)
63      OVERRIDE {
64    DCHECK(observer);
65    observers_.RemoveObserver(observer);
66  }
67
68  // dbus::ObjectManager::Interface override.
69  virtual dbus::PropertySet* CreateProperties(
70      dbus::ObjectProxy* object_proxy,
71      const dbus::ObjectPath& object_path,
72      const std::string& interface_name) OVERRIDE {
73    Properties* properties = new Properties(
74        object_proxy,
75        interface_name,
76        base::Bind(&BluetoothInputClientImpl::OnPropertyChanged,
77                   weak_ptr_factory_.GetWeakPtr(),
78                   object_path));
79    return static_cast<dbus::PropertySet*>(properties);
80  }
81
82  // BluetoothInputClient override.
83  virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
84      OVERRIDE {
85    return static_cast<Properties*>(
86        object_manager_->GetProperties(
87            object_path,
88            bluetooth_input::kBluetoothInputInterface));
89  }
90
91 private:
92  // Called by dbus::ObjectManager when an object with the input interface
93  // is created. Informs observers.
94  virtual void ObjectAdded(const dbus::ObjectPath& object_path,
95                           const std::string& interface_name) OVERRIDE {
96    FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_,
97                      InputAdded(object_path));
98  }
99
100  // Called by dbus::ObjectManager when an object with the input interface
101  // is removed. Informs observers.
102  virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
103                             const std::string& interface_name) OVERRIDE {
104    FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_,
105                      InputRemoved(object_path));
106  }
107
108  // Called by BluetoothPropertySet when a property value is changed,
109  // either by result of a signal or response to a GetAll() or Get()
110  // call. Informs observers.
111  void OnPropertyChanged(const dbus::ObjectPath& object_path,
112                         const std::string& property_name) {
113    FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_,
114                      InputPropertyChanged(object_path, property_name));
115  }
116
117  dbus::Bus* bus_;
118  dbus::ObjectManager* object_manager_;
119
120  // List of observers interested in event notifications from us.
121  ObserverList<BluetoothInputClient::Observer> observers_;
122
123  // Weak pointer factory for generating 'this' pointers that might live longer
124  // than we do.
125  // Note: This should remain the last member so it'll be destroyed and
126  // invalidate its weak pointers before any other members are destroyed.
127  base::WeakPtrFactory<BluetoothInputClientImpl> weak_ptr_factory_;
128
129  DISALLOW_COPY_AND_ASSIGN(BluetoothInputClientImpl);
130};
131
132BluetoothInputClient::BluetoothInputClient() {
133}
134
135BluetoothInputClient::~BluetoothInputClient() {
136}
137
138BluetoothInputClient* BluetoothInputClient::Create(
139    DBusClientImplementationType type,
140    dbus::Bus* bus) {
141  if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
142    return new BluetoothInputClientImpl(bus);
143  DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
144  return new FakeBluetoothInputClient();
145}
146
147}  // namespace chromeos
148