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_input_client.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <map>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stl_util.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/bus.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/message.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_manager.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_path.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "dbus/object_proxy.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace chromeos {
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothInputClient::Properties::Properties(
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dbus::ObjectProxy* object_proxy,
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& interface_name,
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const PropertyChangedCallback& callback)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : dbus::PropertySet(object_proxy, interface_name, callback) {
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RegisterProperty(bluetooth_input::kReconnectModeProperty, &reconnect_mode);
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothInputClient::Properties::~Properties() {
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// The BluetoothInputClient implementation used in production.
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BluetoothInputClientImpl
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public BluetoothInputClient,
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      public dbus::ObjectManager::Interface {
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BluetoothInputClientImpl() : object_manager_(NULL), weak_ptr_factory_(this) {}
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~BluetoothInputClientImpl() {
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    object_manager_->UnregisterInterface(
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        bluetooth_input::kBluetoothInputInterface);
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // BluetoothInputClient override.
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void AddObserver(BluetoothInputClient::Observer* observer)
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      OVERRIDE {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(observer);
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observers_.AddObserver(observer);
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // BluetoothInputClient override.
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void RemoveObserver(BluetoothInputClient::Observer* observer)
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      OVERRIDE {
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(observer);
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observers_.RemoveObserver(observer);
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // dbus::ObjectManager::Interface override.
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual dbus::PropertySet* CreateProperties(
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dbus::ObjectProxy* object_proxy,
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const dbus::ObjectPath& object_path,
62b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      const std::string& interface_name) OVERRIDE {
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Properties* properties = new Properties(
64b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        object_proxy,
65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        interface_name,
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base::Bind(&BluetoothInputClientImpl::OnPropertyChanged,
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr(),
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   object_path));
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return static_cast<dbus::PropertySet*>(properties);
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // BluetoothInputClient override.
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      OVERRIDE {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return static_cast<Properties*>(
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        object_manager_->GetProperties(
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            object_path,
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            bluetooth_input::kBluetoothInputInterface));
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) protected:
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void Init(dbus::Bus* bus) OVERRIDE {
83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    object_manager_ = bus->GetObjectManager(
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        bluetooth_object_manager::kBluetoothObjectManagerServiceName,
85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        dbus::ObjectPath(
86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)            bluetooth_object_manager::kBluetoothObjectManagerServicePath));
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    object_manager_->RegisterInterface(
88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        bluetooth_input::kBluetoothInputInterface, this);
89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called by dbus::ObjectManager when an object with the input interface
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is created. Informs observers.
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void ObjectAdded(const dbus::ObjectPath& object_path,
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                           const std::string& interface_name) OVERRIDE {
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_,
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      InputAdded(object_path));
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called by dbus::ObjectManager when an object with the input interface
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // is removed. Informs observers.
102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void ObjectRemoved(const dbus::ObjectPath& object_path,
103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                             const std::string& interface_name) OVERRIDE {
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_,
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      InputRemoved(object_path));
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called by BluetoothPropertySet when a property value is changed,
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // either by result of a signal or response to a GetAll() or Get()
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // call. Informs observers.
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OnPropertyChanged(const dbus::ObjectPath& object_path,
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const std::string& property_name) {
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    FOR_EACH_OBSERVER(BluetoothInputClient::Observer, observers_,
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      InputPropertyChanged(object_path, property_name));
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dbus::ObjectManager* object_manager_;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // List of observers interested in event notifications from us.
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ObserverList<BluetoothInputClient::Observer> observers_;
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Weak pointer factory for generating 'this' pointers that might live longer
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // than we do.
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Note: This should remain the last member so it'll be destroyed and
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // invalidate its weak pointers before any other members are destroyed.
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::WeakPtrFactory<BluetoothInputClientImpl> weak_ptr_factory_;
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BluetoothInputClientImpl);
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothInputClient::BluetoothInputClient() {
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BluetoothInputClient::~BluetoothInputClient() {
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)BluetoothInputClient* BluetoothInputClient::Create() {
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return new BluetoothInputClientImpl();
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace chromeos
142