blob: 66f50b75061a820465f84985665453ad0757d486 [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
49void DBusManager::WatchName(const string &name,
50 const AppearedCallback &on_appear,
51 const VanishedCallback &on_vanish) {
52 LOG(INFO) << "DBus watch: " << name;
53 NameWatcher watcher(on_appear, on_vanish);
54 name_watchers_[name].push_back(watcher);
55 Error error;
56 proxy_->GetNameOwner(
57 name,
58 &error,
59 Bind(&DBusManager::OnGetNameOwnerComplete, Unretained(this), watcher),
60 kDefaultRPCTimeoutMS);
61 // Ensures that the watcher gets an initial appear/vanish notification
62 // regardless of the outcome of the GetNameOwner call.
63 if (error.IsFailure()) {
64 OnGetNameOwnerComplete(watcher, string(), error);
65 }
66}
67
68void DBusManager::OnNameOwnerChanged(
69 const string &name, const string &old_owner, const string &new_owner) {
70 map<string, list<NameWatcher> >::const_iterator find_it =
71 name_watchers_.find(name);
72 if (find_it == name_watchers_.end()) {
73 return;
74 }
75 LOG(INFO) << "DBus name owner changed: " << name
76 << "(" << old_owner << "->" << new_owner << ")";
77 for (list<NameWatcher>::const_iterator it = find_it->second.begin();
78 it != find_it->second.end(); ++it) {
79 NotifyNameWatcher(*it, new_owner);
80 }
81}
82
83void DBusManager::OnGetNameOwnerComplete(const NameWatcher &watcher,
84 const string &unique_name,
85 const Error &error) {
86 LOG(INFO) << "DBus name owner: " << unique_name
87 << "(" << error.message() << ")";
88 NotifyNameWatcher(watcher, error.IsSuccess() ? unique_name : string());
89}
90
91// static
92void DBusManager::NotifyNameWatcher(const NameWatcher &watcher,
93 const string &owner) {
94 SLOG(DBus, 2) << __func__ << "(" << owner << ")";
95 if (owner.empty()) {
96 if (!watcher.on_vanish.is_null()) {
97 watcher.on_vanish.Run();
98 }
99 } else if (!watcher.on_appear.is_null()) {
100 watcher.on_appear.Run(owner);
101 }
102}
103
104} // namespace shill