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; 39 static string ObjectID(ChromeosWiMaxManagerProxy* w) { 40 return "(wimax_manager_proxy)"; 41 } 42 } 43 44 // static. 45 const char ChromeosWiMaxManagerProxy::kPropertyDevices[] = "Devices"; 46 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 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 98 ChromeosWiMaxManagerProxy::~ChromeosWiMaxManagerProxy() {} 99 100 void ChromeosWiMaxManagerProxy::set_devices_changed_callback( 101 const DevicesChangedCallback& callback) { 102 devices_changed_callback_ = callback; 103 } 104 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 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 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 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 158 void ChromeosWiMaxManagerProxy::OnPropertyChanged( 159 const std::string& property_name) { 160 SLOG(DBus, nullptr, 2) << __func__ << ": " << property_name; 161 } 162 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