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"
8 #include "base/logging.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/observer_list.h"
13 #include "dbus/message.h"
14 #include "dbus/object_manager.h"
15 #include "dbus/object_proxy.h"
21 // TODO(benchan): Move these constants to system_api.
22 const char kManagerInterfaceName
[] = "org.chromium.privetd.Manager";
23 const char kPrivetdManagerPath
[] = "/org/chromium/privetd/Manager";
24 const char kPrivetdServiceName
[] = "org.chromium.privetd";
25 const char kPrivetdServicePath
[] = "/org/chromium/privetd";
26 const char kSetDescriptionMethod
[] = "SetDescription";
28 const char kDescriptionProperty
[] = "Description";
29 const char kGCDBootstrapStateProperty
[] = "GCDBootstrapState";
30 const char kNameProperty
[] = "Name";
31 const char kPairingInfoCodeProperty
[] = "code";
32 const char kPairingInfoModeProperty
[] = "mode";
33 const char kPairingInfoProperty
[] = "PairingInfo";
34 const char kPairingInfoSessionIdProperty
[] = "sessionId";
35 const char kWiFiBootstrapStateProperty
[] = "WiFiBootstrapState";
37 // The PrivetDaemonManagerClient implementation used in production.
38 class PrivetDaemonManagerClientImpl
: public PrivetDaemonManagerClient
,
39 public dbus::ObjectManager::Interface
{
41 PrivetDaemonManagerClientImpl();
42 ~PrivetDaemonManagerClientImpl() override
;
44 // PrivetDaemonManagerClient overrides.
45 void AddObserver(Observer
* observer
) override
;
46 void RemoveObserver(Observer
* observer
) override
;
47 void SetDescription(const std::string
& description
,
48 const VoidDBusMethodCallback
& callback
) override
;
49 const Properties
* GetProperties() override
;
51 // DBusClient overrides.
52 void Init(dbus::Bus
* bus
) override
;
54 // dbus::ObjectManager::Interface overrides.
55 dbus::PropertySet
* CreateProperties(
56 dbus::ObjectProxy
* object_proxy
,
57 const dbus::ObjectPath
& object_path
,
58 const std::string
& interface_name
) override
;
59 void ObjectAdded(const dbus::ObjectPath
& object_path
,
60 const std::string
& interface_name
) override
;
61 void ObjectRemoved(const dbus::ObjectPath
& object_path
,
62 const std::string
& interface_name
) override
;
65 // Called by dbus::PropertySet when a property value is changed,
66 // either by result of a signal or response to a GetAll() or Get()
67 // call. Informs observers.
68 void OnManagerPropertyChanged(const std::string
& property_name
);
69 void OnVoidDBusMethod(const VoidDBusMethodCallback
& callback
,
70 dbus::Response
* response
);
72 // List of observers interested in event notifications from us.
73 ObserverList
<Observer
> observers_
;
74 dbus::ObjectManager
* object_manager_
;
75 base::WeakPtrFactory
<PrivetDaemonManagerClientImpl
> weak_ptr_factory_
;
77 DISALLOW_COPY_AND_ASSIGN(PrivetDaemonManagerClientImpl
);
80 PrivetDaemonManagerClientImpl::PrivetDaemonManagerClientImpl()
81 : object_manager_(nullptr), weak_ptr_factory_(this) {
84 PrivetDaemonManagerClientImpl::~PrivetDaemonManagerClientImpl() {
85 if (object_manager_
) {
86 object_manager_
->UnregisterInterface(kManagerInterfaceName
);
90 void PrivetDaemonManagerClientImpl::AddObserver(Observer
* observer
) {
92 observers_
.AddObserver(observer
);
95 void PrivetDaemonManagerClientImpl::RemoveObserver(Observer
* observer
) {
97 observers_
.RemoveObserver(observer
);
100 void PrivetDaemonManagerClientImpl::SetDescription(
101 const std::string
& description
,
102 const VoidDBusMethodCallback
& callback
) {
103 dbus::ObjectProxy
* object_proxy
=
104 object_manager_
->GetObjectProxy(dbus::ObjectPath(kPrivetdManagerPath
));
106 base::MessageLoop::current()->PostTask(
108 base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod
,
109 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
113 dbus::MethodCall
method_call(kManagerInterfaceName
, kSetDescriptionMethod
);
114 dbus::MessageWriter
writer(&method_call
);
115 writer
.AppendString(description
);
116 object_proxy
->CallMethod(
117 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
118 base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod
,
119 weak_ptr_factory_
.GetWeakPtr(), callback
));
122 const PrivetDaemonManagerClient::Properties
*
123 PrivetDaemonManagerClientImpl::GetProperties() {
124 return static_cast<Properties
*>(object_manager_
->GetProperties(
125 dbus::ObjectPath(kPrivetdManagerPath
), kManagerInterfaceName
));
128 void PrivetDaemonManagerClientImpl::Init(dbus::Bus
* bus
) {
129 object_manager_
= bus
->GetObjectManager(
130 kPrivetdServiceName
, dbus::ObjectPath(kPrivetdServicePath
));
131 object_manager_
->RegisterInterface(kManagerInterfaceName
, this);
134 dbus::PropertySet
* PrivetDaemonManagerClientImpl::CreateProperties(
135 dbus::ObjectProxy
* object_proxy
,
136 const dbus::ObjectPath
& object_path
,
137 const std::string
& interface_name
) {
138 dbus::PropertySet
* properties
= nullptr;
139 if (interface_name
== kManagerInterfaceName
) {
140 properties
= new Properties(
141 object_proxy
, interface_name
,
142 base::Bind(&PrivetDaemonManagerClientImpl::OnManagerPropertyChanged
,
143 weak_ptr_factory_
.GetWeakPtr()));
145 NOTREACHED() << "Unhandled interface name " << interface_name
;
150 void PrivetDaemonManagerClientImpl::ObjectAdded(
151 const dbus::ObjectPath
& object_path
,
152 const std::string
& interface_name
) {
153 if (interface_name
== kManagerInterfaceName
) {
154 FOR_EACH_OBSERVER(Observer
, observers_
, ManagerAdded());
156 NOTREACHED() << "Unhandled interface name " << interface_name
;
160 void PrivetDaemonManagerClientImpl::ObjectRemoved(
161 const dbus::ObjectPath
& object_path
,
162 const std::string
& interface_name
) {
163 if (interface_name
== kManagerInterfaceName
) {
164 FOR_EACH_OBSERVER(Observer
, observers_
, ManagerRemoved());
166 NOTREACHED() << "Unhandled interface name " << interface_name
;
170 void PrivetDaemonManagerClientImpl::OnManagerPropertyChanged(
171 const std::string
& property_name
) {
172 FOR_EACH_OBSERVER(Observer
, observers_
,
173 ManagerPropertyChanged(property_name
));
176 void PrivetDaemonManagerClientImpl::OnVoidDBusMethod(
177 const VoidDBusMethodCallback
& callback
,
178 dbus::Response
* response
) {
179 callback
.Run(response
? DBUS_METHOD_CALL_SUCCESS
: DBUS_METHOD_CALL_FAILURE
);
184 void PrivetDaemonManagerClient::PairingInfo::Clear() {
190 bool PrivetDaemonManagerClient::PairingInfoProperty::PopValueFromReader(
191 dbus::MessageReader
* reader
) {
192 dbus::MessageReader
variant_reader(nullptr);
193 dbus::MessageReader
array_reader(nullptr);
195 if (!reader
->PopVariant(&variant_reader
) ||
196 !variant_reader
.PopArray(&array_reader
)) {
199 while (array_reader
.HasMoreData()) {
200 dbus::MessageReader
dict_entry_reader(nullptr);
201 if (!array_reader
.PopDictEntry(&dict_entry_reader
))
204 if (!dict_entry_reader
.PopString(&key
))
207 dbus::MessageReader
field_reader(nullptr);
208 if (!dict_entry_reader
.PopVariant(&field_reader
))
211 if (field_reader
.GetDataSignature() == "s") {
212 std::string string_value
;
213 if (!field_reader
.PopString(&string_value
))
215 if (key
== kPairingInfoSessionIdProperty
) {
216 value_
.set_session_id(string_value
);
217 } else if (key
== kPairingInfoModeProperty
) {
218 value_
.set_mode(string_value
);
220 } else if (field_reader
.GetDataSignature() == "ay") {
221 const uint8
* bytes
= nullptr;
223 if (!field_reader
.PopArrayOfBytes(&bytes
, &length
))
225 if (key
== kPairingInfoCodeProperty
)
226 value_
.set_code(bytes
, length
);
232 PrivetDaemonManagerClient::PairingInfo::PairingInfo() {
235 PrivetDaemonManagerClient::PairingInfo::~PairingInfo() {
238 void PrivetDaemonManagerClient::PairingInfoProperty::AppendSetValueToWriter(
239 dbus::MessageWriter
* writer
) {
243 void PrivetDaemonManagerClient::PairingInfoProperty::
244 ReplaceValueWithSetValue() {
248 PrivetDaemonManagerClient::Properties::Properties(
249 dbus::ObjectProxy
* object_proxy
,
250 const std::string
& interface_name
,
251 const PropertyChangedCallback
& callback
)
252 : dbus::PropertySet(object_proxy
, interface_name
, callback
) {
253 RegisterProperty(kWiFiBootstrapStateProperty
, &wifi_bootstrap_state_
);
254 RegisterProperty(kGCDBootstrapStateProperty
, &gcd_bootstrap_state_
);
255 RegisterProperty(kPairingInfoProperty
, &pairing_info_
);
256 RegisterProperty(kDescriptionProperty
, &description_
);
257 RegisterProperty(kNameProperty
, &name_
);
260 PrivetDaemonManagerClient::Properties::~Properties() {
263 PrivetDaemonManagerClient::Observer::~Observer() {
266 PrivetDaemonManagerClient::PrivetDaemonManagerClient() {
269 PrivetDaemonManagerClient::~PrivetDaemonManagerClient() {
273 PrivetDaemonManagerClient
* PrivetDaemonManagerClient::Create() {
274 return new PrivetDaemonManagerClientImpl();
277 } // namespace chromeos