1 //
2 // Copyright (C) 2015 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/dbus/chromeos_wimax_manager_proxy.h"
18
19 #include <string>
20
21 #if defined(__ANDROID__)
22 #include <dbus/service_constants.h>
23 #else
24 #include <chromeos/dbus/service_constants.h>
25 #endif // __ANDROID__
26
27 #include "shill/error.h"
28 #include "shill/event_dispatcher.h"
29 #include "shill/key_value_store.h"
30 #include "shill/logging.h"
31
32 using std::string;
33 using std::vector;
34
35 namespace shill {
36
37 namespace Logging {
38 static auto kModuleLogScope = ScopeLogger::kDBus;
ObjectID(ChromeosWiMaxManagerProxy * w)39 static string ObjectID(ChromeosWiMaxManagerProxy* w) {
40 return "(wimax_manager_proxy)";
41 }
42 }
43
44 // static.
45 const char ChromeosWiMaxManagerProxy::kPropertyDevices[] = "Devices";
46
PropertySet(dbus::ObjectProxy * object_proxy,const std::string & interface_name,const PropertyChangedCallback & callback)47 ChromeosWiMaxManagerProxy::PropertySet::PropertySet(
48 dbus::ObjectProxy* object_proxy,
49 const std::string& interface_name,
50 const PropertyChangedCallback& callback)
51 : dbus::PropertySet(object_proxy, interface_name, callback) {
52 RegisterProperty(kPropertyDevices, &devices);
53 }
54
ChromeosWiMaxManagerProxy(EventDispatcher * dispatcher,const scoped_refptr<dbus::Bus> & bus,const base::Closure & service_appeared_callback,const base::Closure & service_vanished_callback)55 ChromeosWiMaxManagerProxy::ChromeosWiMaxManagerProxy(
56 EventDispatcher* dispatcher,
57 const scoped_refptr<dbus::Bus>& bus,
58 const base::Closure& service_appeared_callback,
59 const base::Closure& service_vanished_callback)
60 : proxy_(
61 new org::chromium::WiMaxManagerProxy(
62 bus,
63 wimax_manager::kWiMaxManagerServiceName,
64 dbus::ObjectPath(wimax_manager::kWiMaxManagerServicePath))),
65 dispatcher_(dispatcher),
66 service_appeared_callback_(service_appeared_callback),
67 service_vanished_callback_(service_vanished_callback),
68 service_available_(false) {
69 // Register signal handler.
70 proxy_->RegisterDevicesChangedSignalHandler(
71 base::Bind(&ChromeosWiMaxManagerProxy::DevicesChanged,
72 weak_factory_.GetWeakPtr()),
73 base::Bind(&ChromeosWiMaxManagerProxy::OnSignalConnected,
74 weak_factory_.GetWeakPtr()));
75
76 // Register properties.
77 properties_.reset(
78 new PropertySet(
79 proxy_->GetObjectProxy(),
80 wimax_manager::kWiMaxManagerInterface,
81 base::Bind(&ChromeosWiMaxManagerProxy::OnPropertyChanged,
82 weak_factory_.GetWeakPtr())));
83 properties_->ConnectSignals();
84 properties_->GetAll();
85
86 // Monitor service owner changes. This callback lives for the lifetime of
87 // the ObjectProxy.
88 proxy_->GetObjectProxy()->SetNameOwnerChangedCallback(
89 base::Bind(&ChromeosWiMaxManagerProxy::OnServiceOwnerChanged,
90 weak_factory_.GetWeakPtr()));
91
92 // One time callback when service becomes available.
93 proxy_->GetObjectProxy()->WaitForServiceToBeAvailable(
94 base::Bind(&ChromeosWiMaxManagerProxy::OnServiceAvailable,
95 weak_factory_.GetWeakPtr()));
96 }
97
~ChromeosWiMaxManagerProxy()98 ChromeosWiMaxManagerProxy::~ChromeosWiMaxManagerProxy() {}
99
set_devices_changed_callback(const DevicesChangedCallback & callback)100 void ChromeosWiMaxManagerProxy::set_devices_changed_callback(
101 const DevicesChangedCallback& callback) {
102 devices_changed_callback_ = callback;
103 }
104
Devices(Error * error)105 RpcIdentifiers ChromeosWiMaxManagerProxy::Devices(Error* error) {
106 SLOG(this, 2) << __func__;
107 if (!service_available_) {
108 Error::PopulateAndLog(FROM_HERE, error, Error::kOperationFailed,
109 "WiMax Manager process not present");
110 return RpcIdentifiers();
111 }
112
113 if (!properties_->devices.GetAndBlock()) {
114 LOG(ERROR) << "Failed to get Devices";
115 return RpcIdentifiers();
116 }
117 RpcIdentifiers rpc_devices;
118 KeyValueStore::ConvertPathsToRpcIdentifiers(properties_->devices.value(),
119 &rpc_devices);
120 return rpc_devices;
121 }
122
OnServiceAvailable(bool available)123 void ChromeosWiMaxManagerProxy::OnServiceAvailable(bool available) {
124 SLOG(DBus, nullptr, 2) << __func__ << ": " << available;
125
126 // The callback might invoke calls to the ObjectProxy, so defer the callback
127 // to event loop.
128 if (available && !service_appeared_callback_.is_null()) {
129 dispatcher_->PostTask(service_appeared_callback_);
130 } else if (!available && !service_vanished_callback_.is_null()) {
131 dispatcher_->PostTask(service_vanished_callback_);
132 }
133 service_available_ = available;
134 }
135
OnServiceOwnerChanged(const string & old_owner,const string & new_owner)136 void ChromeosWiMaxManagerProxy::OnServiceOwnerChanged(
137 const string& old_owner, const string& new_owner) {
138 SLOG(DBus, nullptr, 2) << __func__
139 << "old: " << old_owner << " new: " << new_owner;
140 if (new_owner.empty()) {
141 OnServiceAvailable(false);
142 } else {
143 OnServiceAvailable(true);
144 }
145 }
146
OnSignalConnected(const string & interface_name,const string & signal_name,bool success)147 void ChromeosWiMaxManagerProxy::OnSignalConnected(
148 const string& interface_name, const string& signal_name, bool success) {
149 SLOG(DBus, nullptr, 2) << __func__
150 << "interface: " << interface_name << " signal: " << signal_name
151 << "success: " << success;
152 if (!success) {
153 LOG(ERROR) << "Failed to connect signal " << signal_name
154 << " to interface " << interface_name;
155 }
156 }
157
OnPropertyChanged(const std::string & property_name)158 void ChromeosWiMaxManagerProxy::OnPropertyChanged(
159 const std::string& property_name) {
160 SLOG(DBus, nullptr, 2) << __func__ << ": " << property_name;
161 }
162
DevicesChanged(const vector<dbus::ObjectPath> & devices)163 void ChromeosWiMaxManagerProxy::DevicesChanged(
164 const vector<dbus::ObjectPath>& devices) {
165 SLOG(DBus, nullptr, 2) << __func__ << "(" << devices.size() << ")";
166 if (devices_changed_callback_.is_null()) {
167 return;
168 }
169 RpcIdentifiers rpc_devices;
170 KeyValueStore::ConvertPathsToRpcIdentifiers(devices, &rpc_devices);
171 devices_changed_callback_.Run(rpc_devices);
172 }
173
174 } // namespace shill
175