update_engine: Switch to chrome-dbus for client requests in update_engine
update_engine daemon acts as DBus client to send DBus calls to shill,
power_manager and chrome, and to listen for signals from shill, chrome
and login_manager. This patch migrates these calls and signals to use
chrome-dbus framework instead of dbus-glib.
All references to dbus-glib code are removed.
BUG=chromium:419827
TEST=Updated unittest. Deployed on a link device and tested interactions with shill and chromium.
Change-Id: I31b389e0d1690cccb115ff3b6539c876ba81bd0e
Reviewed-on: https://chromium-review.googlesource.com/290990
Tested-by: Alex Deymo <deymo@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
diff --git a/connection_manager.cc b/connection_manager.cc
index 45b6467..d0d3392 100644
--- a/connection_manager.cc
+++ b/connection_manager.cc
@@ -10,7 +10,6 @@
#include <base/stl_util.h>
#include <base/strings/string_util.h>
#include <chromeos/dbus/service_constants.h>
-#include <dbus/dbus-glib.h>
#include <glib.h>
#include <policy/device_policy.h>
@@ -18,6 +17,8 @@
#include "update_engine/system_state.h"
#include "update_engine/utils.h"
+using org::chromium::flimflam::ManagerProxyInterface;
+using org::chromium::flimflam::ServiceProxyInterface;
using std::set;
using std::string;
@@ -25,163 +26,38 @@
namespace {
-// Gets the DbusGProxy for FlimFlam. Must be free'd with ProxyUnref()
-bool GetFlimFlamProxy(DBusWrapperInterface* dbus_iface,
- const char* path,
- const char* interface,
- DBusGProxy** out_proxy) {
- DBusGConnection* bus;
- DBusGProxy* proxy;
- GError* error = nullptr;
-
- bus = dbus_iface->BusGet(DBUS_BUS_SYSTEM, &error);
- if (!bus) {
- LOG(ERROR) << "Failed to get system bus";
- return false;
- }
- proxy = dbus_iface->ProxyNewForName(bus, shill::kFlimflamServiceName, path,
- interface);
- *out_proxy = proxy;
- return true;
-}
-
-// On success, caller owns the GHashTable at out_hash_table.
-// Returns true on success.
-bool GetProperties(DBusWrapperInterface* dbus_iface,
- const char* path,
- const char* interface,
- GHashTable** out_hash_table) {
- DBusGProxy* proxy;
- GError* error = nullptr;
-
- TEST_AND_RETURN_FALSE(GetFlimFlamProxy(dbus_iface,
- path,
- interface,
- &proxy));
-
- gboolean rc = dbus_iface->ProxyCall_0_1(proxy,
- "GetProperties",
- &error,
- out_hash_table);
- dbus_iface->ProxyUnref(proxy);
- if (rc == FALSE) {
- LOG(ERROR) << "dbus_g_proxy_call failed";
- return false;
- }
-
- return true;
-}
-
-// Returns (via out_path) the default network path, or empty string if
-// there's no network up.
-// Returns true on success.
-bool GetDefaultServicePath(DBusWrapperInterface* dbus_iface, string* out_path) {
- GHashTable* hash_table = nullptr;
-
- TEST_AND_RETURN_FALSE(GetProperties(dbus_iface,
- shill::kFlimflamServicePath,
- shill::kFlimflamManagerInterface,
- &hash_table));
-
- GValue* value = reinterpret_cast<GValue*>(g_hash_table_lookup(hash_table,
- "Services"));
- GPtrArray* array = nullptr;
- bool success = false;
- if (G_VALUE_HOLDS(value, DBUS_TYPE_G_OBJECT_PATH_ARRAY) &&
- (array = reinterpret_cast<GPtrArray*>(g_value_get_boxed(value))) &&
- (array->len > 0)) {
- *out_path = static_cast<const char*>(g_ptr_array_index(array, 0));
- success = true;
- }
-
- g_hash_table_unref(hash_table);
- return success;
-}
-
-NetworkConnectionType ParseConnectionType(const char* type_str) {
- if (!strcmp(type_str, shill::kTypeEthernet)) {
+NetworkConnectionType ParseConnectionType(const string& type_str) {
+ if (type_str == shill::kTypeEthernet) {
return NetworkConnectionType::kEthernet;
- } else if (!strcmp(type_str, shill::kTypeWifi)) {
+ } else if (type_str == shill::kTypeWifi) {
return NetworkConnectionType::kWifi;
- } else if (!strcmp(type_str, shill::kTypeWimax)) {
+ } else if (type_str == shill::kTypeWimax) {
return NetworkConnectionType::kWimax;
- } else if (!strcmp(type_str, shill::kTypeBluetooth)) {
+ } else if (type_str == shill::kTypeBluetooth) {
return NetworkConnectionType::kBluetooth;
- } else if (!strcmp(type_str, shill::kTypeCellular)) {
+ } else if (type_str == shill::kTypeCellular) {
return NetworkConnectionType::kCellular;
}
return NetworkConnectionType::kUnknown;
}
-NetworkTethering ParseTethering(const char* tethering_str) {
- if (!strcmp(tethering_str, shill::kTetheringNotDetectedState)) {
+NetworkTethering ParseTethering(const string& tethering_str) {
+ if (tethering_str == shill::kTetheringNotDetectedState) {
return NetworkTethering::kNotDetected;
- } else if (!strcmp(tethering_str, shill::kTetheringSuspectedState)) {
+ } else if (tethering_str == shill::kTetheringSuspectedState) {
return NetworkTethering::kSuspected;
- } else if (!strcmp(tethering_str, shill::kTetheringConfirmedState)) {
+ } else if (tethering_str == shill::kTetheringConfirmedState) {
return NetworkTethering::kConfirmed;
}
LOG(WARNING) << "Unknown Tethering value: " << tethering_str;
return NetworkTethering::kUnknown;
}
-bool GetServicePathProperties(DBusWrapperInterface* dbus_iface,
- const string& path,
- NetworkConnectionType* out_type,
- NetworkTethering* out_tethering) {
- GHashTable* hash_table = nullptr;
-
- TEST_AND_RETURN_FALSE(GetProperties(dbus_iface,
- path.c_str(),
- shill::kFlimflamServiceInterface,
- &hash_table));
-
- // Populate the out_tethering.
- GValue* value =
- reinterpret_cast<GValue*>(g_hash_table_lookup(hash_table,
- shill::kTetheringProperty));
- const char* tethering_str = nullptr;
-
- if (value != nullptr)
- tethering_str = g_value_get_string(value);
- if (tethering_str != nullptr) {
- *out_tethering = ParseTethering(tethering_str);
- } else {
- // Set to Unknown if not present.
- *out_tethering = NetworkTethering::kUnknown;
- }
-
- // Populate the out_type property.
- value = reinterpret_cast<GValue*>(g_hash_table_lookup(hash_table,
- shill::kTypeProperty));
- const char* type_str = nullptr;
- bool success = false;
- if (value != nullptr && (type_str = g_value_get_string(value)) != nullptr) {
- success = true;
- if (!strcmp(type_str, shill::kTypeVPN)) {
- value = reinterpret_cast<GValue*>(
- g_hash_table_lookup(hash_table, shill::kPhysicalTechnologyProperty));
- if (value != nullptr &&
- (type_str = g_value_get_string(value)) != nullptr) {
- *out_type = ParseConnectionType(type_str);
- } else {
- LOG(ERROR) << "No PhysicalTechnology property found for a VPN"
- << " connection (service: " << path << "). Returning default"
- << " NetworkConnectionType::kUnknown value.";
- *out_type = NetworkConnectionType::kUnknown;
- }
- } else {
- *out_type = ParseConnectionType(type_str);
- }
- }
- g_hash_table_unref(hash_table);
- return success;
-}
-
} // namespace
-ConnectionManager::ConnectionManager(SystemState *system_state)
- : system_state_(system_state) {}
+ConnectionManager::ConnectionManager(ShillProxyInterface* shill_proxy,
+ SystemState* system_state)
+ : shill_proxy_(shill_proxy), system_state_(system_state) {}
bool ConnectionManager::IsUpdateAllowedOver(NetworkConnectionType type,
NetworkTethering tethering) const {
@@ -273,33 +149,81 @@
return "Unknown";
}
-// static
-const char* ConnectionManager::StringForTethering(NetworkTethering tethering) {
- switch (tethering) {
- case NetworkTethering::kNotDetected:
- return shill::kTetheringNotDetectedState;
- case NetworkTethering::kSuspected:
- return shill::kTetheringSuspectedState;
- case NetworkTethering::kConfirmed:
- return shill::kTetheringConfirmedState;
- case NetworkTethering::kUnknown:
- return "Unknown";
- }
- // The program shouldn't reach this point, but the compiler isn't smart
- // enough to infer that.
- return "Unknown";
+bool ConnectionManager::GetConnectionProperties(
+ NetworkConnectionType* out_type,
+ NetworkTethering* out_tethering) {
+ string default_service_path;
+ TEST_AND_RETURN_FALSE(GetDefaultServicePath(&default_service_path));
+ if (default_service_path.empty())
+ return false;
+ TEST_AND_RETURN_FALSE(
+ GetServicePathProperties(default_service_path, out_type, out_tethering));
+ return true;
}
-bool ConnectionManager::GetConnectionProperties(
- DBusWrapperInterface* dbus_iface,
+bool ConnectionManager::GetDefaultServicePath(string* out_path) {
+ chromeos::VariantDictionary properties;
+ chromeos::ErrorPtr error;
+ ManagerProxyInterface* manager_proxy = shill_proxy_->GetManagerProxy();
+ if (!manager_proxy)
+ return false;
+ TEST_AND_RETURN_FALSE(manager_proxy->GetProperties(&properties, &error));
+
+ const auto& prop_default_service =
+ properties.find(shill::kDefaultServiceProperty);
+ if (prop_default_service == properties.end())
+ return false;
+
+ *out_path = prop_default_service->second.TryGet<dbus::ObjectPath>().value();
+ return !out_path->empty();
+}
+
+bool ConnectionManager::GetServicePathProperties(
+ const string& path,
NetworkConnectionType* out_type,
- NetworkTethering* out_tethering) const {
- string default_service_path;
- TEST_AND_RETURN_FALSE(GetDefaultServicePath(dbus_iface,
- &default_service_path));
- TEST_AND_RETURN_FALSE(GetServicePathProperties(dbus_iface,
- default_service_path,
- out_type, out_tethering));
+ NetworkTethering* out_tethering) {
+ // We create and dispose the ServiceProxyInterface on every request.
+ std::unique_ptr<ServiceProxyInterface> service =
+ shill_proxy_->GetServiceForPath(path);
+
+ chromeos::VariantDictionary properties;
+ chromeos::ErrorPtr error;
+ TEST_AND_RETURN_FALSE(service->GetProperties(&properties, &error));
+
+ // Populate the out_tethering.
+ const auto& prop_tethering = properties.find(shill::kTetheringProperty);
+ if (prop_tethering == properties.end()) {
+ // Set to Unknown if not present.
+ *out_tethering = NetworkTethering::kUnknown;
+ } else {
+ // If the property doesn't contain a string value, the empty string will
+ // become kUnknown.
+ *out_tethering = ParseTethering(prop_tethering->second.TryGet<string>());
+ }
+
+ // Populate the out_type property.
+ const auto& prop_type = properties.find(shill::kTypeProperty);
+ if (prop_type == properties.end()) {
+ // Set to Unknown if not present.
+ *out_type = NetworkConnectionType::kUnknown;
+ return false;
+ }
+
+ string type_str = prop_type->second.TryGet<string>();
+ if (type_str == shill::kTypeVPN) {
+ const auto& prop_physical =
+ properties.find(shill::kPhysicalTechnologyProperty);
+ if (prop_physical == properties.end()) {
+ LOG(ERROR) << "No PhysicalTechnology property found for a VPN"
+ << " connection (service: " << path << "). Returning default"
+ << " kUnknown value.";
+ *out_type = NetworkConnectionType::kUnknown;
+ } else {
+ *out_type = ParseConnectionType(prop_physical->second.TryGet<string>());
+ }
+ } else {
+ *out_type = ParseConnectionType(type_str);
+ }
return true;
}