Adding Peter Thatcher to the owners file.
[chromium-blink-merge.git] / chromeos / dbus / privet_daemon_manager_client.cc
blob4a39ebd048c9598020d56f71f5903d9dc91c5872
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/logging.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/observer_list.h"
12 #include "dbus/bus.h"
13 #include "dbus/message.h"
14 #include "dbus/object_manager.h"
15 #include "dbus/object_proxy.h"
17 namespace chromeos {
19 namespace {
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 {
40 public:
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;
64 private:
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) {
91 DCHECK(observer);
92 observers_.AddObserver(observer);
95 void PrivetDaemonManagerClientImpl::RemoveObserver(Observer* observer) {
96 DCHECK(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));
105 if (!object_proxy) {
106 base::MessageLoop::current()->PostTask(
107 FROM_HERE,
108 base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod,
109 weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
110 return;
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()));
144 } else {
145 NOTREACHED() << "Unhandled interface name " << interface_name;
147 return properties;
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());
155 } else {
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());
165 } else {
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);
182 } // namespace
184 void PrivetDaemonManagerClient::PairingInfo::Clear() {
185 code_.clear();
186 mode_.clear();
187 session_id_.clear();
190 bool PrivetDaemonManagerClient::PairingInfoProperty::PopValueFromReader(
191 dbus::MessageReader* reader) {
192 dbus::MessageReader variant_reader(nullptr);
193 dbus::MessageReader array_reader(nullptr);
194 value_.Clear();
195 if (!reader->PopVariant(&variant_reader) ||
196 !variant_reader.PopArray(&array_reader)) {
197 return false;
199 while (array_reader.HasMoreData()) {
200 dbus::MessageReader dict_entry_reader(nullptr);
201 if (!array_reader.PopDictEntry(&dict_entry_reader))
202 return false;
203 std::string key;
204 if (!dict_entry_reader.PopString(&key))
205 return false;
207 dbus::MessageReader field_reader(nullptr);
208 if (!dict_entry_reader.PopVariant(&field_reader))
209 return false;
211 if (field_reader.GetDataSignature() == "s") {
212 std::string string_value;
213 if (!field_reader.PopString(&string_value))
214 return false;
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;
222 size_t length = 0;
223 if (!field_reader.PopArrayOfBytes(&bytes, &length))
224 return false;
225 if (key == kPairingInfoCodeProperty)
226 value_.set_code(bytes, length);
229 return true;
232 PrivetDaemonManagerClient::PairingInfo::PairingInfo() {
235 PrivetDaemonManagerClient::PairingInfo::~PairingInfo() {
238 void PrivetDaemonManagerClient::PairingInfoProperty::AppendSetValueToWriter(
239 dbus::MessageWriter* writer) {
240 NOTIMPLEMENTED();
243 void PrivetDaemonManagerClient::PairingInfoProperty::
244 ReplaceValueWithSetValue() {
245 NOTIMPLEMENTED();
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() {
272 // static
273 PrivetDaemonManagerClient* PrivetDaemonManagerClient::Create() {
274 return new PrivetDaemonManagerClientImpl();
277 } // namespace chromeos