diff options
-rw-r--r-- | libmm-glib/mm-manager.c | 2 | ||||
-rw-r--r-- | libmm-glib/mm-modem-time.c | 223 | ||||
-rw-r--r-- | libmm-glib/mm-modem-time.h | 37 |
3 files changed, 238 insertions, 24 deletions
diff --git a/libmm-glib/mm-manager.c b/libmm-glib/mm-manager.c index 8c484447..39f843c9 100644 --- a/libmm-glib/mm-manager.c +++ b/libmm-glib/mm-manager.c @@ -75,7 +75,7 @@ get_proxy_type (GDBusObjectManagerClient *manager, g_hash_table_insert (lookup_hash, "org.freedesktop.ModemManager1.Modem", GSIZE_TO_POINTER (MM_TYPE_MODEM)); g_hash_table_insert (lookup_hash, "org.freedesktop.ModemManager1.Modem.Messaging", GSIZE_TO_POINTER (MM_TYPE_MODEM_MESSAGING)); g_hash_table_insert (lookup_hash, "org.freedesktop.ModemManager1.Modem.Location", GSIZE_TO_POINTER (MM_TYPE_MODEM_LOCATION)); - g_hash_table_insert (lookup_hash, "org.freedesktop.ModemManager1.Modem.Time", GSIZE_TO_POINTER (MM_GDBUS_TYPE_MODEM_TIME_PROXY)); + g_hash_table_insert (lookup_hash, "org.freedesktop.ModemManager1.Modem.Time", GSIZE_TO_POINTER (MM_TYPE_MODEM_TIME)); g_hash_table_insert (lookup_hash, "org.freedesktop.ModemManager1.Modem.Firmware", GSIZE_TO_POINTER (MM_GDBUS_TYPE_MODEM_FIRMWARE_PROXY)); g_hash_table_insert (lookup_hash, "org.freedesktop.ModemManager1.Modem.Contacts", GSIZE_TO_POINTER (MM_GDBUS_TYPE_MODEM_CONTACTS_PROXY)); g_hash_table_insert (lookup_hash, "org.freedesktop.ModemManager1.Modem.ModemCdma", GSIZE_TO_POINTER (MM_TYPE_MODEM_CDMA)); diff --git a/libmm-glib/mm-modem-time.c b/libmm-glib/mm-modem-time.c index 15011a93..a9cab084 100644 --- a/libmm-glib/mm-modem-time.c +++ b/libmm-glib/mm-modem-time.c @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * + * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org> * Copyright (C) 2012 Google, Inc. */ @@ -26,6 +27,28 @@ #include "mm-modem-time.h" /** + * SECTION: mm-modem-time + * @title: MMModemTime + * @short_description: The Time interface + * + * The #MMModemTime is an object providing access to the methods, signals and + * properties of the Time interface. + * + * The Time interface is exposed on modems which support network time retrieval. + */ + +G_DEFINE_TYPE (MMModemTime, mm_modem_time, MM_GDBUS_TYPE_MODEM_TIME_PROXY) + +struct _MMModemTimePrivate { + /* Timezone */ + GMutex timezone_mutex; + guint timezone_id; + MMNetworkTimezone *timezone; +}; + +/*****************************************************************************/ + +/** * mm_modem_time_get_path: * @self: A #MMModemTime. * @@ -36,7 +59,7 @@ const gchar * mm_modem_time_get_path (MMModemTime *self) { - g_return_val_if_fail (G_IS_DBUS_PROXY (self), NULL); + g_return_val_if_fail (MM_IS_MODEM_TIME (self), NULL); RETURN_NON_EMPTY_CONSTANT_STRING ( g_dbus_proxy_get_object_path (G_DBUS_PROXY (self))); @@ -55,7 +78,7 @@ mm_modem_time_dup_path (MMModemTime *self) { gchar *value; - g_return_val_if_fail (G_IS_DBUS_PROXY (self), NULL); + g_return_val_if_fail (MM_IS_MODEM_TIME (self), NULL); g_object_get (G_OBJECT (self), "g-object-path", &value, @@ -63,6 +86,18 @@ mm_modem_time_dup_path (MMModemTime *self) RETURN_NON_EMPTY_STRING (value); } +/*****************************************************************************/ + +/** + * mm_modem_time_get_network_time_finish: + * @self: A #MMModemTime. + * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to mm_modem_enable(). + * @error: Return location for error or %NULL. + * + * Finishes an operation started with mm_modem_time_get_network_time(). + * + * Returns: A string containing the network time, or %NULL if @error is set. The returned value should be freed with g_free(). + */ gchar * mm_modem_time_get_network_time_finish (MMModemTime *self, GAsyncResult *res, @@ -70,28 +105,55 @@ mm_modem_time_get_network_time_finish (MMModemTime *self, { gchar *network_time = NULL; - g_return_val_if_fail (MM_GDBUS_IS_MODEM_TIME (self), NULL); + g_return_val_if_fail (MM_IS_MODEM_TIME (self), NULL); - if (!mm_gdbus_modem_time_call_get_network_time_finish (self, &network_time, res, error)) + if (!mm_gdbus_modem_time_call_get_network_time_finish (MM_GDBUS_MODEM_TIME (self), &network_time, res, error)) return NULL; return network_time; } +/** + * mm_modem_time_get_network_time: + * @self: A #MMModemTime. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL. + * @user_data: User data to pass to @callback. + * + * Asynchronously requests the current network time. + * + * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from. + * You can then call mm_modem_time_get_network_time_finish() to get the result of the operation. + * + * See mm_modem_time_get_network_time_sync() for the synchronous, blocking version of this method. + */ void mm_modem_time_get_network_time (MMModemTime *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - g_return_if_fail (MM_GDBUS_IS_MODEM_TIME (self)); + g_return_if_fail (MM_IS_MODEM_TIME (self)); - mm_gdbus_modem_time_call_get_network_time (self, + mm_gdbus_modem_time_call_get_network_time (MM_GDBUS_MODEM_TIME (self), cancellable, callback, user_data); } +/** + * mm_modem_time_get_network_time_sync: + * @self: A #MMModemTime. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Synchronously requests the current network time. + * + * The calling thread is blocked until a reply is received. See mm_modem_time_get_network_time() + * for the asynchronous version of this method. + * + * Returns: A string containing the network time, or %NULL if @error is set. The returned value should be freed with g_free(). + */ gchar * mm_modem_time_get_network_time_sync (MMModemTime *self, GCancellable *cancellable, @@ -99,25 +161,150 @@ mm_modem_time_get_network_time_sync (MMModemTime *self, { gchar *network_time = NULL; - g_return_val_if_fail (MM_GDBUS_IS_MODEM_TIME (self), NULL); + g_return_val_if_fail (MM_IS_MODEM_TIME (self), NULL); - if (!mm_gdbus_modem_time_call_get_network_time_sync (self, &network_time, cancellable, error)) + if (!mm_gdbus_modem_time_call_get_network_time_sync (MM_GDBUS_MODEM_TIME (self), &network_time, cancellable, error)) return NULL; return network_time; } +/*****************************************************************************/ + +static void +timezone_updated (MMModemTime *self, + GParamSpec *pspec) +{ + g_mutex_lock (&self->priv->timezone_mutex); + { + GVariant *dictionary; + + g_clear_object (&self->priv->timezone); + dictionary = mm_gdbus_modem_time_get_network_timezone (MM_GDBUS_MODEM_TIME (self)); + self->priv->timezone = (dictionary ? + mm_network_timezone_new_from_dictionary (dictionary, NULL) : + NULL); + } + g_mutex_unlock (&self->priv->timezone_mutex); +} + +static void +ensure_internal_timezone (MMModemTime *self, + MMNetworkTimezone **dup) +{ + g_mutex_lock (&self->priv->timezone_mutex); + { + /* If this is the first time ever asking for the object, setup the + * update listener and the initial object, if any. */ + if (!self->priv->timezone_id) { + GVariant *dictionary; + + dictionary = mm_gdbus_modem_time_dup_network_timezone (MM_GDBUS_MODEM_TIME (self)); + if (dictionary) { + self->priv->timezone = mm_network_timezone_new_from_dictionary (dictionary, NULL); + g_variant_unref (dictionary); + } + + /* No need to clear this signal connection when freeing self */ + self->priv->timezone_id = + g_signal_connect (self, + "notify::network-timezone", + G_CALLBACK (timezone_updated), + NULL); + } + + if (dup && self->priv->timezone) + *dup = g_object_ref (self->priv->timezone); + } + g_mutex_unlock (&self->priv->timezone_mutex); +} + +/** + * mm_modem_get_network_timezone: + * @self: A #MMModem. + * + * Gets the network timezone information. + * + * <warning>The values reported by @self are not updated when the values in the + * interface change. Instead, the client is expected to call + * mm_modem_get_network_timezone() again to get a new #MMNetworkTimezone with the + * new values.</warning> + * + * Returns: (transfer full) A #MMNetworkTimezone that must be freed with g_object_unref() or %NULL if unknown. + */ MMNetworkTimezone * mm_modem_time_get_network_timezone (MMModemTime *self) { - GVariant *dictionary; - MMNetworkTimezone *tz; - - g_return_val_if_fail (MM_GDBUS_IS_MODEM_TIME (self), NULL); + MMNetworkTimezone *tz = NULL; - dictionary = mm_gdbus_modem_time_dup_network_timezone (self); - tz = mm_network_timezone_new_from_dictionary (dictionary, NULL); - g_variant_unref (dictionary); + g_return_val_if_fail (MM_IS_MODEM_TIME (self), NULL); + ensure_internal_timezone (self, &tz); return tz; } + +/** + * mm_modem_peek_network_timezone: + * @self: A #MMModem. + * + * Gets the network timezone information. + * + * <warning>The returned value is only valid until the property changes so + * it is only safe to use this function on the thread where + * @self was constructed. Use mm_modem_get_network_timezone() if on another + * thread.</warning> + * + * Returns: (transfer none) A #MMNetworkTimezone. Do not free the returned value, it belongs to @self. + */ +MMNetworkTimezone * +mm_modem_time_peek_network_timezone (MMModemTime *self) +{ + g_return_val_if_fail (MM_IS_MODEM_TIME (self), NULL); + + ensure_internal_timezone (self, NULL); + return self->priv->timezone; +} + +/*****************************************************************************/ + +static void +mm_modem_time_init (MMModemTime *self) +{ + /* Setup private data */ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + MM_TYPE_MODEM_TIME, + MMModemTimePrivate); + g_mutex_init (&self->priv->timezone_mutex); +} + +static void +dispose (GObject *object) +{ + MMModemTime *self = MM_MODEM_TIME (object); + + g_clear_object (&self->priv->timezone); + + G_OBJECT_CLASS (mm_modem_time_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + MMModemTime *self = MM_MODEM_TIME (object); + + g_mutex_clear (&self->priv->timezone_mutex); + + G_OBJECT_CLASS (mm_modem_time_parent_class)->finalize (object); +} + +static void +mm_modem_time_class_init (MMModemTimeClass *modem_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (modem_class); + + g_type_class_add_private (object_class, sizeof (MMModemTimePrivate)); + + /* Virtual methods */ + object_class->finalize = finalize; + object_class->dispose = dispose; +} diff --git a/libmm-glib/mm-modem-time.h b/libmm-glib/mm-modem-time.h index 99afec7e..8718f014 100644 --- a/libmm-glib/mm-modem-time.h +++ b/libmm-glib/mm-modem-time.h @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * + * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org> * Copyright (C) 2012 Google, Inc. */ @@ -28,10 +29,35 @@ G_BEGIN_DECLS -typedef MmGdbusModemTime MMModemTime; -#define MM_TYPE_MODEM_TIME(o) MM_GDBUS_TYPE_MODEM_TIME (o) -#define MM_MODEM_TIME(o) MM_GDBUS_MODEM_TIME(o) -#define MM_IS_MODEM_TIME(o) MM_GDBUS_IS_MODEM_TIME(o) +#define MM_TYPE_MODEM_TIME (mm_modem_time_get_type ()) +#define MM_MODEM_TIME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_TIME, MMModemTime)) +#define MM_MODEM_TIME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_MODEM_TIME, MMModemTimeClass)) +#define MM_IS_MODEM_TIME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_TIME)) +#define MM_IS_MODEM_TIME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), MM_TYPE_MODEM_TIME)) +#define MM_MODEM_TIME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_MODEM_TIME, MMModemTimeClass)) + +typedef struct _MMModemTime MMModemTime; +typedef struct _MMModemTimeClass MMModemTimeClass; +typedef struct _MMModemTimePrivate MMModemTimePrivate; + +/** + * MMModemTime: + * + * The #MMModemTime structure contains private data and should only be accessed + * using the provided API. + */ +struct _MMModemTime { + /*< private >*/ + MmGdbusModemTimeProxy parent; + MMModemTimePrivate *priv; +}; + +struct _MMModemTimeClass { + /*< private >*/ + MmGdbusModemTimeProxyClass parent; +}; + +GType mm_modem_time_get_type (void); const gchar *mm_modem_time_get_path (MMModemTime *self); gchar *mm_modem_time_dup_path (MMModemTime *self); @@ -47,7 +73,8 @@ gchar *mm_modem_time_get_network_time_sync (MMModemTime *self, GCancellable *cancellable, GError **error); -MMNetworkTimezone *mm_modem_time_get_network_timezone (MMModemTime *self); +MMNetworkTimezone *mm_modem_time_peek_network_timezone (MMModemTime *self); +MMNetworkTimezone *mm_modem_time_get_network_timezone (MMModemTime *self); G_END_DECLS |