iface-modem-location: handle enabling/disabling location gathering

This commit is contained in:
Aleksander Morgado
2012-01-16 19:39:00 +01:00
parent d7f98cf277
commit 03c5f4e6fb
2 changed files with 458 additions and 3 deletions

View File

@@ -20,6 +20,10 @@
#include "mm-iface-modem-location.h"
#include "mm-log.h"
#define LOCATION_CONTEXT_TAG "location-context-tag"
static GQuark location_context_quark;
/*****************************************************************************/
void
@@ -30,14 +34,177 @@ mm_iface_modem_location_bind_simple_status (MMIfaceModemLocation *self,
/*****************************************************************************/
typedef struct {
MmGdbusModemLocation *skeleton;
GDBusMethodInvocation *invocation;
MMIfaceModemLocation *self;
} DbusCallContext;
static void
dbus_call_context_free (DbusCallContext *ctx)
{
g_object_unref (ctx->skeleton);
g_object_unref (ctx->invocation);
g_object_unref (ctx->self);
g_free (ctx);
}
static DbusCallContext *
dbus_call_context_new (MmGdbusModemLocation *skeleton,
GDBusMethodInvocation *invocation,
MMIfaceModemLocation *self)
{
DbusCallContext *ctx;
ctx = g_new (DbusCallContext, 1);
ctx->skeleton = g_object_ref (skeleton);
ctx->invocation = g_object_ref (invocation);
ctx->self = g_object_ref (self);
return ctx;
}
/*****************************************************************************/
typedef struct {
gboolean interface_enabled;
} LocationContext;
static LocationContext *
get_location_context (MMIfaceModemLocation *self)
{
LocationContext *ctx;
if (G_UNLIKELY (!location_context_quark))
location_context_quark = (g_quark_from_static_string (
LOCATION_CONTEXT_TAG));
ctx = g_object_get_qdata (G_OBJECT (self), location_context_quark);
if (!ctx) {
/* Create context and keep it as object data */
ctx = g_new0 (LocationContext, 1);
g_object_set_qdata_full (
G_OBJECT (self),
location_context_quark,
ctx,
(GDestroyNotify)g_free);
}
return ctx;
}
/*****************************************************************************/
static void
enable_location_gathering_ready (MMIfaceModemLocation *self,
GAsyncResult *res,
DbusCallContext *ctx)
{
GError *error = NULL;
if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering_finish (self,
res,
&error))
g_dbus_method_invocation_take_error (ctx->invocation, error);
else {
mm_gdbus_modem_location_set_enabled (ctx->skeleton, TRUE);
mm_gdbus_modem_location_complete_enable (ctx->skeleton,
ctx->invocation);
}
dbus_call_context_free (ctx);
}
static void
disable_location_gathering_ready (MMIfaceModemLocation *self,
GAsyncResult *res,
DbusCallContext *ctx)
{
GError *error = NULL;
if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering_finish (self,
res,
&error))
g_dbus_method_invocation_take_error (ctx->invocation, error);
else {
mm_gdbus_modem_location_set_enabled (ctx->skeleton, FALSE);
mm_gdbus_modem_location_complete_enable (ctx->skeleton,
ctx->invocation);
}
dbus_call_context_free (ctx);
}
static gboolean
handle_enable (MmGdbusModemLocation *object,
handle_enable (MmGdbusModemLocation *skeleton,
GDBusMethodInvocation *invocation,
gboolean enable,
gboolean signal_location,
MMIfaceModemLocation *self)
{
return FALSE;
LocationContext *ctx;
ctx = get_location_context (self);
/* Enabling */
if (enable) {
mm_dbg ("Enabling location gathering%s...",
signal_location ? " (with signaling)" : "");
/* Update the new signal location value */
if (mm_gdbus_modem_location_get_signals_location (skeleton) != signal_location) {
mm_dbg ("%s location signaling",
signal_location ? "Enabling" : "Disabling");
mm_gdbus_modem_location_set_signals_location (skeleton, signal_location);
if (!signal_location)
/* If disabling, cleanup currently available value */
mm_gdbus_modem_location_set_location (skeleton, NULL);
}
/* If already enabled, just done */
if (mm_gdbus_modem_location_get_enabled (skeleton))
mm_gdbus_modem_location_complete_enable (skeleton, invocation);
/* Plugins can run custom actions to enable location gathering */
else if (ctx->interface_enabled &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering_finish)
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering (
self,
(GAsyncReadyCallback)enable_location_gathering_ready,
dbus_call_context_new (skeleton,
invocation,
self));
else {
/* If no plugin-specific setup needed or interface not yet enabled, just done */
mm_gdbus_modem_location_set_enabled (skeleton, TRUE);
mm_gdbus_modem_location_complete_enable (skeleton, invocation);
}
}
/* Disabling */
else {
mm_dbg ("Disabling location gathering...");
/* If already disabled, just done */
if (!mm_gdbus_modem_location_get_enabled (skeleton))
mm_gdbus_modem_location_complete_enable (skeleton, invocation);
/* Plugins can run custom actions to disable location gathering */
else if (ctx->interface_enabled &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering_finish)
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering (
self,
(GAsyncReadyCallback)disable_location_gathering_ready,
dbus_call_context_new (skeleton,
invocation,
self));
else {
/* If no plugin-specific setup needed, or interface not yet enabled, just done */
mm_gdbus_modem_location_set_enabled (skeleton, FALSE);
mm_gdbus_modem_location_complete_enable (skeleton, invocation);
}
}
return TRUE;
}
/*****************************************************************************/
@@ -52,6 +219,262 @@ handle_get_location (MmGdbusModemLocation *object,
/*****************************************************************************/
typedef struct _DisablingContext DisablingContext;
static void interface_disabling_step (DisablingContext *ctx);
typedef enum {
DISABLING_STEP_FIRST,
DISABLING_STEP_DISABLE_GATHERING,
DISABLING_STEP_LAST
} DisablingStep;
struct _DisablingContext {
MMIfaceModemLocation *self;
MMAtSerialPort *primary;
DisablingStep step;
GSimpleAsyncResult *result;
MmGdbusModemLocation *skeleton;
};
static DisablingContext *
disabling_context_new (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
DisablingContext *ctx;
ctx = g_new0 (DisablingContext, 1);
ctx->self = g_object_ref (self);
ctx->primary = g_object_ref (mm_base_modem_get_port_primary (MM_BASE_MODEM (self)));
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
disabling_context_new);
ctx->step = DISABLING_STEP_FIRST;
g_object_get (ctx->self,
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &ctx->skeleton,
NULL);
g_assert (ctx->skeleton != NULL);
return ctx;
}
static void
disabling_context_complete_and_free (DisablingContext *ctx)
{
g_simple_async_result_complete_in_idle (ctx->result);
g_object_unref (ctx->self);
g_object_unref (ctx->primary);
g_object_unref (ctx->result);
g_object_unref (ctx->skeleton);
g_free (ctx);
}
gboolean
mm_iface_modem_location_disable_finish (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error)
{
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}
static void
disabling_location_gathering_ready (MMIfaceModemLocation *self,
GAsyncResult *res,
DisablingContext *ctx)
{
GError *error = NULL;
if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->disable_location_gathering_finish (self,
res,
&error)) {
g_simple_async_result_take_error (ctx->result, error);
disabling_context_complete_and_free (ctx);
return;
}
mm_gdbus_modem_location_set_enabled (ctx->skeleton, FALSE);
/* Go on to next step */
ctx->step++;
interface_disabling_step (ctx);
}
static void
interface_disabling_step (DisablingContext *ctx)
{
LocationContext *location_context;
location_context = get_location_context (ctx->self);
switch (ctx->step) {
case DISABLING_STEP_FIRST:
/* Fall down to next step */
ctx->step++;
case DISABLING_STEP_DISABLE_GATHERING:
if (mm_gdbus_modem_location_get_enabled (ctx->skeleton) &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->disable_location_gathering &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->disable_location_gathering_finish) {
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->disable_location_gathering (
ctx->self,
(GAsyncReadyCallback)disabling_location_gathering_ready,
ctx);
return;
}
/* Fall down to next step */
ctx->step++;
case DISABLING_STEP_LAST:
/* We are done without errors! */
location_context->interface_enabled = FALSE;
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
disabling_context_complete_and_free (ctx);
return;
}
g_assert_not_reached ();
}
void
mm_iface_modem_location_disable (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
interface_disabling_step (disabling_context_new (self,
callback,
user_data));
}
/*****************************************************************************/
typedef struct _EnablingContext EnablingContext;
static void interface_enabling_step (EnablingContext *ctx);
typedef enum {
ENABLING_STEP_FIRST,
ENABLING_STEP_ENABLE_GATHERING,
ENABLING_STEP_LAST
} EnablingStep;
struct _EnablingContext {
MMIfaceModemLocation *self;
MMAtSerialPort *primary;
EnablingStep step;
GSimpleAsyncResult *result;
MmGdbusModemLocation *skeleton;
};
static EnablingContext *
enabling_context_new (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
EnablingContext *ctx;
ctx = g_new0 (EnablingContext, 1);
ctx->self = g_object_ref (self);
ctx->primary = g_object_ref (mm_base_modem_get_port_primary (MM_BASE_MODEM (self)));
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
enabling_context_new);
ctx->step = ENABLING_STEP_FIRST;
g_object_get (ctx->self,
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, &ctx->skeleton,
NULL);
g_assert (ctx->skeleton != NULL);
return ctx;
}
static void
enabling_context_complete_and_free (EnablingContext *ctx)
{
g_simple_async_result_complete_in_idle (ctx->result);
g_object_unref (ctx->self);
g_object_unref (ctx->primary);
g_object_unref (ctx->result);
g_object_unref (ctx->skeleton);
g_free (ctx);
}
gboolean
mm_iface_modem_location_enable_finish (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error)
{
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}
static void
enabling_location_gathering_ready (MMIfaceModemLocation *self,
GAsyncResult *res,
EnablingContext *ctx)
{
GError *error = NULL;
if (!MM_IFACE_MODEM_LOCATION_GET_INTERFACE (self)->enable_location_gathering_finish (self,
res,
&error)) {
g_simple_async_result_take_error (ctx->result, error);
enabling_context_complete_and_free (ctx);
return;
}
/* Go on to next step */
ctx->step++;
interface_enabling_step (ctx);
}
static void
interface_enabling_step (EnablingContext *ctx)
{
LocationContext *location_context;
location_context = get_location_context (ctx->self);
switch (ctx->step) {
case ENABLING_STEP_FIRST:
/* Fall down to next step */
ctx->step++;
case ENABLING_STEP_ENABLE_GATHERING:
if (mm_gdbus_modem_location_get_enabled (ctx->skeleton) &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->enable_location_gathering &&
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->enable_location_gathering_finish) {
MM_IFACE_MODEM_LOCATION_GET_INTERFACE (ctx->self)->enable_location_gathering (
ctx->self,
(GAsyncReadyCallback)enabling_location_gathering_ready,
ctx);
return;
}
/* Fall down to next step */
ctx->step++;
case ENABLING_STEP_LAST:
/* We are done without errors! */
location_context->interface_enabled = TRUE;
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
enabling_context_complete_and_free (ctx);
return;
}
g_assert_not_reached ();
}
void
mm_iface_modem_location_enable (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
interface_enabling_step (enabling_context_new (self,
callback,
user_data));
}
/*****************************************************************************/
typedef struct _InitializationContext InitializationContext;
static void interface_initialization_step (InitializationContext *ctx);
@@ -220,8 +643,8 @@ mm_iface_modem_location_initialize (MMIfaceModemLocation *self,
/* Set all initial property defaults */
mm_gdbus_modem_location_set_capabilities (skeleton, MM_MODEM_LOCATION_SOURCE_NONE);
mm_gdbus_modem_location_set_enabled (skeleton, TRUE);
mm_gdbus_modem_location_set_location (skeleton, NULL);
mm_gdbus_modem_location_set_signals_location (skeleton, FALSE);
mm_gdbus_modem_location_set_location (skeleton, NULL);
g_object_set (self,
MM_IFACE_MODEM_LOCATION_DBUS_SKELETON, skeleton,

View File

@@ -40,6 +40,22 @@ struct _MMIfaceModemLocation {
MMModemLocationSource (*load_capabilities_finish) (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error);
/* Enable location gathering (async) */
void (* enable_location_gathering) (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (*enable_location_gathering_finish) (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error);
/* Disable location gathering (async) */
void (* disable_location_gathering) (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (*disable_location_gathering_finish) (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error);
};
GType mm_iface_modem_location_get_type (void);
@@ -53,6 +69,22 @@ gboolean mm_iface_modem_location_initialize_finish (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error);
/* Enable Location interface (async) */
void mm_iface_modem_location_enable (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean mm_iface_modem_location_enable_finish (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error);
/* Disable Location interface (async) */
void mm_iface_modem_location_disable (MMIfaceModemLocation *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean mm_iface_modem_location_disable_finish (MMIfaceModemLocation *self,
GAsyncResult *res,
GError **error);
/* Shutdown Location interface */
void mm_iface_modem_location_shutdown (MMIfaceModemLocation *self);