blob: 87ba27f30e96f62fcd31c228d5438ea00ea3221e [file] [log] [blame]
Peter Qiu7e0ffcf2014-12-02 12:53:27 -08001// Copyright 2014 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 "apmanager/shill_proxy.h"
6
Peter Qiu267fff32014-12-10 14:01:58 -08007#include <base/bind.h>
Peter Qiu7e0ffcf2014-12-02 12:53:27 -08008#include <chromeos/dbus/service_constants.h>
9#include <chromeos/errors/error.h>
10
11using std::string;
12
13namespace apmanager {
14
15// static.
16const char ShillProxy::kManagerPath[] = "/";
17
Peter Qiuc9ce1f12014-12-05 11:14:29 -080018ShillProxy::ShillProxy() {}
Peter Qiu7e0ffcf2014-12-02 12:53:27 -080019
20ShillProxy::~ShillProxy() {}
21
Peter Qiuc9ce1f12014-12-05 11:14:29 -080022void ShillProxy::Init(const scoped_refptr<dbus::Bus>& bus) {
23 CHECK(!manager_proxy_) << "Already init";
24 manager_proxy_.reset(
25 new org::chromium::flimflam::ManagerProxy(
26 bus, shill::kFlimflamServiceName, dbus::ObjectPath(kManagerPath)));
Peter Qiu267fff32014-12-10 14:01:58 -080027 // This will connect the name owner changed signal in DBus object proxy,
28 // The callback will be invoked as soon as service is avalilable. and will
29 // be cleared after it is invoked. So this will be an one time callback.
30 manager_proxy_->GetObjectProxy()->WaitForServiceToBeAvailable(
31 base::Bind(&ShillProxy::OnServiceAvailable, base::Unretained(this)));
32 // This will continuously monitor the name owner of the service. However,
33 // it does not connect the name owner changed signal in DBus object proxy
34 // for some reason. In order to connect the name owner changed signal,
35 // either WaitForServiceToBeAvaiable or ConnectToSignal need to be invoked.
36 // Since we're not interested in any signals from Shill proxy,
37 // WaitForServiceToBeAvailable is used.
38 manager_proxy_->GetObjectProxy()->SetNameOwnerChangedCallback(
39 base::Bind(&ShillProxy::OnServiceNameChanged, base::Unretained(this)));
Peter Qiuc9ce1f12014-12-05 11:14:29 -080040}
41
Peter Qiu7e0ffcf2014-12-02 12:53:27 -080042void ShillProxy::ClaimInterface(const string& interface_name) {
Peter Qiuc9ce1f12014-12-05 11:14:29 -080043 CHECK(manager_proxy_) << "Proxy not initialize yet";
Peter Qiu7e0ffcf2014-12-02 12:53:27 -080044 chromeos::ErrorPtr error;
45 if (!manager_proxy_->ClaimInterface(kServiceName, interface_name, &error)) {
46 // Ignore unknown object error (when shill is not running). Only report
47 // internal error from shill.
48 if (error->GetCode() != DBUS_ERROR_UNKNOWN_OBJECT) {
49 LOG(ERROR) << "Failed to claim interface from shill: "
50 << error->GetCode() << " " << error->GetMessage();
51 }
52 }
53 claimed_interfaces_.insert(interface_name);
54}
55
56void ShillProxy::ReleaseInterface(const string& interface_name) {
Peter Qiuc9ce1f12014-12-05 11:14:29 -080057 CHECK(manager_proxy_) << "Proxy not initialize yet";
Peter Qiu7e0ffcf2014-12-02 12:53:27 -080058 chromeos::ErrorPtr error;
59 if (!manager_proxy_->ReleaseInterface(interface_name, &error)) {
60 // Ignore unknown object error (when shill is not running). Only report
61 // internal error from shill.
62 if (error->GetCode() != DBUS_ERROR_UNKNOWN_OBJECT) {
63 LOG(ERROR) << "Failed to release interface from shill: "
64 << error->GetCode() << " " << error->GetMessage();
65 }
66 }
67 claimed_interfaces_.erase(interface_name);
68}
69
Peter Qiu267fff32014-12-10 14:01:58 -080070void ShillProxy::OnServiceAvailable(bool service_available) {
71 LOG(INFO) << "OnServiceAvailabe " << service_available;
72 // Nothing to be done if proxy service not available.
73 if (!service_available) {
74 return;
75 }
76 // Claim all interfaces from shill DBus service in case this is a new
77 // instance.
78 for (const auto& interface : claimed_interfaces_) {
79 chromeos::ErrorPtr error;
80 if (!manager_proxy_->ClaimInterface(kServiceName, interface, &error)) {
81 LOG(ERROR) << "Failed to claim interface from shill: "
82 << error->GetCode() << " " << error->GetMessage();
83 }
84 }
85}
86
87void ShillProxy::OnServiceNameChanged(const string& old_owner,
88 const string& new_owner) {
89 LOG(INFO) << "OnServiceNameChanged old " << old_owner
90 << " new " << new_owner;
91 // Nothing to be done if no owner is attached to the shill service.
92 if (new_owner.empty()) {
93 return;
94 }
95 OnServiceAvailable(true);
96}
97
Peter Qiu7e0ffcf2014-12-02 12:53:27 -080098} // namespace apmanager