ofono: take D-Bus proxy for ConnectionManager asynchronously

Also,

  - disconnect signals from connman_proxy in dispose()

  - don't take reference to self for GetProperties call
This commit is contained in:
Thomas Haller
2017-04-22 21:56:59 +02:00
parent b7329fccce
commit 58712c9546

View File

@@ -46,6 +46,7 @@ typedef struct {
GDBusProxy *context_proxy; GDBusProxy *context_proxy;
GDBusProxy *sim_proxy; GDBusProxy *sim_proxy;
GCancellable *connman_proxy_cancellable;
GCancellable *sim_proxy_cancellable; GCancellable *sim_proxy_cancellable;
GError *property_error; GError *property_error;
@@ -552,22 +553,35 @@ connman_property_changed (GDBusProxy *proxy,
} }
static void static void
connman_get_properties_done (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) connman_get_properties_done (GObject *source,
GAsyncResult *result,
gpointer user_data)
{ {
gs_unref_object NMModemOfono *self = NM_MODEM_OFONO (user_data); NMModemOfono *self;
GError *error = NULL; NMModemOfonoPrivate *priv;
GVariant *v_properties, *v_dict, *v; gs_free_error GError *error = NULL;
gs_unref_variant GVariant *v_properties = NULL;
gs_unref_variant GVariant *v_dict = NULL;
GVariant *v;
GVariantIter i; GVariantIter i;
const char *property; const char *property;
v_properties = _nm_dbus_proxy_call_finish (proxy, v_properties = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (source),
result, result,
G_VARIANT_TYPE ("(a{sv})"), G_VARIANT_TYPE ("(a{sv})"),
&error); &error);
if ( !v_properties
&& g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
self = NM_MODEM_OFONO (user_data);
priv = NM_MODEM_OFONO_GET_PRIVATE (self);
g_clear_object (&priv->connman_proxy_cancellable);
if (!v_properties) { if (!v_properties) {
g_dbus_error_strip_remote_error (error); g_dbus_error_strip_remote_error (error);
_LOGW ("error getting connman properties: %s", error->message); _LOGW ("error getting connman properties: %s", error->message);
g_error_free (error);
return; return;
} }
@@ -587,9 +601,48 @@ connman_get_properties_done (GDBusProxy *proxy, GAsyncResult *result, gpointer u
handle_connman_property (NULL, property, v, self); handle_connman_property (NULL, property, v, self);
g_variant_unref (v); g_variant_unref (v);
} }
}
g_variant_unref (v_dict); static void
g_variant_unref (v_properties); _connman_proxy_new_cb (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
NMModemOfono *self;
NMModemOfonoPrivate *priv;
gs_free_error GError *error = NULL;
GDBusProxy *proxy;
proxy = g_dbus_proxy_new_for_bus_finish (result, &error);
if ( !proxy
&& g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
self = user_data;
priv = NM_MODEM_OFONO_GET_PRIVATE (self);
if (!proxy) {
_LOGW ("failed to create ConnectionManager proxy: %s", error->message);
g_clear_object (&priv->connman_proxy_cancellable);
return;
}
priv->connman_proxy = proxy;
_nm_dbus_signal_connect (priv->connman_proxy,
"PropertyChanged",
G_VARIANT_TYPE ("(sv)"),
G_CALLBACK (connman_property_changed),
self);
g_dbus_proxy_call (priv->connman_proxy,
"GetProperties",
NULL,
G_DBUS_CALL_FLAGS_NONE,
20000,
priv->connman_proxy_cancellable,
connman_get_properties_done,
self);
} }
static void static void
@@ -599,11 +652,13 @@ handle_connman_iface (NMModemOfono *self, gboolean found)
_LOGD ("ConnectionManager interface %sfound", found ? "" : "not "); _LOGD ("ConnectionManager interface %sfound", found ? "" : "not ");
if (!found && priv->connman_proxy) { if (!found && (priv->connman_proxy || priv->connman_proxy_cancellable)) {
_LOGI ("ConnectionManager interface disappeared"); _LOGI ("ConnectionManager interface disappeared");
nm_clear_g_cancellable (&priv->connman_proxy_cancellable);
g_signal_handlers_disconnect_by_data (priv->connman_proxy, NM_MODEM_OFONO (self)); if (priv->connman_proxy) {
g_clear_object (&priv->connman_proxy); g_signal_handlers_disconnect_by_data (priv->connman_proxy, self);
g_clear_object (&priv->connman_proxy);
}
/* The connection manager proxy disappeared, we should /* The connection manager proxy disappeared, we should
* consider the modem disabled. * consider the modem disabled.
@@ -611,41 +666,21 @@ handle_connman_iface (NMModemOfono *self, gboolean found)
priv->gprs_attached = FALSE; priv->gprs_attached = FALSE;
update_modem_state (self); update_modem_state (self);
} else if (found && !priv->connman_proxy) { } else if (found && (!priv->connman_proxy && !priv->connman_proxy_cancellable)) {
GError *error = NULL;
_LOGI ("found new ConnectionManager interface"); _LOGI ("found new ConnectionManager interface");
priv->connman_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, priv->connman_proxy_cancellable = g_cancellable_new ();
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
| G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
NULL, /* GDBusInterfaceInfo */
OFONO_DBUS_SERVICE,
nm_modem_get_path (NM_MODEM (self)),
OFONO_DBUS_INTERFACE_CONNECTION_MANAGER,
NULL, /* GCancellable */
&error);
if (priv->connman_proxy == NULL) {
_LOGW ("failed to create ConnectionManager proxy: %s", error->message);
g_error_free (error);
return;
}
/* Watch for custom ofono PropertyChanged signals */ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
_nm_dbus_signal_connect (priv->connman_proxy, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
"PropertyChanged", | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
G_VARIANT_TYPE ("(sv)"), NULL, /* GDBusInterfaceInfo */
G_CALLBACK (connman_property_changed), OFONO_DBUS_SERVICE,
self); nm_modem_get_path (NM_MODEM (self)),
OFONO_DBUS_INTERFACE_CONNECTION_MANAGER,
g_dbus_proxy_call (priv->connman_proxy, priv->connman_proxy_cancellable,
"GetProperties", _connman_proxy_new_cb,
NULL, NULL);
G_DBUS_CALL_FLAGS_NONE,
20000,
NULL,
(GAsyncReadyCallback) connman_get_properties_done,
g_object_ref (self));
} }
} }
@@ -1201,6 +1236,7 @@ dispose (GObject *object)
NMModemOfono *self = NM_MODEM_OFONO (object); NMModemOfono *self = NM_MODEM_OFONO (object);
NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self);
nm_clear_g_cancellable (&priv->connman_proxy_cancellable);
nm_clear_g_cancellable (&priv->sim_proxy_cancellable); nm_clear_g_cancellable (&priv->sim_proxy_cancellable);
if (priv->connect_properties) { if (priv->connect_properties) {
@@ -1215,7 +1251,11 @@ dispose (GObject *object)
g_clear_object (&priv->modem_proxy); g_clear_object (&priv->modem_proxy);
} }
g_clear_object (&priv->connman_proxy); if (priv->connman_proxy) {
g_signal_handlers_disconnect_by_data (priv->connman_proxy, self);
g_clear_object (&priv->connman_proxy);
}
g_clear_object (&priv->context_proxy); g_clear_object (&priv->context_proxy);
if (priv->sim_proxy) { if (priv->sim_proxy) {