Commit 92369a91 authored by Zeeshan Ali's avatar Zeeshan Ali

Revert "location-source: Make start/stop explicit"

This basically reverts commit 88d42b44
but had to be heavily rebased/changed.

Since all actual location sources are now singletons, one fundamental new
change is that each source now keeps a count of start requests and don't
actually start or stop until this count reaches 1 or 0, respectively.

Conflicts:
	src/gclue-locator.c
	src/gclue-service-client.c
	src/gclue-web-source.c
	src/gclue-wifi.c
parent ed851fd8
......@@ -30,17 +30,25 @@
* The interface all geolocation sources must implement.
**/
static gboolean
start_source (GClueLocationSource *source);
static gboolean
stop_source (GClueLocationSource *source);
G_DEFINE_ABSTRACT_TYPE (GClueLocationSource, gclue_location_source, G_TYPE_OBJECT)
struct _GClueLocationSourcePrivate
{
GeocodeLocation *location;
guint active_counter;
};
enum
{
PROP_0,
PROP_LOCATION,
PROP_ACTIVE,
LAST_PROP
};
......@@ -59,6 +67,11 @@ gclue_location_source_get_property (GObject *object,
g_value_set_object (value, source->priv->location);
break;
case PROP_ACTIVE:
g_value_set_boolean (value,
gclue_location_source_get_active (source));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
......@@ -91,6 +104,7 @@ gclue_location_source_finalize (GObject *object)
{
GClueLocationSourcePrivate *priv = GCLUE_LOCATION_SOURCE (object)->priv;
gclue_location_source_stop (GCLUE_LOCATION_SOURCE (object));
g_clear_object (&priv->location);
G_OBJECT_CLASS (gclue_location_source_parent_class)->finalize (object);
......@@ -101,6 +115,9 @@ gclue_location_source_class_init (GClueLocationSourceClass *klass)
{
GObjectClass *object_class;
klass->start = start_source;
klass->stop = stop_source;
object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gclue_location_source_get_property;
object_class->set_property = gclue_location_source_set_property;
......@@ -115,6 +132,15 @@ gclue_location_source_class_init (GClueLocationSourceClass *klass)
g_object_class_install_property (object_class,
PROP_LOCATION,
gParamSpecs[PROP_LOCATION]);
gParamSpecs[PROP_ACTIVE] = g_param_spec_boolean ("active",
"Active",
"Active",
FALSE,
G_PARAM_READABLE);
g_object_class_install_property (object_class,
PROP_ACTIVE,
gParamSpecs[PROP_ACTIVE]);
}
static void
......@@ -126,6 +152,72 @@ gclue_location_source_init (GClueLocationSource *source)
GClueLocationSourcePrivate);
}
static gboolean
start_source (GClueLocationSource *source)
{
source->priv->active_counter++;
if (source->priv->active_counter > 1) {
g_debug ("%s already active, not starting.",
G_OBJECT_TYPE_NAME (source));
return FALSE;
}
g_object_notify (G_OBJECT (source), "active");
g_debug ("%s now active", G_OBJECT_TYPE_NAME (source));
return TRUE;
}
static gboolean
stop_source (GClueLocationSource *source)
{
if (source->priv->active_counter == 0) {
g_debug ("%s already inactive, not stopping.",
G_OBJECT_TYPE_NAME (source));
return FALSE;
}
source->priv->active_counter--;
if (source->priv->active_counter > 0) {
g_debug ("%s still in use, not stopping.",
G_OBJECT_TYPE_NAME (source));
return FALSE;
}
g_object_notify (G_OBJECT (source), "active");
g_debug ("%s now inactive", G_OBJECT_TYPE_NAME (source));
return TRUE;
}
/**
* gclue_location_source_start:
* @source: a #GClueLocationSource
*
* Start searching for location and keep an eye on location changes.
**/
void
gclue_location_source_start (GClueLocationSource *source)
{
g_return_if_fail (GCLUE_IS_LOCATION_SOURCE (source));
GCLUE_LOCATION_SOURCE_GET_CLASS (source)->start (source);
}
/**
* gclue_location_source_stop:
* @source: a #GClueLocationSource
*
* Stop searching for location and no need to keep an eye on location changes
* anymore.
**/
void
gclue_location_source_stop (GClueLocationSource *source)
{
g_return_if_fail (GCLUE_IS_LOCATION_SOURCE (source));
GCLUE_LOCATION_SOURCE_GET_CLASS (source)->stop (source);
}
/**
* gclue_location_source_get_location:
* @source: a #GClueLocationSource
......@@ -165,3 +257,17 @@ gclue_location_source_set_location (GClueLocationSource *source,
g_object_notify (G_OBJECT (source), "location");
}
/**
* gclue_location_source_get_active:
* @source: a #GClueLocationSource
*
* Returns: TRUE if source is active, FALSE otherwise.
**/
gboolean
gclue_location_source_get_active (GClueLocationSource *source)
{
g_return_val_if_fail (GCLUE_IS_LOCATION_SOURCE (source), FALSE);
return (source->priv->active_counter > 0);
}
......@@ -51,15 +51,22 @@ struct _GClueLocationSource
struct _GClueLocationSourceClass
{
GObjectClass parent_class;
gboolean (*start) (GClueLocationSource *source);
gboolean (*stop) (GClueLocationSource *source);
};
GType gclue_location_source_get_type (void) G_GNUC_CONST;
void gclue_location_source_start (GClueLocationSource *source);
void gclue_location_source_stop (GClueLocationSource *source);
GeocodeLocation * gclue_location_source_get_location
(GClueLocationSource *source);
void gclue_location_source_set_location
(GClueLocationSource *source,
GeocodeLocation *location);
gboolean gclue_location_source_get_active
(GClueLocationSource *source);
G_END_DECLS
......
......@@ -44,6 +44,11 @@
* location sources from rest of the code
*/
static gboolean
gclue_locator_start (GClueLocationSource *source);
static gboolean
gclue_locator_stop (GClueLocationSource *source);
G_DEFINE_TYPE (GClueLocator, gclue_locator, GCLUE_TYPE_LOCATION_SOURCE)
struct _GClueLocatorPrivate
......@@ -63,16 +68,13 @@ enum
static GParamSpec *gParamSpecs[LAST_PROP];
static void
on_location_changed (GObject *gobject,
GParamSpec *pspec,
gpointer user_data)
set_location (GClueLocator *locator,
GeocodeLocation *location)
{
GClueLocationSource *locator = GCLUE_LOCATION_SOURCE (user_data);
GClueLocationSource *source = GCLUE_LOCATION_SOURCE (gobject);
GeocodeLocation *location, *cur_location;
GeocodeLocation *cur_location;
cur_location = gclue_location_source_get_location (locator);
location = gclue_location_source_get_location (source);
cur_location = gclue_location_source_get_location
(GCLUE_LOCATION_SOURCE (locator));
g_debug ("New location available");
......@@ -89,7 +91,39 @@ on_location_changed (GObject *gobject,
return;
}
gclue_location_source_set_location (locator, location);
gclue_location_source_set_location (GCLUE_LOCATION_SOURCE (locator),
location);
}
static void
on_location_changed (GObject *gobject,
GParamSpec *pspec,
gpointer user_data)
{
GClueLocator *locator = GCLUE_LOCATOR (user_data);
GClueLocationSource *source = GCLUE_LOCATION_SOURCE (gobject);
GeocodeLocation *location;
location = gclue_location_source_get_location (source);
set_location (locator, location);
}
static void
start_source (GClueLocator *locator,
GClueLocationSource *src)
{
GeocodeLocation *location;
g_signal_connect (G_OBJECT (src),
"notify::location",
G_CALLBACK (on_location_changed),
locator);
location = gclue_location_source_get_location (src);
if (gclue_location_source_get_active (src) && location != NULL)
set_location (locator, location);
gclue_location_source_start (src);
}
static void
......@@ -176,31 +210,21 @@ gclue_locator_constructed (GObject *object)
#endif
for (node = locator->priv->sources; node != NULL; node = node->next) {
GClueLocationSource *src = GCLUE_LOCATION_SOURCE (node->data);
GeocodeLocation *location;
location = gclue_location_source_get_location (src);
if (location != NULL)
gclue_location_source_set_location
(GCLUE_LOCATION_SOURCE (locator), location);
g_signal_connect (G_OBJECT (src),
"notify::location",
G_CALLBACK (on_location_changed),
locator);
if (submit_source != NULL && GCLUE_IS_WEB_SOURCE (src))
if (submit_source != NULL && GCLUE_IS_WEB_SOURCE (node->data))
gclue_web_source_set_submit_source
(GCLUE_WEB_SOURCE (src),
submit_source);
(GCLUE_WEB_SOURCE (node->data), submit_source);
}
}
static void
gclue_locator_class_init (GClueLocatorClass *klass)
{
GClueLocationSourceClass *source_class = GCLUE_LOCATION_SOURCE_CLASS (klass);
GObjectClass *object_class;
source_class->start = gclue_locator_start;
source_class->stop = gclue_locator_stop;
object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gclue_locator_get_property;
object_class->set_property = gclue_locator_set_property;
......@@ -229,6 +253,55 @@ gclue_locator_init (GClueLocator *locator)
GClueLocatorPrivate);
}
static gboolean
gclue_locator_start (GClueLocationSource *source)
{
GClueLocationSourceClass *base_class;
GClueLocator *locator;
GList *node;
g_return_val_if_fail (GCLUE_IS_LOCATOR (source), FALSE);
locator = GCLUE_LOCATOR (source);
base_class = GCLUE_LOCATION_SOURCE_CLASS (gclue_locator_parent_class);
if (!base_class->start (source))
return FALSE;
for (node = locator->priv->sources; node != NULL; node = node->next) {
GClueLocationSource *src = GCLUE_LOCATION_SOURCE (node->data);
start_source (locator, src);
}
return TRUE;
}
static gboolean
gclue_locator_stop (GClueLocationSource *source)
{
GClueLocationSourceClass *base_class;
GClueLocator *locator;
GList *node;
g_return_val_if_fail (GCLUE_IS_LOCATOR (source), FALSE);
locator = GCLUE_LOCATOR (source);
base_class = GCLUE_LOCATION_SOURCE_CLASS (gclue_locator_parent_class);
if (!base_class->stop (source))
return FALSE;
for (node = locator->priv->sources; node != NULL; node = node->next) {
GClueLocationSource *src = GCLUE_LOCATION_SOURCE (node->data);
g_signal_handlers_disconnect_by_func (G_OBJECT (src),
G_CALLBACK (on_location_changed),
locator);
gclue_location_source_stop (src);
}
return TRUE;
}
GClueLocator *
gclue_locator_new (GClueAccuracyLevel level)
{
......
......@@ -32,6 +32,11 @@
* Baseclass for all sources that use a modem through ModemManager.
**/
static gboolean
gclue_modem_source_start (GClueLocationSource *source);
static gboolean
gclue_modem_source_stop (GClueLocationSource *source);
G_DEFINE_ABSTRACT_TYPE (GClueModemSource, gclue_modem_source, GCLUE_TYPE_LOCATION_SOURCE)
struct _GClueModemSourcePrivate {
......@@ -88,8 +93,12 @@ gclue_modem_source_constructed (GObject *object);
static void
gclue_modem_source_class_init (GClueModemSourceClass *klass)
{
GClueLocationSourceClass *source_class = GCLUE_LOCATION_SOURCE_CLASS (klass);
GObjectClass *gsource_class = G_OBJECT_CLASS (klass);
source_class->start = gclue_modem_source_start;
source_class->stop = gclue_modem_source_stop;
gsource_class->finalize = gclue_modem_source_finalize;
gsource_class->constructed = gclue_modem_source_constructed;
......@@ -166,6 +175,48 @@ on_modem_enabled (GObject *source_object,
user_data);
}
static gboolean
gclue_modem_source_start (GClueLocationSource *source)
{
GClueLocationSourceClass *base_class;
g_return_val_if_fail (GCLUE_IS_MODEM_SOURCE (source), FALSE);
base_class = GCLUE_LOCATION_SOURCE_CLASS (gclue_modem_source_parent_class);
if (!base_class->start (source))
return FALSE;
if (GCLUE_MODEM_SOURCE (source)->priv->modem == NULL)
return FALSE;
mm_modem_enable (GCLUE_MODEM_SOURCE (source)->priv->modem,
GCLUE_MODEM_SOURCE (source)->priv->cancellable,
on_modem_enabled,
source);
return TRUE;
}
static gboolean
gclue_modem_source_stop (GClueLocationSource *source)
{
GClueLocationSourceClass *base_class;
g_return_val_if_fail (GCLUE_IS_MODEM_SOURCE (source), FALSE);
base_class = GCLUE_LOCATION_SOURCE_CLASS (gclue_modem_source_parent_class);
if (!base_class->stop (source))
return FALSE;
if (GCLUE_MODEM_SOURCE (source)->priv->modem == NULL)
return FALSE;
mm_modem_disable (GCLUE_MODEM_SOURCE (source)->priv->modem,
NULL,
NULL,
NULL);
return TRUE;
}
static void
on_mm_object_added (GDBusObjectManager *manager,
GDBusObject *object,
......@@ -200,10 +251,11 @@ on_mm_object_added (GDBusObjectManager *manager,
source->priv->modem = mm_object_get_modem (mm_object);
source->priv->modem_location = mm_object_get_modem_location (mm_object);
mm_modem_enable (source->priv->modem,
source->priv->cancellable,
on_modem_enabled,
user_data);
if (gclue_location_source_get_active (GCLUE_LOCATION_SOURCE (source)))
mm_modem_enable (source->priv->modem,
source->priv->cancellable,
on_modem_enabled,
user_data);
}
static void
......
......@@ -205,10 +205,7 @@ start_client (GClueServiceClient *client, GClueAccuracyLevel accuracy_level)
G_CALLBACK (on_locator_location_changed),
client);
/* In case locator already has a location */
on_locator_location_changed (G_OBJECT (priv->locator),
NULL,
client);
gclue_location_source_start (GCLUE_LOCATION_SOURCE (priv->locator));
}
static void
......
......@@ -36,6 +36,9 @@
* Baseclass for all sources that solely use a web resource for geolocation.
**/
static gboolean
gclue_web_source_start (GClueLocationSource *source);
struct _GClueWebSourcePrivate {
SoupSession *soup_session;
......@@ -103,6 +106,9 @@ on_network_changed (GNetworkMonitor *monitor,
GError *error = NULL;
gboolean last_available = web->priv->network_available;
if (!gclue_location_source_get_active (GCLUE_LOCATION_SOURCE (user_data)))
return;
web->priv->network_available = available;
if (last_available == available)
return; /* We already reacted to netork change */
......@@ -172,16 +178,16 @@ gclue_web_source_constructed (GObject *object)
"network-changed",
G_CALLBACK (on_network_changed),
object);
if (g_network_monitor_get_network_available (monitor))
on_network_changed (monitor, TRUE, object);
}
static void
gclue_web_source_class_init (GClueWebSourceClass *klass)
{
GClueLocationSourceClass *source_class = GCLUE_LOCATION_SOURCE_CLASS (klass);
GObjectClass *gsource_class = G_OBJECT_CLASS (klass);
source_class->start = gclue_web_source_start;
gsource_class->finalize = gclue_web_source_finalize;
gsource_class->constructed = gclue_web_source_constructed;
......@@ -220,6 +226,19 @@ gclue_web_source_refresh (GClueWebSource *source)
}
}
static gboolean
gclue_web_source_start (GClueLocationSource *source)
{
GClueLocationSourceClass *base_class;
base_class = GCLUE_LOCATION_SOURCE_CLASS (gclue_web_source_parent_class);
if (!base_class->start (source))
return FALSE;
gclue_web_source_refresh (GCLUE_WEB_SOURCE (source));
return TRUE;
}
static void
submit_query_callback (SoupSession *session,
SoupMessage *query,
......
......@@ -42,6 +42,11 @@
* configuration file so its easy to switch to Google's API.
**/
static gboolean
gclue_wifi_start (GClueLocationSource *source);
static gboolean
gclue_wifi_stop (GClueLocationSource *source);
struct _GClueWifiPrivate {
NMClient *client;
NMDeviceWifi *wifi_device;
......@@ -87,12 +92,16 @@ gclue_wifi_finalize (GObject *gwifi)
static void
gclue_wifi_class_init (GClueWifiClass *klass)
{
GClueWebSourceClass *source_class = GCLUE_WEB_SOURCE_CLASS (klass);
GClueWebSourceClass *web_class = GCLUE_WEB_SOURCE_CLASS (klass);
GClueLocationSourceClass *source_class = GCLUE_LOCATION_SOURCE_CLASS (klass);
GObjectClass *gwifi_class = G_OBJECT_CLASS (klass);
source_class->create_query = gclue_wifi_create_query;
source_class->create_submit_query = gclue_wifi_create_submit_query;
source_class->parse_response = gclue_wifi_parse_response;
source_class->start = gclue_wifi_start;
source_class->stop = gclue_wifi_stop;
web_class->create_query = gclue_wifi_create_query;
web_class->create_submit_query = gclue_wifi_create_submit_query;
web_class->parse_response = gclue_wifi_parse_response;
gwifi_class->finalize = gclue_wifi_finalize;
g_type_class_add_private (klass, sizeof (GClueWifiPrivate));
......@@ -197,7 +206,7 @@ connect_ap_signals (GClueWifi *wifi)
{
GClueWifiPrivate *priv = wifi->priv;
if (priv->ap_added_id != 0)
if (priv->ap_added_id != 0 || priv->wifi_device == NULL)
return;
priv->ap_added_id = g_signal_connect (priv->wifi_device,
......@@ -211,7 +220,7 @@ disconnect_ap_signals (GClueWifi *wifi)
{
GClueWifiPrivate *priv = wifi->priv;
if (priv->ap_added_id == 0)
if (priv->ap_added_id == 0 || priv->wifi_device == NULL)
return;
g_signal_handler_disconnect (priv->wifi_device, priv->ap_added_id);
......@@ -223,6 +232,36 @@ disconnect_ap_signals (GClueWifi *wifi)
}
}
static gboolean
gclue_wifi_start (GClueLocationSource *source)
{
GClueLocationSourceClass *base_class;
g_return_val_if_fail (GCLUE_IS_WIFI (source), FALSE);
base_class = GCLUE_LOCATION_SOURCE_CLASS (gclue_wifi_parent_class);
if (!base_class->start (source))
return FALSE;
connect_ap_signals (GCLUE_WIFI (source));
return TRUE;
}
static gboolean
gclue_wifi_stop (GClueLocationSource *source)
{
GClueLocationSourceClass *base_class;
g_return_val_if_fail (GCLUE_IS_WIFI (source), FALSE);
base_class = GCLUE_LOCATION_SOURCE_CLASS (gclue_wifi_parent_class);
if (!base_class->stop (source))
return FALSE;
disconnect_ap_signals (GCLUE_WIFI (source));
return TRUE;
}
static void
on_device_added (NMClient *client,
NMDevice *device,
......@@ -237,7 +276,8 @@ on_device_added (NMClient *client,
g_debug ("WiFi device '%s' added.",
nm_device_wifi_get_hw_address (wifi->priv->wifi_device));
connect_ap_signals (wifi);
if (gclue_location_source_get_active (GCLUE_LOCATION_SOURCE (wifi)))
connect_ap_signals (wifi);
}
static void
......
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