Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3275)

Unified Diff: chromeos/dbus/privet_daemon_manager_client.cc

Issue 996013003: privetd: Expose dbus API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chromeos/dbus/privet_daemon_manager_client.cc
diff --git a/chromeos/dbus/privet_daemon_manager_client.cc b/chromeos/dbus/privet_daemon_manager_client.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f8bf1b0143f6be6b984de783a098639d5b2dd5cf
--- /dev/null
+++ b/chromeos/dbus/privet_daemon_manager_client.cc
@@ -0,0 +1,324 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/dbus/privet_daemon_manager_client.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/observer_list.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "dbus/object_manager.h"
+#include "dbus/object_proxy.h"
+#include "dbus/values_util.h"
+
+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
+
+template <>
+bool Property<
+ std::map<std::string,
+ chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>::
+ PopValueFromReader(MessageReader* reader);
+
+template <>
+void Property<
+ std::map<std::string,
+ chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>::
+ AppendSetValueToWriter(MessageWriter* writer);
+
+template class Property<
+ std::map<std::string,
+ chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>;
+
+template <>
+bool Property<
+ std::map<std::string,
+ chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>::
+ PopValueFromReader(MessageReader* reader) {
+ MessageReader variant_reader(NULL);
+ MessageReader array_reader(NULL);
+ if (!reader->PopVariant(&variant_reader) ||
+ !variant_reader.PopArray(&array_reader)) {
+ return false;
+ }
+ value_.clear();
+ while (array_reader.HasMoreData()) {
+ MessageReader dict_entry_reader(NULL);
+ if (!array_reader.PopDictEntry(&dict_entry_reader))
+ return false;
+ std::string key;
+ if (!dict_entry_reader.PopString(&key))
+ return false;
+
+ MessageReader field_reader(NULL);
+ if (!dict_entry_reader.PopVariant(&field_reader))
+ return false;
+
+ chromeos::PrivetDaemonManagerClient::PairingInfoVariant value;
+ if (field_reader.GetDataSignature() == "s") {
+ if (!field_reader.PopString(&value.string))
+ return false;
+ value.type =
+ chromeos::PrivetDaemonManagerClient::PairingInfoVariant::Type::STRING;
+ } else if (field_reader.GetDataSignature() == "ay") {
+ const uint8* bytes = NULL;
+ size_t length = 0;
+ if (!field_reader.PopArrayOfBytes(&bytes, &length))
+ return false;
+ value.blob.assign(bytes, bytes + length);
+ value.type =
+ chromeos::PrivetDaemonManagerClient::PairingInfoVariant::Type::BLOB;
+ }
+
+ value_[key] = value;
+ }
+ return true;
+}
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.
+
+template <>
+void Property<
+ std::map<std::string,
+ chromeos::PrivetDaemonManagerClient::PairingInfoVariant>>::
+ AppendSetValueToWriter(MessageWriter* writer) {
+ MessageWriter variant_writer(NULL);
+ MessageWriter dict_writer(NULL);
+ writer->OpenVariant("a{sv}", &variant_writer);
+ variant_writer.OpenArray("{sv}", &dict_writer);
+ for (const auto& pair : set_value_) {
+ dbus::MessageWriter entry_writer(NULL);
+ dict_writer.OpenDictEntry(&entry_writer);
+ entry_writer.AppendString(pair.first);
+ switch (pair.second.type) {
+ case chromeos::PrivetDaemonManagerClient::PairingInfoVariant::Type::
+ STRING:
+ entry_writer.AppendVariantOfString(pair.second.string);
+ break;
+ case chromeos::PrivetDaemonManagerClient::PairingInfoVariant::Type::
+ BLOB: {
+ MessageWriter array_writer(NULL);
+ entry_writer.OpenVariant("ay", &array_writer);
+ array_writer.AppendArrayOfBytes(pair.second.blob.data(),
+ pair.second.blob.size());
+ entry_writer.CloseContainer(&array_writer);
+ }
+ }
+ dict_writer.CloseContainer(&entry_writer);
+ }
+ variant_writer.CloseContainer(&dict_writer);
+ writer->CloseContainer(&variant_writer);
+}
satorux1 2015/03/17 17:39:11 nit: blank line here.
dtapuska 2015/03/18 14:28:54 Done.
+} // namespace dbus
+
+namespace chromeos {
+
+// TODO(benchan): Move these constants to system_api.
+namespace privetd {
+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.
+const char kPrivetdServicePath[] = "/org/chromium/privetd";
+const char kPrivetdManagerPath[] = "/org/chromium/privetd/Manager";
+const char kManagerInterfaceName[] = "org.chromium.privetd.Manager";
+const char kSetDescriptionMethod[] = "SetDescription";
+const char kGCDBootstrapStateProperty[] = "GCDBootstrapState";
+const char kWiFiBootstrapStateProperty[] = "WiFiBootstrapState";
+const char kPairingInfoProperty[] = "PairingInfo";
+const char kDescriptionProperty[] = "Description";
+const char kNameProperty[] = "Name";
+
+} // namespace privetd
+
+namespace {
+
+// The PrivetDaemonManagerClient implementation used in production.
+class PrivetDaemonManagerClientImpl : public PrivetDaemonManagerClient,
+ public dbus::ObjectManager::Interface {
+ public:
+ PrivetDaemonManagerClientImpl();
+ ~PrivetDaemonManagerClientImpl() override;
+
+ // PrivetDaemonManagerClient overrides.
+ void AddObserver(Observer* observer) override;
+ void RemoveObserver(Observer* observer) override;
+ void SetDescription(const std::string& description,
+ const VoidDBusMethodCallback& callback) override;
+ const ManagerProperties* GetManagerProperties() override;
+
+ // DBusClient overrides.
+ void Init(dbus::Bus* bus) override;
+
+ // dbus::ObjectManager::Interface overrides.
+ dbus::PropertySet* CreateProperties(
+ dbus::ObjectProxy* object_proxy,
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override;
+ void ObjectAdded(const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override;
+ void ObjectRemoved(const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override;
+
+ private:
+ // Called by dbus::PropertySet when a property value is changed,
+ // either by result of a signal or response to a GetAll() or Get()
+ // call. Informs observers.
+ void OnManagerPropertyChanged(const std::string& property_name);
+ void OnVoidDBusMethod(const VoidDBusMethodCallback& callback,
+ dbus::Response* response);
+
+ // List of observers interested in event notifications from us.
+ ObserverList<Observer> observers_;
+ dbus::ObjectManager* object_manager_;
+ base::WeakPtrFactory<PrivetDaemonManagerClientImpl> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrivetDaemonManagerClientImpl);
+};
+
+PrivetDaemonManagerClientImpl::PrivetDaemonManagerClientImpl()
+ : object_manager_(nullptr), weak_ptr_factory_(this) {
+}
+
+PrivetDaemonManagerClientImpl::~PrivetDaemonManagerClientImpl() {
+ if (object_manager_) {
+ object_manager_->UnregisterInterface(privetd::kManagerInterfaceName);
+ }
+}
+
+void PrivetDaemonManagerClientImpl::AddObserver(Observer* observer) {
+ DCHECK(observer);
+ observers_.AddObserver(observer);
+}
+
+void PrivetDaemonManagerClientImpl::RemoveObserver(Observer* observer) {
+ DCHECK(observer);
+ observers_.RemoveObserver(observer);
+}
+
+void PrivetDaemonManagerClientImpl::SetDescription(
+ const std::string& description,
+ const VoidDBusMethodCallback& callback) {
+ dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
+ dbus::ObjectPath(privetd::kPrivetdManagerPath));
+ if (!object_proxy) {
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod,
+ weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
+ return;
+ }
+
+ dbus::MethodCall method_call(privetd::kManagerInterfaceName,
+ privetd::kSetDescriptionMethod);
+ dbus::MessageWriter writer(&method_call);
+ writer.AppendString(description);
+ object_proxy->CallMethod(
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&PrivetDaemonManagerClientImpl::OnVoidDBusMethod,
+ weak_ptr_factory_.GetWeakPtr(), callback));
+}
+
+const PrivetDaemonManagerClient::ManagerProperties*
+PrivetDaemonManagerClientImpl::GetManagerProperties() {
+ return static_cast<ManagerProperties*>(object_manager_->GetProperties(
+ dbus::ObjectPath(privetd::kPrivetdManagerPath),
+ privetd::kManagerInterfaceName));
+}
+
+void PrivetDaemonManagerClientImpl::Init(dbus::Bus* bus) {
+ object_manager_ =
+ bus->GetObjectManager(privetd::kPrivetdServiceName,
+ dbus::ObjectPath(privetd::kPrivetdServicePath));
+ object_manager_->RegisterInterface(privetd::kManagerInterfaceName, this);
+}
+
+dbus::PropertySet* PrivetDaemonManagerClientImpl::CreateProperties(
+ dbus::ObjectProxy* object_proxy,
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) {
+ dbus::PropertySet* properties = nullptr;
+ if (interface_name == privetd::kManagerInterfaceName) {
+ properties = new ManagerProperties(
+ object_proxy, interface_name,
+ base::Bind(&PrivetDaemonManagerClientImpl::OnManagerPropertyChanged,
+ weak_ptr_factory_.GetWeakPtr()));
+ } else {
+ NOTREACHED() << "Unhandled interface name " << interface_name;
+ }
+ return properties;
+}
+
+void PrivetDaemonManagerClientImpl::ObjectAdded(
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) {
+ if (interface_name == privetd::kManagerInterfaceName) {
+ FOR_EACH_OBSERVER(Observer, observers_, ManagerAdded());
+ } else {
+ NOTREACHED() << "Unhandled interface name " << interface_name;
+ }
+}
+
+void PrivetDaemonManagerClientImpl::ObjectRemoved(
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) {
+ if (interface_name == privetd::kManagerInterfaceName) {
+ FOR_EACH_OBSERVER(Observer, observers_, ManagerRemoved());
+ } else {
+ NOTREACHED() << "Unhandled interface name " << interface_name;
+ }
+}
+
+void PrivetDaemonManagerClientImpl::OnManagerPropertyChanged(
+ const std::string& property_name) {
+ FOR_EACH_OBSERVER(Observer, observers_,
+ ManagerPropertyChanged(property_name));
+}
+
+void PrivetDaemonManagerClientImpl::OnVoidDBusMethod(
+ const VoidDBusMethodCallback& callback,
+ dbus::Response* response) {
+ callback.Run(response ? DBUS_METHOD_CALL_SUCCESS : DBUS_METHOD_CALL_FAILURE);
+}
+
+} // namespace
+
+PrivetDaemonManagerClient::ManagerProperties::ManagerProperties(
+ dbus::ObjectProxy* object_proxy,
+ const std::string& interface_name,
+ const PropertyChangedCallback& callback)
+ : dbus::PropertySet(object_proxy, interface_name, callback) {
+ RegisterProperty(privetd::kWiFiBootstrapStateProperty,
+ &wifi_bootstrap_state_);
+ RegisterProperty(privetd::kGCDBootstrapStateProperty, &gcd_bootstrap_state_);
+ RegisterProperty(privetd::kPairingInfoProperty, &pairing_info_);
+ RegisterProperty(privetd::kDescriptionProperty, &description_);
+ RegisterProperty(privetd::kNameProperty, &name_);
+}
+
+PrivetDaemonManagerClient::ManagerProperties::~ManagerProperties() {
+}
+
+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
+}
+
+void PrivetDaemonManagerClient::Observer::ManagerAdded() {
+}
+
+void PrivetDaemonManagerClient::Observer::ManagerRemoved() {
+}
+
+void PrivetDaemonManagerClient::Observer::ManagerPropertyChanged(
+ const std::string& property_name) {
+}
+
+PrivetDaemonManagerClient::PrivetDaemonManagerClient() {
+}
+
+PrivetDaemonManagerClient::~PrivetDaemonManagerClient() {
+}
+
+// static
+PrivetDaemonManagerClient* PrivetDaemonManagerClient::Create() {
+ return new PrivetDaemonManagerClientImpl();
+}
+
+} // namespace chromeos
« chromeos/dbus/privet_daemon_manager_client.h ('K') | « chromeos/dbus/privet_daemon_manager_client.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698