update for beta universally
[framework/location/libslp-location.git] / location / manager / location-hybrid.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "location-setting.h"
27 #include "location-log.h"
28
29 #include "module-internal.h"
30
31 #include "location-hybrid.h"
32 #include "location-marshal.h"
33 #include "location-ielement.h"
34 #include "location-signaling-util.h"
35 #include "location-common-util.h"
36
37 #include "location-gps.h"
38 #include "location-wps.h"
39 #include "location-sps.h"
40
41 typedef struct _LocationHybridPrivate {
42         gboolean is_started;
43         gboolean gps_enabled;
44         gboolean wps_enabled;
45         gboolean sps_enabled;
46         guint interval;
47         guint sat_timestamp;
48         LocationObject *gps;
49         LocationObject *wps;
50         LocationObject *sps;
51         gboolean enabled;
52         LocationMethod current_method;
53         LocationPosition *pos;
54         LocationVelocity *vel;
55         LocationAccuracy *acc;
56         LocationSatellite *sat;
57         GList* boundary_list;
58         ZoneStatus zone_status;
59
60 } LocationHybridPrivate;
61
62 enum {
63         PROP_0,
64         PROP_METHOD_TYPE,
65         PROP_LAST_POSITION,
66         PROP_UPDATE_INTERVAL,
67         PROP_BOUNDARY,
68         PROP_REMOVAL_BOUNDARY,
69         PROP_MAX
70 };
71
72 static guint32 signals[LAST_SIGNAL] = {0, };
73 static GParamSpec *properties[PROP_MAX] = {NULL, };
74
75 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_HYBRID, LocationHybridPrivate))
76
77 static void location_ielement_interface_init (LocationIElementInterface *iface);
78
79 G_DEFINE_TYPE_WITH_CODE (LocationHybrid, location_hybrid, G_TYPE_OBJECT,
80                          G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
81                          location_ielement_interface_init));
82
83
84 static LocationObject*
85 hybrid_get_update_method_obj (LocationHybridPrivate* priv)
86 {
87         if(!priv->sps && !priv->gps && !priv->wps) return NULL;
88
89         LocationObject* obj = NULL;
90         if (priv->sps_enabled) {
91                 LOCATION_LOGW("Current method is SPS");
92                 priv->current_method = LOCATION_METHOD_SPS;
93                 obj = priv->sps;
94         } else if (priv->gps_enabled) {
95                 LOCATION_LOGW("Current method is GPS");
96                 priv->current_method = LOCATION_METHOD_GPS;
97                 obj = priv->gps;
98         } else if (priv->wps_enabled) {
99                 LOCATION_LOGW("Current method is WPS");
100                 priv->current_method = LOCATION_METHOD_WPS;
101                 obj = priv->wps;
102         } else {
103                 LOCATION_LOGW("No current method available");
104                 priv->current_method = LOCATION_METHOD_HYBRID;
105                 obj = NULL;
106         }
107         return obj;
108 }
109
110 static gboolean
111 hybrid_is_equal_g_type_method(GType g_type, LocationMethod method)
112 {
113         if (g_type == LOCATION_TYPE_SPS && method == LOCATION_METHOD_SPS) return TRUE;
114         if (g_type == LOCATION_TYPE_GPS && method == LOCATION_METHOD_GPS) return TRUE;
115         if (g_type == LOCATION_TYPE_WPS && method == LOCATION_METHOD_WPS) return TRUE;
116         return FALSE;
117 }
118
119 static void
120 hybrid_update_sps(LocationHybrid* self,
121         guint type,
122         gpointer data,
123         gpointer accuracy)
124 {
125         LocationHybridPrivate* priv = GET_PRIVATE(self);
126         if (!priv->sps) return;
127         LOCATION_LOGD ("hybrid_update_sps");
128
129         switch (type) {
130                 case POSITION_UPDATED: {
131                         if (data) g_object_set(priv->sps, "position-base", data, NULL);
132                         if (priv->gps) {
133                                 LocationSatellite* sat = NULL;
134                                 g_object_get(priv->gps, "satellite", &sat, NULL);
135                                 if (sat) {
136                                         g_object_set(priv->sps, "satellite-info", sat, NULL);
137                                         location_satellite_free (sat);
138                                 }
139                         }
140                         if (accuracy) g_object_set(priv->sps, "accuracy-info", accuracy, NULL);
141                         break;
142                 }
143                 case VELOCITY_UPDATED:
144                         if (data) g_object_set(priv->sps, "velocity-base", data, NULL);
145                         if (accuracy) g_object_set(priv->sps, "accuracy-info", accuracy, NULL);
146                         break;
147         }
148 }
149
150 static void
151 hybrid_service_updated (GObject *obj,
152         guint type,
153         gpointer data,
154         gpointer accuracy,
155         gpointer self)
156 {
157         LOCATION_LOGD ("hybrid_service_updated");
158         LocationHybridPrivate* priv = GET_PRIVATE((LocationHybrid*)self);
159         GType g_type = G_TYPE_FROM_INSTANCE(obj);
160         if (g_type == LOCATION_TYPE_GPS) {
161                 if (type == SATELLITE_UPDATED) {
162                         LocationSatellite *sat = (LocationSatellite *) data;
163                         satellite_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->sat_timestamp), &(priv->sat), TRUE, sat);
164                 } else hybrid_update_sps((LocationHybrid*)self, type, data, accuracy);
165         }
166
167         if (hybrid_is_equal_g_type_method(g_type, priv->current_method)) {
168                 LocationAccuracy *acc = (LocationAccuracy*)accuracy;
169                 if (type == POSITION_UPDATED) {
170                         LocationPosition *pos = (LocationPosition*)data;
171                         position_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->pos), &(priv->acc), priv->boundary_list, &(priv->zone_status), TRUE, pos, acc);
172                 } else if (type == VELOCITY_UPDATED) {
173                         LocationVelocity *vel = (LocationVelocity*) data;
174                         velocity_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->vel), TRUE, vel, acc);
175                 }else LOCATION_LOGW ("Undefined GType updated");
176         }
177
178 }
179
180 static void
181 hybrid_service_enabled (GObject *obj,
182         guint status,
183         gpointer self)
184 {
185         LOCATION_LOGD ("hybrid_service_enabled");
186         LocationHybridPrivate* priv = GET_PRIVATE((LocationHybrid*)self);
187         GType g_type = G_TYPE_FROM_INSTANCE(obj);
188         if (g_type == LOCATION_TYPE_SPS)     priv->sps_enabled = TRUE;
189         else if(g_type == LOCATION_TYPE_GPS) priv->gps_enabled = TRUE;
190         else if(g_type == LOCATION_TYPE_WPS) priv->wps_enabled = TRUE;
191         else {
192                 LOCATION_LOGW("Undefined GType enabled");
193                 return;
194         }
195         hybrid_get_update_method_obj(priv);
196         if(priv->sps_enabled || priv->gps_enabled || priv->wps_enabled)
197                 enable_signaling(self, signals, &(priv->enabled), TRUE, status);
198 }
199
200 static void
201 hybrid_service_disabled (GObject *obj,
202         guint status,
203         gpointer self)
204 {
205         LOCATION_LOGD ("hybrid_service_disabled");
206         LocationHybridPrivate* priv = GET_PRIVATE((LocationHybrid*)self);
207         GType g_type = G_TYPE_FROM_INSTANCE(obj);
208         if (g_type == LOCATION_TYPE_SPS)     priv->sps_enabled = FALSE;
209         else if(g_type == LOCATION_TYPE_GPS) priv->gps_enabled = FALSE;
210         else if(g_type == LOCATION_TYPE_WPS) priv->wps_enabled = FALSE;
211         else {
212                 LOCATION_LOGW("Undefined GType disabled");
213                 return;
214         }
215         hybrid_get_update_method_obj(priv);
216         if(!priv->sps_enabled && !priv->gps_enabled && !priv->wps_enabled)
217                 enable_signaling(self, signals, &(priv->enabled), FALSE, status);
218 }
219
220 static int
221 location_hybrid_start (LocationHybrid *self)
222 {
223         LOCATION_LOGD("location_hybrid_start");
224
225         int ret_gps = LOCATION_ERROR_NONE;
226         int ret_wps = LOCATION_ERROR_NONE;
227         int ret_sps = LOCATION_ERROR_NONE;
228
229         LocationHybridPrivate* priv = GET_PRIVATE(self);
230         if (priv->is_started == TRUE)
231                 return LOCATION_ERROR_NONE;
232
233         if(priv->gps) ret_gps = location_start(priv->gps);
234         if(priv->wps) ret_wps = location_start(priv->wps);
235         if(priv->sps) ret_sps = location_start(priv->sps);
236
237         if (ret_gps != LOCATION_ERROR_NONE &&
238                 ret_wps != LOCATION_ERROR_NONE &&
239                 ret_sps != LOCATION_ERROR_NONE) {
240                 if (ret_gps == LOCATION_ERROR_NOT_ALLOWED ||
241                                 ret_wps == LOCATION_ERROR_NOT_ALLOWED ||
242                                 ret_sps == LOCATION_ERROR_NOT_ALLOWED) {
243                         priv->is_started = TRUE;
244                         return LOCATION_ERROR_NOT_ALLOWED;
245                 }
246                 else {
247                         return LOCATION_ERROR_NOT_AVAILABLE;
248                 }
249         }
250
251         priv->is_started = TRUE;
252         return LOCATION_ERROR_NONE;
253 }
254
255 static int
256 location_hybrid_stop (LocationHybrid *self)
257 {
258         LOCATION_LOGD("location_hybrid_stop");
259
260         LocationHybridPrivate* priv = GET_PRIVATE(self);
261         if( priv->is_started == FALSE)
262                 return LOCATION_ERROR_NONE;
263
264         int ret_gps = LOCATION_ERROR_NONE;
265         int ret_wps = LOCATION_ERROR_NONE;
266         int ret_sps = LOCATION_ERROR_NONE;
267
268         if(priv->gps) ret_gps = location_stop(priv->gps);
269         if(priv->wps) ret_wps = location_stop(priv->wps);
270         if(priv->sps) ret_sps = location_stop(priv->sps);
271
272         priv->is_started = FALSE;
273
274         if (ret_gps != LOCATION_ERROR_NONE &&
275                 ret_wps != LOCATION_ERROR_NONE &&
276                 ret_sps != LOCATION_ERROR_NONE)
277                 return LOCATION_ERROR_NOT_AVAILABLE;
278
279         return LOCATION_ERROR_NONE;
280 }
281
282 static void
283 location_hybrid_dispose (GObject *gobject)
284 {
285         LOCATION_LOGD("location_hybrid_dispose");
286         G_OBJECT_CLASS (location_hybrid_parent_class)->dispose (gobject);
287 }
288
289 static void
290 location_hybrid_finalize (GObject *gobject)
291 {
292         LOCATION_LOGD("location_hybrid_finalize");
293         LocationHybridPrivate* priv = GET_PRIVATE(gobject);
294
295         if (priv->gps) {
296                 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK (hybrid_service_enabled), gobject);
297                 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK (hybrid_service_disabled), gobject);
298                 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK (hybrid_service_updated), gobject);
299                 location_free(priv->gps);
300         }
301         if (priv->wps) {
302                 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK (hybrid_service_enabled), gobject);
303                 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK (hybrid_service_disabled), gobject);
304                 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK (hybrid_service_updated), gobject);
305                 location_free(priv->wps);
306         }
307         if (priv->sps) {
308                 g_signal_handlers_disconnect_by_func(priv->sps, G_CALLBACK (hybrid_service_enabled), gobject);
309                 g_signal_handlers_disconnect_by_func(priv->sps, G_CALLBACK (hybrid_service_disabled), gobject);
310                 g_signal_handlers_disconnect_by_func(priv->sps, G_CALLBACK (hybrid_service_updated), gobject);
311                 location_free(priv->sps);
312         }
313
314         G_OBJECT_CLASS (location_hybrid_parent_class)->finalize (gobject);
315 }
316
317 static void
318 location_hybrid_set_property (GObject *object,
319         guint property_id,
320         const GValue *value,
321         GParamSpec *pspec)
322 {
323         LocationHybridPrivate* priv = GET_PRIVATE(object);
324         if (!priv->gps && !priv->wps && !priv->sps) {
325                 LOCATION_LOGW("Set property is not available now");
326                 return;
327         }
328
329         int ret = 0;
330         switch (property_id){
331                 case PROP_BOUNDARY:{
332                         GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
333                         ret = set_prop_boundary(&priv->boundary_list, boundary_list);
334                         if(ret != 0) LOCATION_LOGD("Set boundary. Error[%d]", ret);
335                    break;
336                 }
337                 case PROP_REMOVAL_BOUNDARY: {
338                         LocationBoundary *req_boundary = (LocationBoundary*) g_value_dup_boxed(value);
339                         ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
340                         if(ret != 0) LOCATION_LOGD("Removal boundary. Error[%d]", ret);
341                         break;
342                 }
343                 case PROP_UPDATE_INTERVAL: {
344                         guint interval = g_value_get_uint(value);
345                         if(interval > 0) {
346                                 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
347                                         priv->interval = interval;
348                                 else
349                                         priv->interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
350
351                         }
352                         else
353                                 priv->interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
354                         break;
355                 }
356                 default:
357                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
358                         break;
359         }
360 }
361
362 static void
363 location_hybrid_get_property (GObject *object,
364         guint property_id,
365         GValue *value,
366         GParamSpec *pspec)
367 {
368         LocationHybridPrivate *priv = GET_PRIVATE (object);
369         if(!priv->gps && !priv->wps && !priv->sps){
370                 LOCATION_LOGW("Get property is not available now");
371                 return;
372         }
373
374         LOCATION_LOGW("Get Propery ID[%d]", property_id);
375
376         switch (property_id){
377         case PROP_METHOD_TYPE:
378                 g_value_set_int(value, priv->current_method);
379                 break;
380         case PROP_LAST_POSITION:
381                 g_value_set_boxed(value, priv->pos);
382                 break;
383         case PROP_BOUNDARY:
384                 g_value_set_pointer(value, g_list_first(priv->boundary_list));
385                 break;
386         case PROP_UPDATE_INTERVAL:
387                 g_value_set_uint(value, priv->interval);
388                 break;
389         default:
390                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
391                 break;
392         }
393 }
394
395 static int
396 location_hybrid_get_position (LocationHybrid *self,
397         LocationPosition **position,
398         LocationAccuracy **accuracy)
399 {
400         LOCATION_LOGD("location_hybrid_get_position");
401         setting_retval_if_fail(GPS_ENABLED);
402
403         LocationHybridPrivate *priv = GET_PRIVATE (self);
404         LocationObject *obj = hybrid_get_update_method_obj(priv);
405         if(!obj) return LOCATION_ERROR_NOT_AVAILABLE;
406         return location_get_position (obj, position, accuracy);
407 }
408
409 static int
410 location_hybrid_get_last_position (LocationHybrid *self,
411         LocationPosition **position,
412         LocationAccuracy **accuracy)
413 {
414         LOCATION_LOGD("location_hybrid_get_last_position");
415         setting_retval_if_fail(GPS_ENABLED);
416
417         int ret = LOCATION_ERROR_NONE;
418         LocationPosition *gps_pos = NULL, *wps_pos = NULL;
419         LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
420         LocationHybridPrivate *priv = GET_PRIVATE (self);
421
422         if (priv->gps) location_get_last_position (priv->gps, &gps_pos, &gps_acc);
423         if (priv->wps) location_get_last_position (priv->wps, &wps_pos, &wps_acc);
424
425         if (gps_pos && wps_pos) {
426                 if (wps_pos->timestamp > gps_pos->timestamp) {
427                         *position = wps_pos;
428                         *accuracy = wps_acc;
429                         location_position_free (gps_pos);
430                         location_accuracy_free (gps_acc);
431                 }
432                 else {
433                         *position = gps_pos;
434                         *accuracy = gps_acc;
435                         location_position_free (wps_pos);
436                         location_accuracy_free (wps_acc);
437                 }
438         } else if (gps_pos) {
439                 *position = gps_pos;
440                 *accuracy = gps_acc;
441         } else if (wps_pos) {
442                 *position = wps_pos;
443                 *accuracy = wps_acc;
444         } else {
445                 ret = LOCATION_ERROR_NOT_AVAILABLE;
446         }
447
448         return ret;
449 }
450
451 static int
452 location_hybrid_get_velocity (LocationHybrid *self,
453         LocationVelocity **velocity,
454         LocationAccuracy **accuracy)
455 {
456         LOCATION_LOGD("location_hybrid_get_velocity");
457         setting_retval_if_fail(GPS_ENABLED);
458
459         LocationHybridPrivate *priv = GET_PRIVATE (self);
460         LocationObject *obj = hybrid_get_update_method_obj(priv);
461         if(!obj) return LOCATION_ERROR_NOT_AVAILABLE;
462         return location_get_velocity (obj, velocity, accuracy);
463 }
464
465 static int
466 location_hybrid_get_last_velocity (LocationHybrid *self,
467         LocationVelocity **velocity,
468         LocationAccuracy **accuracy)
469 {
470         LOCATION_LOGD("location_hybrid_get_last_velocity");
471         setting_retval_if_fail(GPS_ENABLED);
472
473         int ret = LOCATION_ERROR_NONE;
474         LocationHybridPrivate *priv = GET_PRIVATE (self);
475         LocationVelocity *gps_vel = NULL, *wps_vel = NULL;
476         LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
477
478         if (priv->gps) location_get_last_velocity (priv->gps, &gps_vel, &gps_acc);
479         if (priv->wps) location_get_last_velocity (priv->wps, &wps_vel, &wps_acc);
480
481         if (gps_vel && wps_vel) {
482                 if (wps_vel->timestamp > gps_vel->timestamp) {
483                         *velocity = wps_vel;
484                         *accuracy = wps_acc;
485                         location_velocity_free (gps_vel);
486                         location_accuracy_free (gps_acc);
487                 } else {
488                         *velocity = gps_vel;
489                         *accuracy = gps_acc;
490                         location_velocity_free (wps_vel);
491                         location_accuracy_free (wps_acc);
492                 }
493         }
494         else if (gps_vel) {
495                 *velocity = gps_vel;
496                 *accuracy = gps_acc;
497         } else if (wps_vel) {
498                 *velocity = wps_vel;
499                 *accuracy = wps_acc;
500         } else {
501                 *velocity = NULL;
502                 *accuracy = NULL;
503                 ret = LOCATION_ERROR_NOT_AVAILABLE;
504         }
505
506         return ret;
507 }
508
509 static int
510 location_hybrid_get_satellite (LocationHybrid *self,
511         LocationSatellite **satellite)
512 {
513         LOCATION_LOGD("location_hybrid_get_satellite");
514         setting_retval_if_fail(GPS_ENABLED);
515
516         int ret = LOCATION_ERROR_NONE;
517         LocationHybridPrivate *priv = GET_PRIVATE (self);
518         if (priv->gps) ret = location_get_satellite (priv->gps, satellite);
519         else {
520                 *satellite = NULL;
521                 ret = LOCATION_ERROR_NOT_AVAILABLE;
522         }
523
524         return ret;
525 }
526
527 static int
528 location_hybrid_get_last_satellite (LocationHybrid *self,
529         LocationSatellite **satellite)
530 {
531         LOCATION_LOGD("location_hybrid_get_last_satellite");
532         setting_retval_if_fail(GPS_ENABLED);
533
534         int ret = LOCATION_ERROR_NONE;
535         LocationHybridPrivate *priv = GET_PRIVATE (self);
536
537         if (priv->gps) ret = location_get_last_satellite (priv->gps, satellite);
538         else {
539                 *satellite = NULL;
540                 ret = LOCATION_ERROR_NOT_AVAILABLE;
541         }
542
543         return ret;
544 }
545
546 static void
547 location_ielement_interface_init (LocationIElementInterface *iface)
548 {
549         iface->start = (TYPE_START_FUNC)location_hybrid_start;
550         iface->stop = (TYPE_STOP_FUNC)location_hybrid_stop;
551         iface->get_position = (TYPE_GET_POSITION)location_hybrid_get_position;
552         iface->get_last_position = (TYPE_GET_POSITION)location_hybrid_get_last_position;
553         iface->get_velocity = (TYPE_GET_VELOCITY)location_hybrid_get_velocity;
554         iface->get_last_velocity = (TYPE_GET_VELOCITY)location_hybrid_get_last_velocity;
555         iface->get_satellite = (TYPE_GET_SATELLITE)location_hybrid_get_satellite;
556         iface->get_last_satellite = (TYPE_GET_SATELLITE)location_hybrid_get_last_satellite;
557 }
558
559 static void
560 location_hybrid_init (LocationHybrid *self)
561 {
562         LOCATION_LOGD("location_hybrid_init");
563         LocationHybridPrivate* priv = GET_PRIVATE(self);
564
565         priv->is_started = FALSE;
566         priv->interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
567         priv->gps_enabled = FALSE;
568         priv->wps_enabled = FALSE;
569         priv->sps_enabled = FALSE;
570         priv->gps = NULL;
571         priv->wps = NULL;
572         priv->sps = NULL;
573
574         if(location_is_supported_method(LOCATION_METHOD_GPS)) priv->gps = location_new (LOCATION_METHOD_GPS);
575         if(location_is_supported_method(LOCATION_METHOD_WPS)) priv->wps = location_new (LOCATION_METHOD_WPS);
576         if(location_is_supported_method(LOCATION_METHOD_SPS)) priv->sps = location_new (LOCATION_METHOD_SPS);
577
578         if(priv->gps){
579                 g_signal_connect (priv->gps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self);
580                 g_signal_connect (priv->gps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self);
581                 g_signal_connect (priv->gps, "service-updated", G_CALLBACK(hybrid_service_updated), self);
582         }
583         if(priv->wps){
584                 g_signal_connect (priv->wps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self);
585                 g_signal_connect (priv->wps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self);
586                 g_signal_connect (priv->wps, "service-updated", G_CALLBACK(hybrid_service_updated), self);
587         }
588         if(priv->sps){
589                 g_signal_connect (priv->sps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self);
590                 g_signal_connect (priv->sps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self);
591                 g_signal_connect (priv->sps, "service-updated", G_CALLBACK(hybrid_service_updated), self);
592         }
593
594         priv->current_method = LOCATION_METHOD_HYBRID;
595         priv->enabled= FALSE;
596
597         priv->pos = NULL;
598         priv->vel = NULL;
599         priv->acc = NULL;
600         priv->zone_status = ZONE_STATUS_NONE;
601         priv->boundary_list = NULL;
602 }
603
604 static void
605 location_hybrid_class_init (LocationHybridClass *klass)
606 {
607         LOCATION_LOGD("location_hybrid_class_init");
608         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
609
610         gobject_class->set_property = location_hybrid_set_property;
611         gobject_class->get_property = location_hybrid_get_property;
612
613         gobject_class->dispose = location_hybrid_dispose;
614         gobject_class->finalize = location_hybrid_finalize;
615
616         g_type_class_add_private (klass, sizeof (LocationHybridPrivate));
617
618         signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
619                         G_TYPE_FROM_CLASS (klass),
620                         G_SIGNAL_RUN_FIRST |
621                         G_SIGNAL_NO_RECURSE,
622                         G_STRUCT_OFFSET (LocationHybridClass, enabled),
623                         NULL, NULL,
624                         location_VOID__UINT,
625                         G_TYPE_NONE, 1,
626                         G_TYPE_UINT);
627
628         signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
629                         G_TYPE_FROM_CLASS (klass),
630                         G_SIGNAL_RUN_FIRST |
631                         G_SIGNAL_NO_RECURSE,
632                         G_STRUCT_OFFSET (LocationHybridClass, disabled),
633                         NULL, NULL,
634                         location_VOID__UINT,
635                         G_TYPE_NONE, 1,
636                         G_TYPE_UINT);
637
638         signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
639                         G_TYPE_FROM_CLASS (klass),
640                         G_SIGNAL_RUN_FIRST |
641                         G_SIGNAL_NO_RECURSE,
642                         G_STRUCT_OFFSET (LocationHybridClass, updated),
643                         NULL, NULL,
644                         location_VOID__UINT_POINTER_POINTER,
645                         G_TYPE_NONE, 3,
646                         G_TYPE_UINT,
647                         G_TYPE_POINTER,
648                         G_TYPE_POINTER);
649
650         signals[ZONE_IN] = g_signal_new ("zone-in",
651                         G_TYPE_FROM_CLASS (klass),
652                         G_SIGNAL_RUN_FIRST |
653                         G_SIGNAL_NO_RECURSE,
654                         G_STRUCT_OFFSET (LocationHybridClass, zone_in),
655                         NULL, NULL,
656                         location_VOID__UINT_POINTER_POINTER,
657                         G_TYPE_NONE, 3,
658                         G_TYPE_UINT,
659                         G_TYPE_POINTER,
660                         G_TYPE_POINTER);
661
662         signals[ZONE_OUT] = g_signal_new ("zone-out",
663                         G_TYPE_FROM_CLASS (klass),
664                         G_SIGNAL_RUN_FIRST |
665                         G_SIGNAL_NO_RECURSE,
666                         G_STRUCT_OFFSET (LocationHybridClass, zone_out),
667                         NULL, NULL,
668                         location_VOID__UINT_POINTER_POINTER,
669                         G_TYPE_NONE, 3,
670                         G_TYPE_UINT,
671                         G_TYPE_POINTER,
672                         G_TYPE_POINTER);
673
674         properties[PROP_METHOD_TYPE] = g_param_spec_int ("method",
675                         "method type",
676                         "location method type name",
677                         LOCATION_METHOD_HYBRID,
678                         LOCATION_METHOD_HYBRID,
679                         LOCATION_METHOD_HYBRID,
680                         G_PARAM_READABLE);
681
682         properties[PROP_LAST_POSITION] = g_param_spec_boxed ("last-position",
683                         "hybrid last position prop",
684                         "hybrid last position data",
685                         LOCATION_TYPE_POSITION,
686                         G_PARAM_READABLE);
687
688         properties[PROP_UPDATE_INTERVAL] = g_param_spec_uint ("update-interval",
689                         "update interval prop",
690                         "update interval data",
691                         LOCATION_UPDATE_INTERVAL_MIN,
692                         LOCATION_UPDATE_INTERVAL_MAX,
693                         LOCATION_UPDATE_INTERVAL_DEFAULT,
694                         G_PARAM_READWRITE);
695
696         properties[PROP_BOUNDARY]  = g_param_spec_pointer ("boundary",
697                         "hybrid boundary prop",
698                         "hybrid boundary data",
699                         G_PARAM_READWRITE);
700
701         properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary",
702                         "hybrid removal boundary prop",
703                         "hybrid removal boundary data",
704                         LOCATION_TYPE_BOUNDARY,
705                         G_PARAM_READWRITE);
706
707         g_object_class_install_properties (gobject_class,
708                         PROP_MAX,
709                         properties);
710
711 }