blob: d18a37c7ed2c2f59e04ef06647e740855087d1ff [file] [log] [blame]
Darin Petkov002c58e2012-06-19 02:56:05 +02001// Copyright (c) 2012 The Chromium OS 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 "shill/dbus_manager.h"
6
7#include <base/bind.h>
8
9#include "shill/dbus_service_proxy_interface.h"
10#include "shill/error.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070011#include "shill/logging.h"
Darin Petkov002c58e2012-06-19 02:56:05 +020012#include "shill/proxy_factory.h"
Darin Petkov002c58e2012-06-19 02:56:05 +020013
14using base::Bind;
15using base::Unretained;
16using std::list;
17using std::map;
18using std::string;
19
20namespace shill {
21
22namespace {
23
24const int kDefaultRPCTimeoutMS = 30000;
25
26} // namespace
27
28DBusManager::DBusManager()
29 : proxy_factory_(ProxyFactory::GetInstance()) {}
30
31DBusManager::~DBusManager() {}
32
33void DBusManager::Start() {
34 SLOG(DBus, 2) << __func__;
35 if (proxy_.get()) {
36 return;
37 }
38 proxy_.reset(proxy_factory_->CreateDBusServiceProxy());
39 proxy_->set_name_owner_changed_callback(
40 Bind(&DBusManager::OnNameOwnerChanged, Unretained(this)));
41}
42
43void DBusManager::Stop() {
44 SLOG(DBus, 2) << __func__;
45 proxy_.reset();
46 name_watchers_.clear();
47}
48
Ben Chan084faca2013-07-02 14:25:12 -070049DBusNameWatcher *DBusManager::CreateNameWatcher(
50 const string &name,
51 const DBusNameWatcher::NameAppearedCallback &name_appeared_callback,
52 const DBusNameWatcher::NameVanishedCallback &name_vanished_callback) {
53 // DBusNameWatcher holds a weak pointer to, and thus may outlive, this
54 // DBusManager object.
55 scoped_ptr<DBusNameWatcher> name_watcher(new DBusNameWatcher(
56 this, name, name_appeared_callback, name_vanished_callback));
57 name_watchers_[name].push_back(name_watcher.get());
58
Darin Petkov002c58e2012-06-19 02:56:05 +020059 Error error;
Ben Chan084faca2013-07-02 14:25:12 -070060 proxy_->GetNameOwner(name,
61 &error,
62 Bind(&DBusManager::OnGetNameOwnerComplete,
63 AsWeakPtr(),
64 name_watcher->AsWeakPtr()),
65 kDefaultRPCTimeoutMS);
Darin Petkov002c58e2012-06-19 02:56:05 +020066 // Ensures that the watcher gets an initial appear/vanish notification
67 // regardless of the outcome of the GetNameOwner call.
68 if (error.IsFailure()) {
Ben Chan084faca2013-07-02 14:25:12 -070069 OnGetNameOwnerComplete(name_watcher->AsWeakPtr(), string(), error);
70 }
71 return name_watcher.release();
72}
73
74void DBusManager::RemoveNameWatcher(DBusNameWatcher *name_watcher) {
75 CHECK(name_watcher);
76
77 auto watcher_iterator = name_watchers_.find(name_watcher->name());
78 if (watcher_iterator != name_watchers_.end()) {
79 watcher_iterator->second.remove(name_watcher);
Darin Petkov002c58e2012-06-19 02:56:05 +020080 }
81}
82
83void DBusManager::OnNameOwnerChanged(
84 const string &name, const string &old_owner, const string &new_owner) {
Ben Chan084faca2013-07-02 14:25:12 -070085 auto watcher_iterator = name_watchers_.find(name);
86 if (watcher_iterator == name_watchers_.end()) {
Darin Petkov002c58e2012-06-19 02:56:05 +020087 return;
88 }
Ben Chan084faca2013-07-02 14:25:12 -070089 LOG(INFO) << "DBus name '" << name << "' owner changed ('" << old_owner
90 << "' -> '" << new_owner << "')";
91 for (const auto &watcher : watcher_iterator->second) {
92 watcher->OnNameOwnerChanged(new_owner);
Darin Petkov002c58e2012-06-19 02:56:05 +020093 }
94}
95
Ben Chan084faca2013-07-02 14:25:12 -070096void DBusManager::OnGetNameOwnerComplete(
97 const base::WeakPtr<DBusNameWatcher> &watcher,
98 const string &unique_name,
99 const Error &error) {
100 if (watcher) {
101 LOG(INFO) << "DBus name '" << watcher->name() << "' owner '" << unique_name
102 << "' (" << error.message() << ")";
103 watcher->OnNameOwnerChanged(error.IsSuccess() ? unique_name : string());
Darin Petkov002c58e2012-06-19 02:56:05 +0200104 }
105}
106
107} // namespace shill