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_dbus_objectmanager_proxy.h" 18 19 #include <memory> 20 21 #include "shill/cellular/cellular_error.h" 22 #include "shill/event_dispatcher.h" 23 #include "shill/logging.h" 24 25 using std::string; 26 27 namespace shill { 28 29 namespace Logging { 30 static auto kModuleLogScope = ScopeLogger::kDBus; 31 static string ObjectID(const dbus::ObjectPath* p) { return p->value(); } 32 } 33 34 ChromeosDBusObjectManagerProxy::ChromeosDBusObjectManagerProxy( 35 EventDispatcher* dispatcher, 36 const scoped_refptr<dbus::Bus>& bus, 37 const std::string& path, 38 const std::string& service, 39 const base::Closure& service_appeared_callback, 40 const base::Closure& service_vanished_callback) 41 : proxy_( 42 new org::freedesktop::DBus::ObjectManagerProxy( 43 bus, service, dbus::ObjectPath(path))), 44 dispatcher_(dispatcher), 45 service_appeared_callback_(service_appeared_callback), 46 service_vanished_callback_(service_vanished_callback), 47 service_available_(false) { 48 // Register signal handlers. 49 proxy_->RegisterInterfacesAddedSignalHandler( 50 base::Bind(&ChromeosDBusObjectManagerProxy::InterfacesAdded, 51 weak_factory_.GetWeakPtr()), 52 base::Bind(&ChromeosDBusObjectManagerProxy::OnSignalConnected, 53 weak_factory_.GetWeakPtr())); 54 proxy_->RegisterInterfacesRemovedSignalHandler( 55 base::Bind(&ChromeosDBusObjectManagerProxy::InterfacesRemoved, 56 weak_factory_.GetWeakPtr()), 57 base::Bind(&ChromeosDBusObjectManagerProxy::OnSignalConnected, 58 weak_factory_.GetWeakPtr())); 59 60 // Monitor service owner changes. This callback lives for the lifetime of 61 // the ObjectProxy. 62 proxy_->GetObjectProxy()->SetNameOwnerChangedCallback( 63 base::Bind(&ChromeosDBusObjectManagerProxy::OnServiceOwnerChanged, 64 weak_factory_.GetWeakPtr())); 65 66 // One time callback when service becomes available. 67 proxy_->GetObjectProxy()->WaitForServiceToBeAvailable( 68 base::Bind(&ChromeosDBusObjectManagerProxy::OnServiceAvailable, 69 weak_factory_.GetWeakPtr())); 70 } 71 72 ChromeosDBusObjectManagerProxy::~ChromeosDBusObjectManagerProxy() {} 73 74 void ChromeosDBusObjectManagerProxy::GetManagedObjects( 75 Error* error, 76 const ManagedObjectsCallback& callback, 77 int timeout) { 78 if (!service_available_) { 79 Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError, 80 "Service not available"); 81 return; 82 } 83 proxy_->GetManagedObjectsAsync( 84 base::Bind(&ChromeosDBusObjectManagerProxy::OnGetManagedObjectsSuccess, 85 weak_factory_.GetWeakPtr(), 86 callback), 87 base::Bind(&ChromeosDBusObjectManagerProxy::OnGetManagedObjectsFailure, 88 weak_factory_.GetWeakPtr(), 89 callback)); 90 } 91 92 void ChromeosDBusObjectManagerProxy::OnServiceAvailable(bool available) { 93 LOG(INFO) << __func__ << ": " << available; 94 95 // The callback might invoke calls to the ObjectProxy, so defer the callback 96 // to event loop. 97 if (available && !service_appeared_callback_.is_null()) { 98 dispatcher_->PostTask(service_appeared_callback_); 99 } else if (!available && !service_vanished_callback_.is_null()) { 100 dispatcher_->PostTask(service_vanished_callback_); 101 } 102 service_available_ = available; 103 } 104 105 void ChromeosDBusObjectManagerProxy::OnServiceOwnerChanged( 106 const string& old_owner, const string& new_owner) { 107 LOG(INFO) << __func__ << " old: " << old_owner << " new: " << new_owner; 108 if (new_owner.empty()) { 109 OnServiceAvailable(false); 110 } else { 111 OnServiceAvailable(true); 112 } 113 } 114 115 void ChromeosDBusObjectManagerProxy::OnSignalConnected( 116 const string& interface_name, const string& signal_name, bool success) { 117 SLOG(&proxy_->GetObjectPath(), 2) << __func__ 118 << "interface: " << interface_name 119 << " signal: " << signal_name << "success: " << success; 120 if (!success) { 121 LOG(ERROR) << "Failed to connect signal " << signal_name 122 << " to interface " << interface_name; 123 } 124 } 125 126 void ChromeosDBusObjectManagerProxy::InterfacesAdded( 127 const dbus::ObjectPath& object_path, 128 const DBusInterfaceToProperties& dbus_interface_to_properties) { 129 SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" 130 << object_path.value() << ")"; 131 InterfaceToProperties interface_to_properties; 132 ConvertDBusInterfaceProperties(dbus_interface_to_properties, 133 &interface_to_properties); 134 interfaces_added_callback_.Run(object_path.value(), interface_to_properties); 135 } 136 137 void ChromeosDBusObjectManagerProxy::InterfacesRemoved( 138 const dbus::ObjectPath& object_path, 139 const std::vector<std::string>& interfaces) { 140 SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" 141 << object_path.value() << ")"; 142 interfaces_removed_callback_.Run(object_path.value(), interfaces); 143 } 144 145 void ChromeosDBusObjectManagerProxy::OnGetManagedObjectsSuccess( 146 const ManagedObjectsCallback& callback, 147 const DBusObjectsWithProperties& dbus_objects_with_properties) { 148 SLOG(&proxy_->GetObjectPath(), 2) << __func__; 149 ObjectsWithProperties objects_with_properties; 150 for (const auto& object : dbus_objects_with_properties) { 151 InterfaceToProperties interface_to_properties; 152 ConvertDBusInterfaceProperties(object.second, &interface_to_properties); 153 objects_with_properties.emplace(object.first.value(), 154 interface_to_properties); 155 } 156 callback.Run(objects_with_properties, Error()); 157 } 158 159 void ChromeosDBusObjectManagerProxy::OnGetManagedObjectsFailure( 160 const ManagedObjectsCallback& callback, 161 brillo::Error* dbus_error) { 162 Error error; 163 CellularError::FromChromeosDBusError(dbus_error, &error); 164 callback.Run(ObjectsWithProperties(), error); 165 } 166 167 void ChromeosDBusObjectManagerProxy::ConvertDBusInterfaceProperties( 168 const DBusInterfaceToProperties& dbus_interface_to_properties, 169 InterfaceToProperties* interface_to_properties) { 170 for (const auto& interface : dbus_interface_to_properties) { 171 KeyValueStore properties; 172 KeyValueStore::ConvertFromVariantDictionary(interface.second, &properties); 173 interface_to_properties->emplace(interface.first, properties); 174 } 175 } 176 177 } // namespace shill 178