Commit f7d8460e authored by Jussi Kukkonen's avatar Jussi Kukkonen

Start of some intelligence in client

parent 73628833
......@@ -158,6 +158,22 @@ typedef enum _GeoclueResourceFlags {
GEOCLUE_RESOURCE_FLAGS_GPS = 1 << 1,
} GeoclueResourceFlags;
/**
* GeoclueNetworkStatus:
*
* Enumeration for current network status.
*
**/
typedef enum {
GEOCLUE_CONNECTIVITY_UNKNOWN,
GEOCLUE_CONNECTIVITY_OFFLINE,
GEOCLUE_CONNECTIVITY_ACQUIRING,
GEOCLUE_CONNECTIVITY_ONLINE,
} GeoclueNetworkStatus;
void geoclue_types_init (void);
#endif
......@@ -40,6 +40,14 @@ finalize (GObject *object)
((GObjectClass *) gc_master_client_parent_class)->finalize (object);
}
static void
status_changed (GcMasterProvider *provider,
GeoclueStatus status,
GcMasterClient *client)
{
g_debug ("client: provider status changed");
}
static void
position_changed (GcMasterProvider *provider,
GeocluePositionFields fields,
......@@ -80,56 +88,72 @@ gc_iface_master_client_set_requirements (GcMasterClient *client,
GeoclueResourceFlags allowed_resources,
GError **error)
{
GList *providers = NULL;
client->min_accuracy = min_accuracy;
client->min_time = min_time;
client->require_updates = require_updates;
client->allowed_resources = allowed_resources;
/* position provider */
providers = gc_master_get_providers (GC_IFACE_POSITION,
min_accuracy,
require_updates,
allowed_resources,
NULL);
g_debug ("%d position providers matching requirements found", g_list_length (providers));
if (!providers) {
client->position_providers =
gc_master_get_providers (GC_IFACE_POSITION,
min_accuracy,
require_updates,
allowed_resources,
NULL);
g_debug ("%d position providers matching requirements found",
g_list_length (client->position_providers));
if (!client->position_providers) {
// TODO: should have a return value to indicate provider existence?
} else {
GList *p = client->position_providers;
/* TODO: choose the most accurate provider that is also available */
/* TODO: connect to the status signal of current provider,
* change provider if it goes offline */
/* TODO: connect to all providers status signals,
* change provider if a better than current becomes available */
while (p) {
GcMasterProvider *provider = p->data;
g_signal_connect (G_OBJECT (provider),
"status-changed",
G_CALLBACK (status_changed),
client);
/* choose the most accurate provider that is available or acquiring */
if ((!client->position_provider) &&
(gc_master_provider_get_status (provider) >= GEOCLUE_STATUS_ACQUIRING)) {
client->position_provider = provider;
g_signal_connect (G_OBJECT (client->position_provider),
"position-changed",
G_CALLBACK (position_changed),
client);
}
p = p->next;
}
/* choose the most accurate provider (first one) */
client->position_provider = providers->data;
g_signal_connect (G_OBJECT (client->position_provider),
"position-changed",
G_CALLBACK (position_changed),
client);
g_list_free (providers);
}
/* Address provider */
providers = gc_master_get_providers (GC_IFACE_ADDRESS,
min_accuracy,
require_updates,
allowed_resources,
NULL);
g_debug ("%d address providers matching requirements found", g_list_length (providers));
if (!providers) {
client->address_providers =
gc_master_get_providers (GC_IFACE_ADDRESS,
min_accuracy,
require_updates,
allowed_resources,
NULL);
g_debug ("%d address providers matching requirements found",
g_list_length (client->address_providers));
if (!client->address_providers) {
// TODO: should have a return value to indicate provider existence?
} else {
/* choose the most accurate provider (first one) */
client->address_provider = providers->data;
client->address_provider = client->address_providers->data;
g_signal_connect (G_OBJECT (client->address_provider),
"address-changed",
G_CALLBACK (address_changed),
client);
g_list_free (providers);
}
return TRUE;
......
......@@ -31,6 +31,8 @@ typedef struct {
GcMasterProvider *address_provider;
GList *position_providers;
GList *address_providers;
} GcMasterClient;
typedef struct {
......
......@@ -55,7 +55,7 @@ geoclue_connectivity_get_type (void)
return type;
}
int
GeoclueNetworkStatus
geoclue_connectivity_get_status (GeoclueConnectivity *self)
{
return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_status (self);
......
......@@ -10,16 +10,10 @@
#define _GEOCLUE_CONNECTIVITY_H
#include <glib-object.h>
#include <geoclue/geoclue-types.h>
G_BEGIN_DECLS
typedef enum {
GEOCLUE_CONNECTIVITY_UNKNOWN,
GEOCLUE_CONNECTIVITY_OFFLINE,
GEOCLUE_CONNECTIVITY_ACQUIRING,
GEOCLUE_CONNECTIVITY_ONLINE,
} GeoclueNetworkStatus;
#define GEOCLUE_TYPE_CONNECTIVITY (geoclue_connectivity_get_type ())
#define GEOCLUE_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_CONNECTIVITY, GeoclueConnectivity))
......@@ -43,7 +37,7 @@ struct _GeoclueConnectivityInterface {
GType geoclue_connectivity_get_type (void);
int geoclue_connectivity_get_status (GeoclueConnectivity *self);
GeoclueNetworkStatus geoclue_connectivity_get_status (GeoclueConnectivity *self);
void
geoclue_connectivity_emit_status_changed (GeoclueConnectivity *self,
......
This diff is collapsed.
#ifndef MASTER_PROVIDER_H
#define MASTER_PROVIDER_H
#include <geoclue/geoclue-provider.h>
#include <geoclue/geoclue-types.h>
#include <geoclue/geoclue-accuracy.h>
#include "connectivity.h"
G_BEGIN_DECLS
......@@ -26,6 +28,8 @@ typedef struct _GcMasterProvider {
typedef struct _GcMasterProviderClass {
GeoclueProviderClass provider_class;
void (* status_changed) (GcMasterProvider *master_provider,
GeoclueStatus status);
void (* position_changed) (GcMasterProvider *master_provider,
GeocluePositionFields fields,
int timestamp,
......@@ -42,7 +46,7 @@ typedef struct _GcMasterProviderClass {
GType gc_master_provider_get_type (void);
GcMasterProvider *gc_master_provider_new (const char *filename,
gboolean network_status_events);
GeoclueConnectivity *connectivity);
gint gc_master_provider_compare_by_accuracy (GcMasterProvider *a, GcMasterProvider *b);
......@@ -51,9 +55,11 @@ gboolean gc_master_provider_is_good (GcMasterProvider *provider,
GeoclueAccuracyLevel min_accuracy,
gboolean need_update,
GeoclueResourceFlags allowed_resources);
void gc_master_provider_network_status_changed (GcMasterProvider *provider,
GeoclueStatus status);
GeoclueNetworkStatus status);
GeoclueNetworkStatus gc_master_provider_get_status (GcMasterProvider *provider);
GeocluePositionFields gc_master_provider_get_position (GcMasterProvider *master_provider,
int *timestamp,
......
......@@ -108,7 +108,8 @@ gc_master_add_new_provider (GcMaster *master,
GcMasterProvider *provider;
provider = gc_master_provider_new (filename,
master->connectivity != NULL);
master->connectivity);
if (!provider) {
g_warning ("Loading from %s failed", filename);
return;
......@@ -161,37 +162,6 @@ gc_master_load_providers (GcMaster *master)
g_dir_close (dir);
}
static int ConnectivityStatusToProviderStatus[] = {
GEOCLUE_STATUS_UNAVAILABLE, /*GEOCLUE_CONNECTIVITY_UNKNOWN,*/
GEOCLUE_STATUS_UNAVAILABLE, /*GEOCLUE_CONNECTIVITY_OFFLINE,*/
GEOCLUE_STATUS_ACQUIRING, /*GEOCLUE_CONNECTIVITY_ACQUIRING,*/
GEOCLUE_STATUS_AVAILABLE /*GEOCLUE_CONNECTIVITY_ONLINE,*/
};
static void
network_status_changed (GeoclueConnectivity *connectivity,
GeoclueNetworkStatus status,
GcMaster *master)
{
/* TODO: connectivity stuff should maybe have some latency
* so we wouldn't start this on any 2sec network problems */
GList *l;
GeoclueStatus gc_status;
if (providers == NULL) {
return;
}
gc_status = ConnectivityStatusToProviderStatus[status];
for (l = providers; l; l = l->next) {
GcMasterProvider *provider = l->data;
/* might be nicer to do this with a signal, but ... */
gc_master_provider_network_status_changed (provider,
gc_status);
}
}
static void
gc_master_init (GcMaster *master)
{
......@@ -213,8 +183,6 @@ gc_master_init (GcMaster *master)
master->connectivity = GEOCLUE_CONNECTIVITY (g_object_new (GEOCLUE_TYPE_CONIC, NULL));
#endif
#endif
g_signal_connect (master->connectivity, "status-changed",
G_CALLBACK (network_status_changed), master);
gc_master_load_providers (master);
}
......
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