Home | History | Annotate | Download | only in dbus
      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