Implement finding BLE connections in chrome://proximity-auth.
[chromium-blink-merge.git] / chromeos / dbus / privet_daemon_manager_client.cc
blobde61cc889d90e382b0dfbad9124c954c88c314dc
1 // Copyright 2015 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.
5 #include "chromeos/dbus/privet_daemon_manager_client.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/observer_list.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "dbus/bus.h"
15 #include "dbus/message.h"
16 #include "dbus/object_manager.h"
17 #include "dbus/object_proxy.h"
19 namespace chromeos {
21 namespace {
23 // TODO(benchan): Move these constants to system_api.
24 const char kManagerInterfaceName[] = "org.chromium.privetd.Manager";
25 const char kPrivetdManagerPath[] = "/org/chromium/privetd/Manager";
26 const char kPrivetdServiceName[] = "org.chromium.privetd";
27 const char kPrivetdServicePath[] = "/org/chromium/privetd";
28 const char kSetDescriptionMethod[] = "SetDescription";
30 const char kDescriptionProperty[] = "Description";
31 const char kGCDBootstrapStateProperty[] = "GCDBootstrapState";
32 const char kNameProperty[] = "Name";
33 const char kPairingInfoCodeProperty[] = "code";
34 const char kPairingInfoModeProperty[] = "mode";
35 const char kPairingInfoProperty[] = "PairingInfo";
36 const char kPairingInfoSessionIdProperty[] = "sessionId";
37 const char kWiFiBootstrapStateProperty[] = "WiFiBootstrapState";
39 // The PrivetDaemonManagerClient implementation used in production.
40 class PrivetDaemonManagerClientImpl : public PrivetDaemonManagerClient,
41 public dbus::ObjectManager::Interface {
42 public:
43 PrivetDaemonManagerClientImpl();
44 ~PrivetDaemonManagerClientImpl() override;
46 // PrivetDaemonManagerClient overrides.
47 void AddObserver(Observer* observer) override;
48 void RemoveObserver(Observer* observer) override;
49 void SetDescription(const std::string& description,
50 const VoidDBusMethodCallback& callback) override;
51 const Properties* GetProperties() override;
53 // DBusClient overrides.
54 void Init(dbus::Bus* bus) override;
56 // dbus::ObjectManager::Interface overrides.
57 dbus::PropertySet* CreateProperties(
58 dbus::ObjectProxy* object_proxy,
59 const dbus::ObjectPath& object_path,
60 const std::string& interface_name) override;
61 void ObjectAdded(const dbus::ObjectPath& object_path,
62 const std::string& interface_name) override;
63 void ObjectRemoved(const dbus::ObjectPath& object_path,
64 const std::string& interface_name) override;
66 private:
67 // Called by dbus::PropertySet when a property value is changed,
68 // either by result of a signal or response to a GetAll() or Get()
69 // call. Informs observers.
70 void OnManagerPropertyChanged(const std::string& property_name);
71 void OnVoidDBusMethod(const VoidDBusMethodCallback& callback,
72 dbus::Response* response);
74 // List of observers interested in event notifications from us.
75 base::ObserverList<Observer> observers_;
76 dbus::ObjectManager* object_manager_;
77 base::WeakPtrFactory<PrivetDaemonManagerClientImpl> weak_ptr_factory_;
79 DISALLOW_COPY_AND_ASSIGN(PrivetDaemonManagerClientImpl);
82 PrivetDaemonManagerClientImpl::PrivetDaemonManagerClientImpl()
83 : object_manager_(nullptr), weak_ptr_factory_(this) {
86 PrivetDaemonManagerClientImpl::~PrivetDaemonManagerClientImpl() {
87 if (object_manager_) {
88 object_manager_->UnregisterInterface(kManagerInterfaceName);
92 void PrivetDaemonManagerClientImpl::AddObserver(Observer* observer) {
93 DCHECK(observer);
94 observers_.AddObserver(observer);
97 void PrivetDaemonManagerClientImpl::RemoveObserver(Observer* observer) {
98 DCHECK(observer);
99 observers_.RemoveObserver(observer);
102 void PrivetDaemonManagerClientImpl::SetDescription(
103 const std::string& description,
104 const VoidDBusMethodCallback& callback) {
105 dbus::ObjectProxy* object_proxy =
106 object_manager_->GetObjectProxy(dbus::ObjectPath(kPrivetdManagerPath));
107 if (!object_proxy) {
108 base::ThreadTaskRunnerHandle::Get()->PostTask(
109 FROM_HERE,
110 base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod,
111 weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
112 return;
115 dbus::MethodCall method_call(kManagerInterfaceName, kSetDescriptionMethod);
116 dbus::MessageWriter writer(&method_call);
117 writer.AppendString(description);
118 object_proxy->CallMethod(
119 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
120 base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod,
121 weak_ptr_factory_.GetWeakPtr(), callback));
124 const PrivetDaemonManagerClient::Properties*
125 PrivetDaemonManagerClientImpl::GetProperties() {
126 return static_cast<Properties*>(object_manager_->GetProperties(
127 dbus::ObjectPath(kPrivetdManagerPath), kManagerInterfaceName));
130 void PrivetDaemonManagerClientImpl::Init(dbus::Bus* bus) {
131 object_manager_ = bus->GetObjectManager(
132 kPrivetdServiceName, dbus::ObjectPath(kPrivetdServicePath));
133 object_manager_->RegisterInterface(kManagerInterfaceName, this);
136 dbus::PropertySet* PrivetDaemonManagerClientImpl::CreateProperties(
137 dbus::ObjectProxy* object_proxy,
138 const dbus::ObjectPath& object_path,
139 const std::string& interface_name) {
140 dbus::PropertySet* properties = nullptr;
141 if (interface_name == kManagerInterfaceName) {
142 properties = new Properties(
143 object_proxy, interface_name,
144 base::Bind(&PrivetDaemonManagerClientImpl::OnManagerPropertyChanged,
145 weak_ptr_factory_.GetWeakPtr()));
146 } else {
147 NOTREACHED() << "Unhandled interface name " << interface_name;
149 return properties;
152 void PrivetDaemonManagerClientImpl::ObjectAdded(
153 const dbus::ObjectPath& object_path,
154 const std::string& interface_name) {
155 if (interface_name == kManagerInterfaceName) {
156 FOR_EACH_OBSERVER(Observer, observers_, ManagerAdded());
157 } else {
158 NOTREACHED() << "Unhandled interface name " << interface_name;
162 void PrivetDaemonManagerClientImpl::ObjectRemoved(
163 const dbus::ObjectPath& object_path,
164 const std::string& interface_name) {
165 if (interface_name == kManagerInterfaceName) {
166 FOR_EACH_OBSERVER(Observer, observers_, ManagerRemoved());
167 } else {
168 NOTREACHED() << "Unhandled interface name " << interface_name;
172 void PrivetDaemonManagerClientImpl::OnManagerPropertyChanged(
173 const std::string& property_name) {
174 FOR_EACH_OBSERVER(Observer, observers_,
175 ManagerPropertyChanged(property_name));
178 void PrivetDaemonManagerClientImpl::OnVoidDBusMethod(
179 const VoidDBusMethodCallback& callback,
180 dbus::Response* response) {
181 callback.Run(response ? DBUS_METHOD_CALL_SUCCESS : DBUS_METHOD_CALL_FAILURE);
184 } // namespace
186 void PrivetDaemonManagerClient::PairingInfo::Clear() {
187 code_.clear();
188 mode_.clear();
189 session_id_.clear();
192 bool PrivetDaemonManagerClient::PairingInfoProperty::PopValueFromReader(
193 dbus::MessageReader* reader) {
194 dbus::MessageReader variant_reader(nullptr);
195 dbus::MessageReader array_reader(nullptr);
196 value_.Clear();
197 if (!reader->PopVariant(&variant_reader) ||
198 !variant_reader.PopArray(&array_reader)) {
199 return false;
201 while (array_reader.HasMoreData()) {
202 dbus::MessageReader dict_entry_reader(nullptr);
203 if (!array_reader.PopDictEntry(&dict_entry_reader))
204 return false;
205 std::string key;
206 if (!dict_entry_reader.PopString(&key))
207 return false;
209 dbus::MessageReader field_reader(nullptr);
210 if (!dict_entry_reader.PopVariant(&field_reader))
211 return false;
213 if (field_reader.GetDataSignature() == "s") {
214 std::string string_value;
215 if (!field_reader.PopString(&string_value))
216 return false;
217 if (key == kPairingInfoSessionIdProperty) {
218 value_.set_session_id(string_value);
219 } else if (key == kPairingInfoModeProperty) {
220 value_.set_mode(string_value);
222 } else if (field_reader.GetDataSignature() == "ay") {
223 const uint8* bytes = nullptr;
224 size_t length = 0;
225 if (!field_reader.PopArrayOfBytes(&bytes, &length))
226 return false;
227 if (key == kPairingInfoCodeProperty)
228 value_.set_code(bytes, length);
231 return true;
234 PrivetDaemonManagerClient::PairingInfo::PairingInfo() {
237 PrivetDaemonManagerClient::PairingInfo::~PairingInfo() {
240 void PrivetDaemonManagerClient::PairingInfoProperty::AppendSetValueToWriter(
241 dbus::MessageWriter* writer) {
242 NOTIMPLEMENTED();
245 void PrivetDaemonManagerClient::PairingInfoProperty::
246 ReplaceValueWithSetValue() {
247 NOTIMPLEMENTED();
250 PrivetDaemonManagerClient::Properties::Properties(
251 dbus::ObjectProxy* object_proxy,
252 const std::string& interface_name,
253 const PropertyChangedCallback& callback)
254 : dbus::PropertySet(object_proxy, interface_name, callback) {
255 RegisterProperty(kWiFiBootstrapStateProperty, &wifi_bootstrap_state_);
256 RegisterProperty(kGCDBootstrapStateProperty, &gcd_bootstrap_state_);
257 RegisterProperty(kPairingInfoProperty, &pairing_info_);
258 RegisterProperty(kDescriptionProperty, &description_);
259 RegisterProperty(kNameProperty, &name_);
262 PrivetDaemonManagerClient::Properties::~Properties() {
265 PrivetDaemonManagerClient::Observer::~Observer() {
268 PrivetDaemonManagerClient::PrivetDaemonManagerClient() {
271 PrivetDaemonManagerClient::~PrivetDaemonManagerClient() {
274 // static
275 PrivetDaemonManagerClient* PrivetDaemonManagerClient::Create() {
276 return new PrivetDaemonManagerClientImpl();
279 } // namespace chromeos