iface-modem-location: handle enabling/disabling location gathering
This commit is contained in:
@@ -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,
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user