Chromium Code Reviews| Index: chromeos/dbus/leadership_daemon_manager_client.cc |
| diff --git a/chromeos/dbus/leadership_daemon_manager_client.cc b/chromeos/dbus/leadership_daemon_manager_client.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..cba4abfd44719c66e20389af6b3c2967cfbbade8 |
| --- /dev/null |
| +++ b/chromeos/dbus/leadership_daemon_manager_client.cc |
| @@ -0,0 +1,351 @@ |
| +// 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/leadership_daemon_manager_client.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/callback.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 chromeos { |
| + |
| +// TODO(benchan): Move these constants to system_api. |
| +namespace leaderd { |
| +const char kLeaderdServiceName[] = "org.chromium.leaderd"; |
| +const char kLeaderdObjectManagerServicePath[] = "/org/chromium/leaderd"; |
| +const char kLeaderdManagerPath[] = "/org/chromium/leaderd/Manager"; |
| +const char kManagerInterface[] = "org.chromium.leaderd.Manager"; |
| +const char kGroupInterface[] = "org.chromium.leaderd.Group"; |
| +const char kJoinGroupMethod[] = "JoinGroup"; |
| +const char kLeaveGroupMethod[] = "LeaveGroup"; |
| +const char kSetScoreMethod[] = "SetScore"; |
| +const char kPokeLeaderMethod[] = "PokeLeader"; |
| +const char kPingMethod[] = "Ping"; |
| +const char kLeaderUUID[] = "LeaderUUID"; |
| +const char kGroupMembers[] = "GroupMembers"; |
| +} // namespace leaderd |
| + |
| +namespace { |
| + |
| +// Since there is no property associated with Manager objects, an empty callback |
| +// is used. |
| +void DoNothing(const std::string& property_name) { |
| +} |
| + |
| +// The LeadershipDaemonManagerClient implementation used in production. |
| +class LeadershipDaemonManagerClientImpl |
| + : public LeadershipDaemonManagerClient, |
| + public dbus::ObjectManager::Interface { |
| + public: |
| + LeadershipDaemonManagerClientImpl(); |
| + ~LeadershipDaemonManagerClientImpl() override; |
| + |
| + // LeadershipDaemonManagerClient overrides. |
| + void AddObserver(Observer* observer) override; |
| + void RemoveObserver(Observer* observer) override; |
| + void JoinGroup(const std::string& group, |
| + const base::DictionaryValue& options, |
| + const StringDBusMethodCallback& callback) override; |
| + void LeaveGroup(const std::string& object_path, |
| + const VoidDBusMethodCallback& callback) override; |
| + void SetScore(const std::string& object_path, |
| + int score, |
| + const VoidDBusMethodCallback& callback) override; |
| + void PokeLeader(const std::string& object_path, |
| + const VoidDBusMethodCallback& callback) override; |
| + void Ping(const StringDBusMethodCallback& callback) override; |
| + const GroupProperties* GetGroupProperties( |
| + const dbus::ObjectPath& object_path) override; |
| + |
| + // DBusClient overrides: |
|
stevenjb
2015/02/12 23:03:22
Use '.' or ':' (or omit 'overrides' entirely, e.g.
dtapuska
2015/02/13 15:23:49
Done.
|
| + void Init(dbus::Bus* bus) override; |
| + |
| + // dbus::ObjectManager::Interface override. |
| + 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 OnGroupPropertyChanged(const dbus::ObjectPath& object_path, |
| + const std::string& property_name); |
| + |
| + void OnStringDBusMethod(const StringDBusMethodCallback& callback, |
| + dbus::Response* response); |
| + 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<LeadershipDaemonManagerClientImpl> weak_ptr_factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(LeadershipDaemonManagerClientImpl); |
| +}; |
| + |
| +LeadershipDaemonManagerClientImpl::LeadershipDaemonManagerClientImpl() |
| + : object_manager_(nullptr), weak_ptr_factory_(this) { |
| +} |
| + |
| +LeadershipDaemonManagerClientImpl::~LeadershipDaemonManagerClientImpl() { |
| + if (object_manager_) { |
| + object_manager_->UnregisterInterface(leaderd::kManagerInterface); |
| + object_manager_->UnregisterInterface(leaderd::kGroupInterface); |
| + } |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::AddObserver(Observer* observer) { |
| + DCHECK(observer); |
| + observers_.AddObserver(observer); |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::RemoveObserver(Observer* observer) { |
| + DCHECK(observer); |
| + observers_.RemoveObserver(observer); |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::JoinGroup( |
| + const std::string& group, |
| + const base::DictionaryValue& options, |
| + const StringDBusMethodCallback& callback) { |
| + dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy( |
| + dbus::ObjectPath(leaderd::kLeaderdManagerPath)); |
| + if (!object_proxy) { |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); |
| + return; |
| + } |
| + |
| + dbus::MethodCall method_call(leaderd::kManagerInterface, |
| + leaderd::kJoinGroupMethod); |
| + dbus::MessageWriter writer(&method_call); |
| + writer.AppendString(group); |
| + dbus::AppendValueData(&writer, options); |
| + object_proxy->CallMethod( |
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::LeaveGroup( |
| + const std::string& object_path, |
| + const VoidDBusMethodCallback& callback) { |
| + dbus::ObjectProxy* object_proxy = |
| + object_manager_->GetObjectProxy(dbus::ObjectPath(object_path)); |
| + if (!object_proxy) { |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); |
| + return; |
| + } |
| + |
| + dbus::MethodCall method_call(leaderd::kGroupInterface, |
| + leaderd::kLeaveGroupMethod); |
| + dbus::MessageWriter writer(&method_call); |
| + object_proxy->CallMethod( |
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::SetScore( |
| + const std::string& object_path, |
| + int score, |
| + const VoidDBusMethodCallback& callback) { |
| + dbus::ObjectProxy* object_proxy = |
| + object_manager_->GetObjectProxy(dbus::ObjectPath(object_path)); |
| + if (!object_proxy) { |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); |
| + return; |
| + } |
| + |
| + dbus::MethodCall method_call(leaderd::kGroupInterface, |
| + leaderd::kSetScoreMethod); |
| + dbus::MessageWriter writer(&method_call); |
| + writer.AppendInt32(score); |
| + object_proxy->CallMethod( |
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::PokeLeader( |
| + const std::string& object_path, |
| + const VoidDBusMethodCallback& callback) { |
| + dbus::ObjectProxy* object_proxy = |
| + object_manager_->GetObjectProxy(dbus::ObjectPath(object_path)); |
| + if (!object_proxy) { |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); |
| + return; |
| + } |
| + |
| + dbus::MethodCall method_call(leaderd::kGroupInterface, |
| + leaderd::kPokeLeaderMethod); |
| + dbus::MessageWriter writer(&method_call); |
| + object_proxy->CallMethod( |
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::Ping( |
| + const StringDBusMethodCallback& callback) { |
| + dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy( |
| + dbus::ObjectPath(leaderd::kLeaderdManagerPath)); |
| + if (!object_proxy) { |
| + base::MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); |
| + return; |
| + } |
| + |
| + dbus::MethodCall method_call(leaderd::kManagerInterface, |
| + leaderd::kPingMethod); |
| + dbus::MessageWriter writer(&method_call); |
| + object_proxy->CallMethod( |
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod, |
| + weak_ptr_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +const LeadershipDaemonManagerClient::GroupProperties* |
| +LeadershipDaemonManagerClientImpl::GetGroupProperties( |
| + const dbus::ObjectPath& object_path) { |
| + return static_cast<GroupProperties*>( |
| + object_manager_->GetProperties(object_path, leaderd::kGroupInterface)); |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::Init(dbus::Bus* bus) { |
| + object_manager_ = bus->GetObjectManager( |
| + leaderd::kLeaderdServiceName, |
| + dbus::ObjectPath(leaderd::kLeaderdObjectManagerServicePath)); |
| + object_manager_->RegisterInterface(leaderd::kManagerInterface, this); |
| + object_manager_->RegisterInterface(leaderd::kGroupInterface, this); |
| +} |
| + |
| +dbus::PropertySet* LeadershipDaemonManagerClientImpl::CreateProperties( |
| + dbus::ObjectProxy* object_proxy, |
| + const dbus::ObjectPath& object_path, |
| + const std::string& interface_name) { |
| + dbus::PropertySet* properties = nullptr; |
| + if (interface_name == leaderd::kManagerInterface) { |
| + properties = new dbus::PropertySet(object_proxy, interface_name, |
| + base::Bind(&DoNothing)); |
| + } else if (interface_name == leaderd::kGroupInterface) { |
| + properties = new GroupProperties( |
| + object_proxy, interface_name, |
| + base::Bind(&LeadershipDaemonManagerClientImpl::OnGroupPropertyChanged, |
| + weak_ptr_factory_.GetWeakPtr(), object_path)); |
| + } else { |
| + NOTREACHED() << "Unhandled interface name " << interface_name; |
| + } |
| + return properties; |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::ObjectAdded( |
| + const dbus::ObjectPath& object_path, |
| + const std::string& interface_name) { |
| + if (interface_name == leaderd::kManagerInterface) { |
| + FOR_EACH_OBSERVER(Observer, observers_, ManagerAdded()); |
| + } else if (interface_name == leaderd::kGroupInterface) { |
| + FOR_EACH_OBSERVER(Observer, observers_, GroupAdded(object_path)); |
| + } else { |
| + NOTREACHED() << "Unhandled interface name " << interface_name; |
| + } |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::ObjectRemoved( |
| + const dbus::ObjectPath& object_path, |
| + const std::string& interface_name) { |
| + if (interface_name == leaderd::kManagerInterface) { |
| + FOR_EACH_OBSERVER(Observer, observers_, ManagerRemoved()); |
| + } else if (interface_name == leaderd::kGroupInterface) { |
| + FOR_EACH_OBSERVER(Observer, observers_, GroupRemoved(object_path)); |
| + } else { |
| + NOTREACHED() << "Unhandled interface name " << interface_name; |
| + } |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::OnGroupPropertyChanged( |
| + const dbus::ObjectPath& object_path, |
| + const std::string& property_name) { |
| + FOR_EACH_OBSERVER(Observer, observers_, |
| + GroupPropertyChanged(object_path, property_name)); |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::OnStringDBusMethod( |
| + const StringDBusMethodCallback& callback, |
| + dbus::Response* response) { |
| + if (!response) { |
| + callback.Run(DBUS_METHOD_CALL_FAILURE, std::string()); |
| + return; |
| + } |
| + |
| + dbus::MessageReader reader(response); |
| + std::string result; |
| + if (!reader.PopString(&result)) { |
| + callback.Run(DBUS_METHOD_CALL_FAILURE, std::string()); |
| + return; |
| + } |
| + |
| + callback.Run(DBUS_METHOD_CALL_SUCCESS, result); |
| +} |
| + |
| +void LeadershipDaemonManagerClientImpl::OnVoidDBusMethod( |
| + const VoidDBusMethodCallback& callback, |
| + dbus::Response* response) { |
| + callback.Run(response ? DBUS_METHOD_CALL_SUCCESS : DBUS_METHOD_CALL_FAILURE); |
| +} |
| + |
| +} // namespace |
| + |
| +LeadershipDaemonManagerClient::GroupProperties::GroupProperties( |
| + dbus::ObjectProxy* object_proxy, |
| + const std::string& interface_name, |
| + const PropertyChangedCallback& callback) |
| + : dbus::PropertySet(object_proxy, interface_name, callback) { |
| + RegisterProperty(leaderd::kLeaderUUID, &leader_uuid_); |
| + RegisterProperty(leaderd::kGroupMembers, &group_members_); |
| +} |
| + |
| +LeadershipDaemonManagerClient::GroupProperties::~GroupProperties() { |
| +} |
| + |
| +LeadershipDaemonManagerClient::LeadershipDaemonManagerClient() { |
| +} |
| + |
| +LeadershipDaemonManagerClient::~LeadershipDaemonManagerClient() { |
| +} |
| + |
| +// static |
| +LeadershipDaemonManagerClient* LeadershipDaemonManagerClient::Create() { |
| + return new LeadershipDaemonManagerClientImpl(); |
| +} |
| + |
| +} // namespace chromeos |