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 32using std::string; 33using std::vector; 34 35namespace shill { 36 37namespace Logging { 38static auto kModuleLogScope = ScopeLogger::kDBus; 39static string ObjectID(ChromeosWiMaxManagerProxy* w) { 40 return "(wimax_manager_proxy)"; 41} 42} 43 44// static. 45const char ChromeosWiMaxManagerProxy::kPropertyDevices[] = "Devices"; 46 47ChromeosWiMaxManagerProxy::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 55ChromeosWiMaxManagerProxy::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 98ChromeosWiMaxManagerProxy::~ChromeosWiMaxManagerProxy() {} 99 100void ChromeosWiMaxManagerProxy::set_devices_changed_callback( 101 const DevicesChangedCallback& callback) { 102 devices_changed_callback_ = callback; 103} 104 105RpcIdentifiers 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 123void 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 136void 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 147void 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 158void ChromeosWiMaxManagerProxy::OnPropertyChanged( 159 const std::string& property_name) { 160 SLOG(DBus, nullptr, 2) << __func__ << ": " << property_name; 161} 162 163void 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