Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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. | |
| 4 | |
| 5 #include "chromeos/dbus/privet_daemon_manager_client.h" | |
| 6 | |
| 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" | |
| 16 #include "dbus/values_util.h" | |
| 17 | |
| 18 namespace dbus { | |
|
hashimoto
2015/03/18 05:52:50
Generally speaking, you shouldn't add arbitrary st
dtapuska
2015/03/18 14:28:54
I won't use Property template; but use the Propert
| |
| 19 | |
| 20 template <> | |
| 21 bool Property< | |
| 22 std::map<std::string, | |
| 23 chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>:: | |
| 24 PopValueFromReader(MessageReader* reader); | |
| 25 | |
| 26 template <> | |
| 27 void Property< | |
| 28 std::map<std::string, | |
| 29 chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>:: | |
| 30 AppendSetValueToWriter(MessageWriter* writer); | |
| 31 | |
| 32 template class Property< | |
| 33 std::map<std::string, | |
| 34 chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>; | |
| 35 | |
| 36 template <> | |
| 37 bool Property< | |
| 38 std::map<std::string, | |
| 39 chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>:: | |
| 40 PopValueFromReader(MessageReader* reader) { | |
| 41 MessageReader variant_reader(NULL); | |
| 42 MessageReader array_reader(NULL); | |
| 43 if (!reader->PopVariant(&variant_reader) || | |
| 44 !variant_reader.PopArray(&array_reader)) { | |
| 45 return false; | |
| 46 } | |
| 47 value_.clear(); | |
| 48 while (array_reader.HasMoreData()) { | |
| 49 MessageReader dict_entry_reader(NULL); | |
| 50 if (!array_reader.PopDictEntry(&dict_entry_reader)) | |
| 51 return false; | |
| 52 std::string key; | |
| 53 if (!dict_entry_reader.PopString(&key)) | |
| 54 return false; | |
| 55 | |
| 56 MessageReader field_reader(NULL); | |
| 57 if (!dict_entry_reader.PopVariant(&field_reader)) | |
| 58 return false; | |
| 59 | |
| 60 chromeos::PrivetDaemonManagerClient::PairingInfoVariant value; | |
| 61 if (field_reader.GetDataSignature() == "s") { | |
| 62 if (!field_reader.PopString(&value.string)) | |
| 63 return false; | |
| 64 value.type = | |
| 65 chromeos::PrivetDaemonManagerClient::PairingInfoVariant::Type::STRING; | |
| 66 } else if (field_reader.GetDataSignature() == "ay") { | |
| 67 const uint8* bytes = NULL; | |
| 68 size_t length = 0; | |
| 69 if (!field_reader.PopArrayOfBytes(&bytes, &length)) | |
| 70 return false; | |
| 71 value.blob.assign(bytes, bytes + length); | |
| 72 value.type = | |
| 73 chromeos::PrivetDaemonManagerClient::PairingInfoVariant::Type::BLOB; | |
| 74 } | |
| 75 | |
| 76 value_[key] = value; | |
| 77 } | |
| 78 return true; | |
| 79 } | |
|
satorux1
2015/03/17 17:39:11
This and the next function seem to be complex. how
dtapuska
2015/03/18 14:28:53
Done.
| |
| 80 | |
| 81 template <> | |
| 82 void Property< | |
| 83 std::map<std::string, | |
| 84 chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>:: | |
| 85 AppendSetValueToWriter(MessageWriter* writer) { | |
| 86 MessageWriter variant_writer(NULL); | |
| 87 MessageWriter dict_writer(NULL); | |
| 88 writer->OpenVariant("a{sv}", &variant_writer); | |
| 89 variant_writer.OpenArray("{sv}", &dict_writer); | |
| 90 for (const auto& pair : set_value_) { | |
| 91 dbus::MessageWriter entry_writer(NULL); | |
| 92 dict_writer.OpenDictEntry(&entry_writer); | |
| 93 entry_writer.AppendString(pair.first); | |
| 94 switch (pair.second.type) { | |
| 95 case chromeos::PrivetDaemonManagerClient::PairingInfoVariant::Type:: | |
| 96 STRING: | |
| 97 entry_writer.AppendVariantOfString(pair.second.string); | |
| 98 break; | |
| 99 case chromeos::PrivetDaemonManagerClient::PairingInfoVariant::Type:: | |
| 100 BLOB: { | |
| 101 MessageWriter array_writer(NULL); | |
| 102 entry_writer.OpenVariant("ay", &array_writer); | |
| 103 array_writer.AppendArrayOfBytes(pair.second.blob.data(), | |
| 104 pair.second.blob.size()); | |
| 105 entry_writer.CloseContainer(&array_writer); | |
| 106 } | |
| 107 } | |
| 108 dict_writer.CloseContainer(&entry_writer); | |
| 109 } | |
| 110 variant_writer.CloseContainer(&dict_writer); | |
| 111 writer->CloseContainer(&variant_writer); | |
| 112 } | |
|
satorux1
2015/03/17 17:39:11
nit: blank line here.
dtapuska
2015/03/18 14:28:54
Done.
| |
| 113 } // namespace dbus | |
| 114 | |
| 115 namespace chromeos { | |
| 116 | |
| 117 // TODO(benchan): Move these constants to system_api. | |
| 118 namespace privetd { | |
| 119 const char kPrivetdServiceName[] = "org.chromium.privetd"; | |
|
hashimoto
2015/03/18 05:52:50
It's better to put these constants in the anonymou
dtapuska
2015/03/18 14:28:54
Done.
| |
| 120 const char kPrivetdServicePath[] = "/org/chromium/privetd"; | |
| 121 const char kPrivetdManagerPath[] = "/org/chromium/privetd/Manager"; | |
| 122 const char kManagerInterfaceName[] = "org.chromium.privetd.Manager"; | |
| 123 const char kSetDescriptionMethod[] = "SetDescription"; | |
| 124 const char kGCDBootstrapStateProperty[] = "GCDBootstrapState"; | |
| 125 const char kWiFiBootstrapStateProperty[] = "WiFiBootstrapState"; | |
| 126 const char kPairingInfoProperty[] = "PairingInfo"; | |
| 127 const char kDescriptionProperty[] = "Description"; | |
| 128 const char kNameProperty[] = "Name"; | |
| 129 | |
| 130 } // namespace privetd | |
| 131 | |
| 132 namespace { | |
| 133 | |
| 134 // The PrivetDaemonManagerClient implementation used in production. | |
| 135 class PrivetDaemonManagerClientImpl : public PrivetDaemonManagerClient, | |
| 136 public dbus::ObjectManager::Interface { | |
| 137 public: | |
| 138 PrivetDaemonManagerClientImpl(); | |
| 139 ~PrivetDaemonManagerClientImpl() override; | |
| 140 | |
| 141 // PrivetDaemonManagerClient overrides. | |
| 142 void AddObserver(Observer* observer) override; | |
| 143 void RemoveObserver(Observer* observer) override; | |
| 144 void SetDescription(const std::string& description, | |
| 145 const VoidDBusMethodCallback& callback) override; | |
| 146 const ManagerProperties* GetManagerProperties() override; | |
| 147 | |
| 148 // DBusClient overrides. | |
| 149 void Init(dbus::Bus* bus) override; | |
| 150 | |
| 151 // dbus::ObjectManager::Interface overrides. | |
| 152 dbus::PropertySet* CreateProperties( | |
| 153 dbus::ObjectProxy* object_proxy, | |
| 154 const dbus::ObjectPath& object_path, | |
| 155 const std::string& interface_name) override; | |
| 156 void ObjectAdded(const dbus::ObjectPath& object_path, | |
| 157 const std::string& interface_name) override; | |
| 158 void ObjectRemoved(const dbus::ObjectPath& object_path, | |
| 159 const std::string& interface_name) override; | |
| 160 | |
| 161 private: | |
| 162 // Called by dbus::PropertySet when a property value is changed, | |
| 163 // either by result of a signal or response to a GetAll() or Get() | |
| 164 // call. Informs observers. | |
| 165 void OnManagerPropertyChanged(const std::string& property_name); | |
| 166 void OnVoidDBusMethod(const VoidDBusMethodCallback& callback, | |
| 167 dbus::Response* response); | |
| 168 | |
| 169 // List of observers interested in event notifications from us. | |
| 170 ObserverList<Observer> observers_; | |
| 171 dbus::ObjectManager* object_manager_; | |
| 172 base::WeakPtrFactory<PrivetDaemonManagerClientImpl> weak_ptr_factory_; | |
| 173 | |
| 174 DISALLOW_COPY_AND_ASSIGN(PrivetDaemonManagerClientImpl); | |
| 175 }; | |
| 176 | |
| 177 PrivetDaemonManagerClientImpl::PrivetDaemonManagerClientImpl() | |
| 178 : object_manager_(nullptr), weak_ptr_factory_(this) { | |
| 179 } | |
| 180 | |
| 181 PrivetDaemonManagerClientImpl::~PrivetDaemonManagerClientImpl() { | |
| 182 if (object_manager_) { | |
| 183 object_manager_->UnregisterInterface(privetd::kManagerInterfaceName); | |
| 184 } | |
| 185 } | |
| 186 | |
| 187 void PrivetDaemonManagerClientImpl::AddObserver(Observer* observer) { | |
| 188 DCHECK(observer); | |
| 189 observers_.AddObserver(observer); | |
| 190 } | |
| 191 | |
| 192 void PrivetDaemonManagerClientImpl::RemoveObserver(Observer* observer) { | |
| 193 DCHECK(observer); | |
| 194 observers_.RemoveObserver(observer); | |
| 195 } | |
| 196 | |
| 197 void PrivetDaemonManagerClientImpl::SetDescription( | |
| 198 const std::string& description, | |
| 199 const VoidDBusMethodCallback& callback) { | |
| 200 dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy( | |
| 201 dbus::ObjectPath(privetd::kPrivetdManagerPath)); | |
| 202 if (!object_proxy) { | |
| 203 base::MessageLoop::current()->PostTask( | |
| 204 FROM_HERE, | |
| 205 base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod, | |
| 206 weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); | |
| 207 return; | |
| 208 } | |
| 209 | |
| 210 dbus::MethodCall method_call(privetd::kManagerInterfaceName, | |
| 211 privetd::kSetDescriptionMethod); | |
| 212 dbus::MessageWriter writer(&method_call); | |
| 213 writer.AppendString(description); | |
| 214 object_proxy->CallMethod( | |
| 215 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 216 base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod, | |
| 217 weak_ptr_factory_.GetWeakPtr(), callback)); | |
| 218 } | |
| 219 | |
| 220 const PrivetDaemonManagerClient::ManagerProperties* | |
| 221 PrivetDaemonManagerClientImpl::GetManagerProperties() { | |
| 222 return static_cast<ManagerProperties*>(object_manager_->GetProperties( | |
| 223 dbus::ObjectPath(privetd::kPrivetdManagerPath), | |
| 224 privetd::kManagerInterfaceName)); | |
| 225 } | |
| 226 | |
| 227 void PrivetDaemonManagerClientImpl::Init(dbus::Bus* bus) { | |
| 228 object_manager_ = | |
| 229 bus->GetObjectManager(privetd::kPrivetdServiceName, | |
| 230 dbus::ObjectPath(privetd::kPrivetdServicePath)); | |
| 231 object_manager_->RegisterInterface(privetd::kManagerInterfaceName, this); | |
| 232 } | |
| 233 | |
| 234 dbus::PropertySet* PrivetDaemonManagerClientImpl::CreateProperties( | |
| 235 dbus::ObjectProxy* object_proxy, | |
| 236 const dbus::ObjectPath& object_path, | |
| 237 const std::string& interface_name) { | |
| 238 dbus::PropertySet* properties = nullptr; | |
| 239 if (interface_name == privetd::kManagerInterfaceName) { | |
| 240 properties = new ManagerProperties( | |
| 241 object_proxy, interface_name, | |
| 242 base::Bind(&PrivetDaemonManagerClientImpl::OnManagerPropertyChanged, | |
| 243 weak_ptr_factory_.GetWeakPtr())); | |
| 244 } else { | |
| 245 NOTREACHED() << "Unhandled interface name " << interface_name; | |
| 246 } | |
| 247 return properties; | |
| 248 } | |
| 249 | |
| 250 void PrivetDaemonManagerClientImpl::ObjectAdded( | |
| 251 const dbus::ObjectPath& object_path, | |
| 252 const std::string& interface_name) { | |
| 253 if (interface_name == privetd::kManagerInterfaceName) { | |
| 254 FOR_EACH_OBSERVER(Observer, observers_, ManagerAdded()); | |
| 255 } else { | |
| 256 NOTREACHED() << "Unhandled interface name " << interface_name; | |
| 257 } | |
| 258 } | |
| 259 | |
| 260 void PrivetDaemonManagerClientImpl::ObjectRemoved( | |
| 261 const dbus::ObjectPath& object_path, | |
| 262 const std::string& interface_name) { | |
| 263 if (interface_name == privetd::kManagerInterfaceName) { | |
| 264 FOR_EACH_OBSERVER(Observer, observers_, ManagerRemoved()); | |
| 265 } else { | |
| 266 NOTREACHED() << "Unhandled interface name " << interface_name; | |
| 267 } | |
| 268 } | |
| 269 | |
| 270 void PrivetDaemonManagerClientImpl::OnManagerPropertyChanged( | |
| 271 const std::string& property_name) { | |
| 272 FOR_EACH_OBSERVER(Observer, observers_, | |
| 273 ManagerPropertyChanged(property_name)); | |
| 274 } | |
| 275 | |
| 276 void PrivetDaemonManagerClientImpl::OnVoidDBusMethod( | |
| 277 const VoidDBusMethodCallback& callback, | |
| 278 dbus::Response* response) { | |
| 279 callback.Run(response ? DBUS_METHOD_CALL_SUCCESS : DBUS_METHOD_CALL_FAILURE); | |
| 280 } | |
| 281 | |
| 282 } // namespace | |
| 283 | |
| 284 PrivetDaemonManagerClient::ManagerProperties::ManagerProperties( | |
| 285 dbus::ObjectProxy* object_proxy, | |
| 286 const std::string& interface_name, | |
| 287 const PropertyChangedCallback& callback) | |
| 288 : dbus::PropertySet(object_proxy, interface_name, callback) { | |
| 289 RegisterProperty(privetd::kWiFiBootstrapStateProperty, | |
| 290 &wifi_bootstrap_state_); | |
| 291 RegisterProperty(privetd::kGCDBootstrapStateProperty, &gcd_bootstrap_state_); | |
| 292 RegisterProperty(privetd::kPairingInfoProperty, &pairing_info_); | |
| 293 RegisterProperty(privetd::kDescriptionProperty, &description_); | |
| 294 RegisterProperty(privetd::kNameProperty, &name_); | |
| 295 } | |
| 296 | |
| 297 PrivetDaemonManagerClient::ManagerProperties::~ManagerProperties() { | |
| 298 } | |
| 299 | |
| 300 PrivetDaemonManagerClient::Observer::~Observer() { | |
|
hashimoto
2015/03/18 05:52:50
If you want to provide empty implementation for in
dtapuska
2015/03/18 14:28:54
Empty implementations should not be done in the he
| |
| 301 } | |
| 302 | |
| 303 void PrivetDaemonManagerClient::Observer::ManagerAdded() { | |
| 304 } | |
| 305 | |
| 306 void PrivetDaemonManagerClient::Observer::ManagerRemoved() { | |
| 307 } | |
| 308 | |
| 309 void PrivetDaemonManagerClient::Observer::ManagerPropertyChanged( | |
| 310 const std::string& property_name) { | |
| 311 } | |
| 312 | |
| 313 PrivetDaemonManagerClient::PrivetDaemonManagerClient() { | |
| 314 } | |
| 315 | |
| 316 PrivetDaemonManagerClient::~PrivetDaemonManagerClient() { | |
| 317 } | |
| 318 | |
| 319 // static | |
| 320 PrivetDaemonManagerClient* PrivetDaemonManagerClient::Create() { | |
| 321 return new PrivetDaemonManagerClientImpl(); | |
| 322 } | |
| 323 | |
| 324 } // namespace chromeos | |
| OLD | NEW |