Commit 0a871109 authored by Mohammed Sadiq's avatar Mohammed Sadiq

mm-provider: Fix loading locked modems on unlock

Keep an eye on every modem found and see if any of those modem
gets/loses voice feature some time later.

This will help find modems that are locked when found and whose
voice feature will be enabled only once it is unlocked.

Also, remove handling ::interface-added and ::interface-removed
which was not done right (it was checking for interfaces added to
ModemManager, not individual modems)

Fixes Librem5/calls#94
parent 10d46d21
Pipeline #50671 passed with stages
in 2 minutes and 48 seconds
......@@ -44,6 +44,8 @@ struct _CallsMMProvider
MMManager *mm;
/** Map of D-Bus object paths to origins */
GHashTable *origins;
/* All MMObject list */
GListStore *modem_list;
};
static void calls_mm_provider_message_source_interface_init (CallsProviderInterface *iface);
......@@ -63,6 +65,40 @@ enum {
PROP_LAST_PROP,
};
/*
* modem_get_item_position:
* @model: A #GListModel
* @item: A #GObject or derived object.
*
* Get the position of @item in @model.
* This is an O(n) operation.
*/
static gint
modem_get_item_position (GListModel *model,
gpointer item)
{
const gchar *path, *obj_path;
guint i, n_items;
g_return_val_if_fail (G_IS_LIST_MODEL (model), FALSE);
g_return_val_if_fail (item != NULL, FALSE);
path = g_dbus_object_get_object_path (G_DBUS_OBJECT (item));
n_items = g_list_model_get_n_items (model);
for (i = 0; i < n_items; i++)
{
g_autoptr(GDBusObject) object = NULL;
object = g_list_model_get_item (model, i);
obj_path = g_dbus_object_get_object_path (object);
if (g_strcmp0 (obj_path, path) == 0)
return i;
}
return -1;
}
static const gchar *
get_name (CallsProvider *iface)
......@@ -149,35 +185,14 @@ add_origin (CallsMMProvider *self,
update_status (self);
}
static void
interface_added_cb (CallsMMProvider *self,
GDBusObject *object,
GDBusInterface *interface)
{
GDBusInterfaceInfo *info;
info = g_dbus_interface_get_info (interface);
g_debug ("ModemManager interface `%s' found on object `%s'",
info->name,
g_dbus_object_get_object_path (object));
if (g_strcmp0 (info->name,
"org.freedesktop.ModemManager1.Modem.Voice") == 0)
{
add_origin (self, object);
}
}
static void
remove_modem_object (CallsMMProvider *self,
const gchar *path,
GDBusObject *object)
remove_origin (CallsMMProvider *self,
GDBusObject *object)
{
gpointer *origin;
const gchar *path;
path = g_dbus_object_get_object_path (object);
origin = g_hash_table_lookup (self->origins, path);
if (!origin)
{
......@@ -194,25 +209,43 @@ remove_modem_object (CallsMMProvider *self,
update_status (self);
}
static void
interface_removed_cb (CallsMMProvider *self,
GDBusObject *object,
GDBusInterface *interface)
void
modem_voice_changed_cb (CallsMMProvider *self,
GParamSpec *pspec,
MMObject *mm_object)
{
GDBusObject *object;
MMModemVoice *mm_voice;
const gchar *path;
GDBusInterfaceInfo *info;
g_assert (CALLS_IS_MM_PROVIDER (self));
g_assert (MM_IS_OBJECT (mm_object));
object = G_DBUS_OBJECT (mm_object);
mm_voice = mm_object_peek_modem_voice (mm_object);
path = g_dbus_object_get_object_path (object);
info = g_dbus_interface_get_info (interface);
g_debug ("ModemManager interface `%s' removed on object `%s'",
info->name, path);
if (!mm_voice && g_hash_table_contains (self->origins, path))
remove_origin (self, object);
if (mm_voice && !g_hash_table_contains (self->origins, path))
add_origin (self, object);
}
if (g_strcmp0 (info->name,
"org.freedesktop.ModemManager1.Modem.Voice") != 0)
static void
remove_modem_object (CallsMMProvider *self,
const gchar *path,
GDBusObject *object)
{
gint index;
remove_origin (self, object);
index = modem_get_item_position (G_LIST_MODEL (self->modem_list), object);
if (index != -1)
{
remove_modem_object (self, path, object);
g_list_store_remove (self->modem_list, index);
}
}
......@@ -220,16 +253,27 @@ interface_removed_cb (CallsMMProvider *self,
static void
add_mm_object (CallsMMProvider *self, GDBusObject *object)
{
GList *ifaces, *node;
MMModemVoice *mm_voice;
MMObject *mm_obj;
gint index;
mm_obj = MM_OBJECT (object);
index = modem_get_item_position (G_LIST_MODEL (self->modem_list), mm_obj);
mm_voice = mm_object_peek_modem_voice (mm_obj);
ifaces = g_dbus_object_get_interfaces (object);
for (node = ifaces; node; node = node->next)
if (index == -1)
{
interface_added_cb (self, object,
G_DBUS_INTERFACE (node->data));
g_list_store_append (self->modem_list, mm_obj);
}
g_list_free_full (ifaces, g_object_unref);
g_signal_connect_object (mm_obj, "notify::modem-voice",
G_CALLBACK (modem_voice_changed_cb),
self, G_CONNECT_SWAPPED);
if (mm_voice)
{
add_origin (self, object);
}
}
......@@ -288,12 +332,6 @@ mm_manager_new_cb (GDBusConnection *connection,
}
g_signal_connect_swapped (G_DBUS_OBJECT_MANAGER (self->mm),
"interface-added",
G_CALLBACK (interface_added_cb), self);
g_signal_connect_swapped (G_DBUS_OBJECT_MANAGER (self->mm),
"interface-removed",
G_CALLBACK (interface_removed_cb), self);
g_signal_connect_swapped (G_DBUS_OBJECT_MANAGER (self->mm),
"object-added",
G_CALLBACK (object_added_cb), self);
......@@ -418,6 +456,7 @@ finalize (GObject *object)
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
CallsMMProvider *self = CALLS_MM_PROVIDER (object);
g_object_unref (self->modem_list);
g_hash_table_unref (self->origins);
g_free (self->status);
......@@ -461,6 +500,7 @@ calls_mm_provider_provider_interface_init (CallsProviderInterface *iface)
static void
calls_mm_provider_init (CallsMMProvider *self)
{
self->modem_list = g_list_store_new (MM_TYPE_OBJECT);
self->status = g_strdup (_("Initialised"));
self->origins = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment