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/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"
15 #include "dbus/message.h"
16 #include "dbus/object_manager.h"
17 #include "dbus/object_proxy.h"
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
{
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
;
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
) {
94 observers_
.AddObserver(observer
);
97 void PrivetDaemonManagerClientImpl::RemoveObserver(Observer
* 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
));
108 base::ThreadTaskRunnerHandle::Get()->PostTask(
110 base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod
,
111 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
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()));
147 NOTREACHED() << "Unhandled interface name " << interface_name
;
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());
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());
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
);
186 void PrivetDaemonManagerClient::PairingInfo::Clear() {
192 bool PrivetDaemonManagerClient::PairingInfoProperty::PopValueFromReader(
193 dbus::MessageReader
* reader
) {
194 dbus::MessageReader
variant_reader(nullptr);
195 dbus::MessageReader
array_reader(nullptr);
197 if (!reader
->PopVariant(&variant_reader
) ||
198 !variant_reader
.PopArray(&array_reader
)) {
201 while (array_reader
.HasMoreData()) {
202 dbus::MessageReader
dict_entry_reader(nullptr);
203 if (!array_reader
.PopDictEntry(&dict_entry_reader
))
206 if (!dict_entry_reader
.PopString(&key
))
209 dbus::MessageReader
field_reader(nullptr);
210 if (!dict_entry_reader
.PopVariant(&field_reader
))
213 if (field_reader
.GetDataSignature() == "s") {
214 std::string string_value
;
215 if (!field_reader
.PopString(&string_value
))
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;
225 if (!field_reader
.PopArrayOfBytes(&bytes
, &length
))
227 if (key
== kPairingInfoCodeProperty
)
228 value_
.set_code(bytes
, length
);
234 PrivetDaemonManagerClient::PairingInfo::PairingInfo() {
237 PrivetDaemonManagerClient::PairingInfo::~PairingInfo() {
240 void PrivetDaemonManagerClient::PairingInfoProperty::AppendSetValueToWriter(
241 dbus::MessageWriter
* writer
) {
245 void PrivetDaemonManagerClient::PairingInfoProperty::
246 ReplaceValueWithSetValue() {
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() {
275 PrivetDaemonManagerClient
* PrivetDaemonManagerClient::Create() {
276 return new PrivetDaemonManagerClientImpl();
279 } // namespace chromeos