removed wrong contacts, added authors
[platform/core/location/lbs-location.git] / location / manager / location-hybrid-mobile.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "location-setting.h"
24 #include "location-log.h"
25
26 #include "module-internal.h"
27
28 #include "location-hybrid.h"
29 #include "location-marshal.h"
30 #include "location-ielement.h"
31 #include "location-signaling-util.h"
32 #include "location-common-util.h"
33
34 #include "location-gps.h"
35 #include "location-wps.h"
36
37 typedef struct _LocationHybridPrivate {
38         gboolean                gps_enabled;
39         gboolean                wps_enabled;
40         gint                    signal_type;
41         guint                   pos_updated_timestamp;
42         guint                   vel_updated_timestamp;
43         guint                   sat_updated_timestamp;
44         guint                   dist_updated_timestamp;
45         guint                   loc_updated_timestamp;
46         guint                   pos_interval;
47         guint                   vel_interval;
48         guint                   sat_interval;
49         guint                   min_interval;
50         gdouble                 min_distance;
51         guint                   loc_interval;
52         LocationObject  *gps;
53         LocationObject  *wps;
54         gboolean                enabled;
55         LocationMethod  current_method;
56         LocationPosition *pos;
57         LocationVelocity *vel;
58         LocationAccuracy *acc;
59         LocationSatellite *sat;
60         GList                   *boundary_list;
61         gboolean                set_noti;
62         guint                   pos_timer;
63         guint                   vel_timer;
64 } LocationHybridPrivate;
65
66 enum {
67         PROP_0,
68         PROP_METHOD_TYPE,
69         PROP_LAST_POSITION,
70         PROP_POS_INTERVAL,
71         PROP_VEL_INTERVAL,
72         PROP_SAT_INTERVAL,
73         PROP_LOC_INTERVAL,
74         PROP_BOUNDARY,
75         PROP_REMOVAL_BOUNDARY,
76         PROP_MIN_INTERVAL,
77         PROP_MIN_DISTANCE,
78         PROP_SERVICE_STATUS,
79         PROP_MAX
80 };
81
82 static guint32 signals[LAST_SIGNAL] = {0, };
83 static GParamSpec *properties[PROP_MAX] = {NULL, };
84
85 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), LOCATION_TYPE_HYBRID, LocationHybridPrivate))
86
87 static void location_ielement_interface_init(LocationIElementInterface *iface);
88
89 G_DEFINE_TYPE_WITH_CODE(LocationHybrid, location_hybrid, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(LOCATION_TYPE_IELEMENT, location_ielement_interface_init));
90
91 static int
92 __get_availability_use_location(gpointer self)
93 {
94         if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
95                 return LOCATION_ERROR_SETTING_OFF;
96
97         return LOCATION_ERROR_NONE;
98 }
99
100 static LocationMethod
101 hybrid_get_current_method(LocationHybridPrivate *priv)
102 {
103         g_return_val_if_fail(priv, LOCATION_METHOD_NONE);
104         LOCATION_LOGD("Current Method [%d]", priv->current_method);
105         return priv->current_method;
106 }
107
108 static gboolean
109 hybrid_set_current_method(LocationHybridPrivate *priv, GType g_type)
110 {
111         g_return_val_if_fail(priv, FALSE);
112
113         if (g_type == LOCATION_TYPE_GPS)
114                 priv->current_method = LOCATION_METHOD_GPS;
115         else if (g_type == LOCATION_TYPE_WPS)
116                 priv->current_method = LOCATION_METHOD_WPS;
117         else if (g_type == LOCATION_TYPE_HYBRID)
118                 priv->current_method = LOCATION_METHOD_HYBRID;
119         else
120                 return FALSE;
121
122         return TRUE;
123 }
124
125 static int
126 hybrid_get_update_method(LocationHybridPrivate *priv)
127 {
128         if (!priv->gps && !priv->wps)
129                 return -1;
130
131         if (priv->gps_enabled)
132                 hybrid_set_current_method(priv, LOCATION_TYPE_GPS);
133         else if (priv->wps_enabled)
134                 hybrid_set_current_method(priv, LOCATION_TYPE_WPS);
135         else
136                 hybrid_set_current_method(priv, LOCATION_TYPE_HYBRID);
137
138         return 0;
139 }
140
141 static gboolean /* True : Receive more accurate info. False : Receive less accurate info */
142 hybrid_compare_g_type_method(LocationHybridPrivate *priv, GType g_type)
143 {
144         if (g_type == LOCATION_TYPE_GPS) {
145                 hybrid_set_current_method(priv, LOCATION_TYPE_GPS);
146                 return TRUE;
147         } else if (g_type == LOCATION_TYPE_WPS && hybrid_get_current_method(priv) == LOCATION_METHOD_WPS) {
148                 hybrid_set_current_method(priv, LOCATION_TYPE_WPS);
149                 return TRUE;
150         }
151         return FALSE;
152 }
153
154 static gboolean
155 _location_timeout_cb(gpointer data)
156 {
157         GObject *object = (GObject *)data;
158         if (!object) return FALSE;
159         LocationHybridPrivate *priv = GET_PRIVATE(object);
160         g_return_val_if_fail(priv, FALSE);
161
162         LocationPosition *pos = NULL;
163         LocationVelocity *vel = NULL;
164         LocationAccuracy *acc = NULL;
165
166         if (priv->pos)
167                 pos = location_position_copy(priv->pos);
168         else
169                 pos = location_position_new(0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
170
171         if (priv->vel)
172                 vel = location_velocity_copy(priv->vel);
173         else
174                 vel = location_velocity_new(0, 0.0, 0.0, 0.0);
175
176         if (priv->acc)
177                 acc = location_accuracy_copy(priv->acc);
178         else
179                 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
180
181         g_signal_emit(object, signals[SERVICE_UPDATED], 0, priv->signal_type, pos, vel, acc);
182         priv->signal_type = 0;
183
184         if (pos) location_position_free(pos);
185         if (vel) location_velocity_free(vel);
186         if (acc) location_accuracy_free(acc);
187
188         return TRUE;
189 }
190
191 static gboolean
192 _position_timeout_cb(gpointer data)
193 {
194         GObject *object = (GObject *)data;
195         if (!object) return FALSE;
196         LocationHybridPrivate *priv = GET_PRIVATE(object);
197         g_return_val_if_fail(priv, FALSE);
198
199         if (priv->pos_interval == priv->vel_interval) {
200                 priv->signal_type |= POSITION_UPDATED;
201                 priv->signal_type |= VELOCITY_UPDATED;
202         } else {
203                 priv->signal_type |= POSITION_UPDATED;
204         }
205         _location_timeout_cb(object);
206
207         return TRUE;
208 }
209
210 static gboolean
211 _velocity_timeout_cb(gpointer data)
212 {
213         GObject *object = (GObject *)data;
214         LocationHybridPrivate *priv = GET_PRIVATE(object);
215         g_return_val_if_fail(priv, FALSE);
216
217         if (priv->pos_interval != priv->vel_interval) {
218                 priv->signal_type |= VELOCITY_UPDATED;
219                 _location_timeout_cb(object);
220         }
221
222         return TRUE;
223 }
224
225 static void
226 location_hybrid_gps_cb(keynode_t *key, gpointer self)
227 {
228         LOC_FUNC_LOG
229         g_return_if_fail(key);
230         g_return_if_fail(self);
231         LocationHybridPrivate *priv = GET_PRIVATE(self);
232         g_return_if_fail(priv);
233         g_return_if_fail(priv->wps);
234
235         gboolean wps_started = FALSE;
236         int ret = LOCATION_ERROR_NONE;
237         int onoff = 0;
238
239         onoff = location_setting_get_key_val(key);
240         if (0 == onoff) {
241                 /* restart WPS when GPS stopped by setting */
242                 g_object_get(priv->wps, "is_started", &wps_started, NULL);
243                 if (wps_started == FALSE && 1 == location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED)) {
244                         LOCATION_LOGD("GPS stoped by setting, so restart WPS");
245                         ret = location_start(priv->wps);
246                         LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Fail hybrid/wps location_start : [%s]", err_msg(ret));
247                 }
248         } else if (1 == onoff) {
249                 LOCATION_LOGD("Hybrid GPS resumed by setting");
250
251         } else {
252                 LOCATION_LOGD("Invalid Value[%d]", onoff);
253         }
254
255 }
256
257 static void
258 hybrid_location_updated(GObject *obj, guint error, gpointer position, gpointer velocity, gpointer accuracy, gpointer self)
259 {
260         LOC_FUNC_LOG
261         LocationPosition *pos = (LocationPosition *)position;
262         LocationVelocity *vel = (LocationVelocity *)velocity;
263         LocationAccuracy *acc = (LocationAccuracy *)accuracy;
264
265         LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
266         g_return_if_fail(priv);
267
268         GType g_type = G_TYPE_FROM_INSTANCE(obj);
269         if (g_type == LOCATION_TYPE_GPS) {
270                 if (priv->wps)
271                         location_cancel_single_location(priv->wps);
272         } else if (g_type == LOCATION_TYPE_WPS) {
273                 if (priv->gps)
274                         location_cancel_single_location(priv->gps);
275         }
276
277         g_signal_emit(self, signals[LOCATION_UPDATED], 0, error, pos, vel, acc);
278 }
279
280 static void
281 hybrid_service_updated(GObject *obj, gint type, gpointer data, gpointer velocity, gpointer accuracy, gpointer self)
282 {
283         LOC_FUNC_LOG
284         LocationPosition *pos = NULL;
285         LocationVelocity *vel = NULL;
286         LocationAccuracy *acc = NULL;
287         LocationSatellite *sat = NULL;
288         gboolean wps_started = FALSE;
289         int ret = LOCATION_ERROR_NONE;
290
291         if (type == SATELLITE_UPDATED) {
292                 sat = (LocationSatellite *) data;
293                 if (!sat->timestamp) return;
294         } else {
295                 pos = (LocationPosition *) data;
296                 vel = (LocationVelocity *) velocity;
297                 acc = (LocationAccuracy *) accuracy;
298                 if (!pos->timestamp) return;
299                 if (!vel->timestamp) return;
300         }
301
302         LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
303         g_return_if_fail(priv);
304
305         GType g_type = G_TYPE_FROM_INSTANCE(obj);
306         if (g_type == LOCATION_TYPE_GPS) {
307                 if (type == SATELLITE_UPDATED) {
308                         satellite_signaling(self, signals, &(priv->enabled), priv->sat_interval, TRUE, &(priv->sat_updated_timestamp), &(priv->sat), sat);
309                         return;
310                 } else if (location_setting_get_int(VCONFKEY_LOCATION_GPS_STATE) == VCONFKEY_LOCATION_GPS_SEARCHING
311                                          && location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED) == 0) {
312                         LOCATION_LOGD("Searching GPS");
313
314                         /* restart WPS when GPS not available */
315                         if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
316                         if (priv->wps && wps_started == FALSE) {
317                                 LOCATION_LOGD("Starting WPS");
318                                 ret = location_start(priv->wps);
319                                 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Fail hyhrid location_start : [%s]", err_msg(ret));
320                         }
321                         return;
322                 }
323         }
324
325         if (hybrid_compare_g_type_method(priv, g_type)) {
326                 if (priv->pos) location_position_free(priv->pos);
327                 if (priv->vel) location_velocity_free(priv->vel);
328                 if (priv->acc) location_accuracy_free(priv->acc);
329
330                 if (pos) priv->pos = location_position_copy(pos);
331                 if (vel) priv->vel = location_velocity_copy(vel);
332                 if (acc) priv->acc = location_accuracy_copy(acc);
333
334                 if (pos) {
335                         if (!priv->enabled)
336                                 enable_signaling(self, signals, &(priv->enabled), TRUE, pos->status);
337
338                         if (type == DISTANCE_UPDATED) {
339                                 distance_based_position_signaling(self, signals, priv->enabled, pos, vel, acc,
340                                                                   priv->min_interval, priv->min_distance, &(priv->enabled),
341                                                                   &(priv->dist_updated_timestamp), &(priv->pos), &(priv->vel), &(priv->acc));
342                         } else {
343                                 position_velocity_signaling(self, signals, priv->pos_interval, priv->vel_interval, priv->loc_interval,
344                                                                 &(priv->pos_updated_timestamp), &(priv->vel_updated_timestamp), &(priv->loc_updated_timestamp),
345                                                                 priv->boundary_list, pos, vel, acc);
346                         }
347                 }
348
349                 /* if receive GPS position then stop WPS.. */
350                 if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
351                 if (g_type == LOCATION_TYPE_GPS && wps_started == TRUE) {
352                         LOCATION_LOGD("Calling WPS stop");
353                         ret = location_stop(priv->wps);
354                         LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Fail hyhrid location_stop : [%s]", err_msg(ret));
355                 }
356
357         } else if (g_type == LOCATION_TYPE_WPS && location_setting_get_int(VCONFKEY_LOCATION_GPS_STATE) == VCONFKEY_LOCATION_GPS_SEARCHING) {
358                 LOCATION_LOGD("g_type is LOCATION_TYPE_WPS and GPS is searching");
359                 hybrid_set_current_method(priv, g_type);
360
361                 if (priv->pos) location_position_free(priv->pos);
362                 if (priv->vel) location_velocity_free(priv->vel);
363                 if (priv->acc) location_accuracy_free(priv->acc);
364
365                 if (pos) priv->pos = location_position_copy(pos);
366                 if (vel) priv->vel = location_velocity_copy(vel);
367                 if (acc) priv->acc = location_accuracy_copy(acc);
368
369                 if (pos) {
370                         if (!priv->enabled)
371                                 enable_signaling(self, signals, &(priv->enabled), TRUE, pos->status);
372
373                         if (type == DISTANCE_UPDATED) {
374                                 distance_based_position_signaling(self, signals, priv->enabled, pos, vel, acc,
375                                                                                                 priv->min_interval, priv->min_distance, &(priv->enabled),
376                                                                                                 &(priv->dist_updated_timestamp), &(priv->pos), &(priv->vel), &(priv->acc));
377                         } else {
378                                 LOCATION_LOGD("position_velocity_signaling");
379                                 position_velocity_signaling(self, signals, priv->pos_interval, priv->vel_interval, priv->loc_interval,
380                                                                                         &(priv->pos_updated_timestamp), &(priv->vel_updated_timestamp), &(priv->loc_updated_timestamp),
381                                                                                         priv->boundary_list, pos, vel, acc);
382                         }
383                 }
384         }
385 }
386
387 static void
388 hybrid_service_enabled(GObject *obj, guint status, gpointer self)
389 {
390         LOC_FUNC_LOG
391         LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
392         g_return_if_fail(priv);
393
394         GType g_type = G_TYPE_FROM_INSTANCE(obj);
395         if (g_type == LOCATION_TYPE_GPS) {
396                 priv->gps_enabled = TRUE;
397         } else if (g_type == LOCATION_TYPE_WPS) {
398                 priv->wps_enabled = TRUE;
399         } else {
400                 LOCATION_LOGW("Undefined GType enabled");
401                 return;
402         }
403         hybrid_get_update_method(priv);
404 }
405
406 static void
407 hybrid_service_disabled(GObject *obj, guint status, gpointer self)
408 {
409         LOC_FUNC_LOG
410         LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
411         g_return_if_fail(priv);
412         GType g_type = G_TYPE_FROM_INSTANCE(obj);
413         if (g_type == LOCATION_TYPE_GPS) {
414                 priv->gps_enabled = FALSE;
415         } else if (g_type == LOCATION_TYPE_WPS) {
416                 priv->wps_enabled = FALSE;
417         } else {
418                 LOCATION_LOGW("Undefined GType disabled");
419                 return;
420         }
421         hybrid_get_update_method(priv);
422         if (!priv->gps_enabled && !priv->wps_enabled)
423                 enable_signaling(self, signals, &(priv->enabled), FALSE, status);
424
425 }
426
427 static int
428 location_hybrid_start(LocationHybrid *self)
429 {
430         LOC_FUNC_LOG
431
432         int ret_gps = LOCATION_ERROR_NONE;
433         int ret_wps = LOCATION_ERROR_NONE;
434         gboolean gps_started = FALSE;
435         gboolean wps_started = FALSE;
436
437         LocationHybridPrivate *priv = GET_PRIVATE(self);
438         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
439         LOC_COND_RET(!priv->gps && !priv->wps, LOCATION_ERROR_NOT_AVAILABLE, _E, "GPS and WPS Object are not created.");
440
441         if (priv->gps) g_object_get(priv->gps, "is_started", &gps_started, NULL);
442         if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
443
444         if ((gps_started == TRUE) || (wps_started == TRUE)) {
445                 LOCATION_LOGD("Already started");
446                 return LOCATION_ERROR_NONE;
447         }
448
449         if (priv->gps) ret_gps = location_start(priv->gps);
450         if (priv->wps) ret_wps = location_start(priv->wps);
451
452         if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE) {
453                 LOCATION_LOGD("ret_gps = %d, ret_wps = %d", ret_gps, ret_wps);
454                 if (ret_gps == LOCATION_ERROR_SECURITY_DENIED || ret_wps == LOCATION_ERROR_SECURITY_DENIED)
455                         return LOCATION_ERROR_SECURITY_DENIED;
456                 else if (ret_gps == LOCATION_ERROR_SETTING_OFF || ret_wps == LOCATION_ERROR_SETTING_OFF)
457                         return LOCATION_ERROR_SETTING_OFF;
458                 else if (ret_gps == LOCATION_ERROR_NOT_ALLOWED || ret_wps == LOCATION_ERROR_NOT_ALLOWED)
459                         return LOCATION_ERROR_NOT_ALLOWED;
460                 else
461                         return LOCATION_ERROR_NOT_AVAILABLE;
462         }
463
464         if (priv->set_noti == FALSE) {
465                 location_setting_add_notify(VCONFKEY_LOCATION_ENABLED, location_hybrid_gps_cb, self);
466                 priv->set_noti = TRUE;
467         }
468
469         return LOCATION_ERROR_NONE;
470 }
471
472 static int
473 location_hybrid_stop(LocationHybrid *self)
474 {
475         LOC_FUNC_LOG
476
477         LocationHybridPrivate *priv = GET_PRIVATE(self);
478         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
479
480         LOCATION_LOGD("location_hybrid_stop started......!!!");
481
482         int ret_gps = LOCATION_ERROR_NOT_AVAILABLE;
483         int ret_wps = LOCATION_ERROR_NOT_AVAILABLE;
484         gboolean gps_started = FALSE;
485         gboolean wps_started = FALSE;
486
487         if (priv->gps) g_object_get(priv->gps, "is_started", &gps_started, NULL);
488         if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
489
490         if ((gps_started == FALSE) && (wps_started == FALSE))
491                 return LOCATION_ERROR_NONE;
492
493         if (priv->gps) ret_gps = location_stop(priv->gps);
494         if (priv->wps) ret_wps = location_stop(priv->wps);
495
496         if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE)
497                 return LOCATION_ERROR_NOT_AVAILABLE;
498
499         if (priv->pos_timer) g_source_remove(priv->pos_timer);
500         if (priv->vel_timer) g_source_remove(priv->vel_timer);
501         priv->pos_timer = 0;
502         priv->vel_timer = 0;
503
504         if (priv->set_noti == TRUE) {
505                 location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_hybrid_gps_cb);
506                 priv->set_noti = FALSE;
507         }
508
509         priv->gps_enabled = FALSE;
510         priv->wps_enabled = FALSE;
511
512         return LOCATION_ERROR_NONE;
513 }
514
515 static void
516 location_hybrid_dispose(GObject *gobject)
517 {
518         LOC_FUNC_LOG
519         LocationHybridPrivate *priv = GET_PRIVATE(gobject);
520         g_return_if_fail(priv);
521
522         if (priv->pos_timer) g_source_remove(priv->pos_timer);
523         if (priv->vel_timer) g_source_remove(priv->vel_timer);
524         priv->pos_timer = 0;
525         priv->vel_timer = 0;
526
527         if (priv->set_noti == TRUE) {
528                 location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_hybrid_gps_cb);
529                 priv->set_noti = FALSE;
530         }
531
532         G_OBJECT_CLASS(location_hybrid_parent_class)->dispose(gobject);
533 }
534
535 static void
536 location_hybrid_finalize(GObject *gobject)
537 {
538         LOC_FUNC_LOG
539         LocationHybridPrivate *priv = GET_PRIVATE(gobject);
540         g_return_if_fail(priv);
541
542         if (priv->gps) {
543                 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_enabled), gobject);
544                 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_disabled), gobject);
545                 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_updated), gobject);
546                 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_location_updated), gobject);
547                 location_free(priv->gps, TRUE);
548         }
549         if (priv->wps) {
550                 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_enabled), gobject);
551                 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_disabled), gobject);
552                 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_updated), gobject);
553                 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_location_updated), gobject);
554                 location_free(priv->wps, TRUE);
555         }
556
557         if (priv->boundary_list) {
558                 g_list_free_full(priv->boundary_list, free_boundary_list);
559                 priv->boundary_list = NULL;
560         }
561
562         if (priv->pos) {
563                 location_position_free(priv->pos);
564                 priv->pos = NULL;
565         }
566
567         if (priv->vel) {
568                 location_velocity_free(priv->vel);
569                 priv->vel = NULL;
570         }
571
572         if (priv->acc) {
573                 location_accuracy_free(priv->acc);
574                 priv->acc = NULL;
575         }
576
577         if (priv->sat) {
578                 location_satellite_free(priv->sat);
579                 priv->sat = NULL;
580         }
581
582         G_OBJECT_CLASS(location_hybrid_parent_class)->finalize(gobject);
583 }
584
585 static void
586 location_hybrid_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
587 {
588         LocationHybridPrivate *priv = GET_PRIVATE(object);
589         g_return_if_fail(priv);
590         if (!priv->gps && !priv->wps) {
591                 LOCATION_LOGW("Set property is not available now");
592                 return;
593         }
594
595         int ret = 0;
596         switch (property_id) {
597         case PROP_BOUNDARY: {
598                                 GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
599                                 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
600                                 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Set boundary. Error[%s]", err_msg(ret));
601                                 break;
602                         }
603         case PROP_REMOVAL_BOUNDARY: {
604                                 LocationBoundary *req_boundary = (LocationBoundary *) g_value_dup_boxed(value);
605                                 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
606                                 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Removal boundary. Error[%s]", err_msg(ret));
607                                 break;
608                         }
609         case PROP_POS_INTERVAL: {
610                                 guint interval = g_value_get_uint(value);
611                                 LOCATION_LOGD("Set prop>> PROP_POS_INTERVAL: %u", interval);
612                                 if (interval > 0) {
613                                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
614                                                 priv->pos_interval = interval;
615                                         else
616                                                 priv->pos_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
617                                 } else {
618                                         priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
619                                 }
620
621                                 if (priv->pos_timer) {
622                                         g_source_remove(priv->pos_timer);
623                                         priv->pos_timer = g_timeout_add(priv->pos_interval * 1000, _position_timeout_cb, object);
624                                 }
625
626                                 if (priv->gps) g_object_set(priv->gps, "pos-interval", priv->pos_interval, NULL);
627                                 if (priv->wps) g_object_set(priv->wps, "pos-interval", priv->pos_interval, NULL);
628
629                                 break;
630                         }
631         case PROP_VEL_INTERVAL: {
632                                 guint interval = g_value_get_uint(value);
633                                 LOCATION_LOGD("Set prop>> PROP_VEL_INTERVAL: %u", interval);
634                                 if (interval > 0) {
635                                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
636                                                 priv->vel_interval = interval;
637                                         else
638                                                 priv->vel_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
639
640                                 } else
641                                         priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
642
643                                 if (priv->vel_timer) {
644                                         g_source_remove(priv->vel_timer);
645                                         priv->vel_timer = g_timeout_add(priv->vel_interval * 1000, _velocity_timeout_cb, object);
646                                 }
647
648                                 if (priv->gps) g_object_set(priv->gps, "vel-interval", priv->vel_interval, NULL);
649                                 if (priv->wps) g_object_set(priv->wps, "vel-interval", priv->vel_interval, NULL);
650
651                                 break;
652                         }
653         case PROP_SAT_INTERVAL: {
654                                 guint interval = g_value_get_uint(value);
655                                 LOCATION_LOGD("Set prop>> PROP_SAT_INTERVAL: %u", interval);
656                                 if (interval > 0) {
657                                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
658                                                 priv->sat_interval = interval;
659                                         else
660                                                 priv->sat_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
661
662                                 } else
663                                         priv->sat_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
664
665                                 break;
666                         }
667         case PROP_LOC_INTERVAL: {
668                                 guint interval = g_value_get_uint(value);
669                                 LOCATION_LOGD("Set prop>> PROP_LOC_INTERVAL: %u", interval);
670                                 if (interval > 0) {
671                                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
672                                                 priv->loc_interval = interval;
673                                         else
674                                                 priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
675                                 } else
676                                         priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
677
678                                 if (priv->gps) g_object_set(priv->gps, "loc-interval", priv->loc_interval, NULL);
679                                 if (priv->wps) g_object_set(priv->wps, "loc-interval", priv->loc_interval, NULL);
680
681                                 break;
682                         }
683         case PROP_MIN_INTERVAL: {
684                                 guint interval = g_value_get_uint(value);
685                                 LOCATION_LOGD("Set prop>> PROP_MIN_INTERVAL: %u", interval);
686                                 if (interval > 0) {
687                                         if (interval < LOCATION_MIN_INTERVAL_MAX)
688                                                 priv->min_interval = interval;
689                                         else
690                                                 priv->min_interval = (guint)LOCATION_MIN_INTERVAL_MAX;
691                                 } else
692                                         priv->min_interval = (guint)LOCATION_MIN_INTERVAL_DEFAULT;
693
694                                 if (priv->gps) g_object_set(priv->gps, "min-interval", priv->min_interval, NULL);
695                                 if (priv->wps) g_object_set(priv->wps, "min-interval", priv->min_interval, NULL);
696
697                                 break;
698                         }
699         case PROP_MIN_DISTANCE: {
700                                 gdouble distance = g_value_get_double(value);
701                                 LOCATION_LOGD("Set prop>> PROP_MIN_DISTANCE: %f", distance);
702                                 if (distance > 0) {
703                                         if (distance < LOCATION_MIN_DISTANCE_MAX)
704                                                 priv->min_distance = distance;
705                                         else
706                                                 priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_MAX;
707                                 } else
708                                         priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_DEFAULT;
709
710                                 if (priv->gps) g_object_set(priv->gps, "min-distance", priv->min_distance, NULL);
711                                 if (priv->wps) g_object_set(priv->wps, "min-distance", priv->min_distance, NULL);
712
713                                 break;
714                         }
715         default:
716                         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
717                         break;
718         }
719 }
720
721 static void
722 location_hybrid_get_property(GObject *object, guint property_id, GValue *value,  GParamSpec *pspec)
723 {
724         LocationHybridPrivate *priv = GET_PRIVATE(object);
725         g_return_if_fail(priv);
726
727         LOC_COND_VOID(!priv->gps && !priv->wps, _E, "Error : Get property is not available now");
728
729         LOCATION_LOGW("Get Propery ID[%d]", property_id);
730
731         switch (property_id) {
732         case PROP_METHOD_TYPE:
733                 g_value_set_int(value, hybrid_get_current_method(priv));
734                 break;
735         case PROP_LAST_POSITION:
736                 g_value_set_boxed(value, priv->pos);
737                 break;
738         case PROP_BOUNDARY:
739                 g_value_set_pointer(value, g_list_first(priv->boundary_list));
740                 break;
741         case PROP_POS_INTERVAL:
742                 g_value_set_uint(value, priv->pos_interval);
743                 break;
744         case PROP_VEL_INTERVAL:
745                 g_value_set_uint(value, priv->vel_interval);
746                 break;
747         case PROP_SAT_INTERVAL:
748                 g_value_set_uint(value, priv->sat_interval);
749                 break;
750         case PROP_LOC_INTERVAL:
751                 g_value_set_uint(value, priv->loc_interval);
752                 break;
753         case PROP_MIN_INTERVAL:
754                 g_value_set_uint(value, priv->min_interval);
755                 break;
756         case PROP_MIN_DISTANCE:
757                 g_value_set_double(value, priv->min_distance);
758                 break;
759         case PROP_SERVICE_STATUS:
760                 g_value_set_int(value, priv->enabled);
761                 break;
762         default:
763                 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
764                 break;
765         }
766 }
767
768 static int
769 location_hybrid_get_position(LocationHybrid *self, LocationPosition **position, LocationAccuracy **accuracy)
770 {
771         LOC_FUNC_LOG
772         int ret = LOCATION_ERROR_NOT_AVAILABLE;
773         if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
774                 return LOCATION_ERROR_SETTING_OFF;
775
776         LocationHybridPrivate *priv = GET_PRIVATE(self);
777         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
778         LOCATION_IF_HYBRID_FAIL(VCONFKEY_LOCATION_GPS_STATE, VCONFKEY_LOCATION_WPS_STATE);
779
780         if (priv->pos) {
781                 *position = location_position_copy(priv->pos);
782                 ret = LOCATION_ERROR_NONE;
783         }
784
785         if (priv->acc)
786                 *accuracy = location_accuracy_copy(priv->acc);
787
788         return ret;
789 }
790
791 static int
792 location_hybrid_get_position_ext(LocationHybrid *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
793 {
794         LOC_FUNC_LOG
795         if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
796                 return LOCATION_ERROR_SETTING_OFF;
797
798         LocationHybridPrivate *priv = GET_PRIVATE(self);
799         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
800         LOCATION_IF_HYBRID_FAIL(VCONFKEY_LOCATION_GPS_STATE, VCONFKEY_LOCATION_WPS_STATE);
801
802         if (priv->pos && priv->vel) {
803                 *position = location_position_copy(priv->pos);
804                 *velocity = location_velocity_copy(priv->vel);
805         } else {
806                 LOCATION_LOGE("There is invalid data.");
807                 return LOCATION_ERROR_NOT_AVAILABLE;
808         }
809
810         if (priv->acc)
811                 *accuracy = location_accuracy_copy(priv->acc);
812         else
813                 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
814
815         return LOCATION_ERROR_NONE;
816 }
817
818
819 static int
820 location_hybrid_get_last_position(LocationHybrid *self, LocationPosition **position, LocationAccuracy **accuracy)
821 {
822         LOC_FUNC_LOG
823
824         int ret = LOCATION_ERROR_NONE;
825         LocationPosition *gps_pos = NULL, *wps_pos = NULL;
826         LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
827         LocationHybridPrivate *priv = GET_PRIVATE(self);
828         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
829
830         if (priv->gps) location_get_last_position(priv->gps, &gps_pos, &gps_acc);
831         if (priv->wps) location_get_last_position(priv->wps, &wps_pos, &wps_acc);
832
833         if (gps_pos && wps_pos) {
834                 if (wps_pos->timestamp > gps_pos->timestamp) {
835                         *position = wps_pos;
836                         *accuracy = wps_acc;
837                         location_position_free(gps_pos);
838                         location_accuracy_free(gps_acc);
839                 } else {
840                         *position = gps_pos;
841                         *accuracy = gps_acc;
842                         location_position_free(wps_pos);
843                         location_accuracy_free(wps_acc);
844                 }
845         } else if (gps_pos) {
846                 *position = gps_pos;
847                 *accuracy = gps_acc;
848         } else if (wps_pos) {
849                 *position = wps_pos;
850                 *accuracy = wps_acc;
851         } else {
852                 ret = LOCATION_ERROR_NOT_AVAILABLE;
853         }
854
855         return ret;
856 }
857
858 static int
859 location_hybrid_get_last_position_ext(LocationHybrid *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
860 {
861         LOC_FUNC_LOG
862
863         int ret = LOCATION_ERROR_NONE;
864         LocationPosition *gps_pos = NULL, *wps_pos = NULL;
865         LocationVelocity *gps_vel = NULL, *wps_vel = NULL;
866         LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
867         LocationHybridPrivate *priv = GET_PRIVATE(self);
868         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
869
870         if (priv->gps) location_get_last_position_ext(priv->gps, &gps_pos, &gps_vel, &gps_acc);
871         if (priv->wps) location_get_last_position_ext(priv->wps, &wps_pos, &wps_vel, &wps_acc);
872
873         if (gps_pos && wps_pos && gps_vel && wps_vel) {
874                 if (wps_pos->timestamp > gps_pos->timestamp) {
875                         *position = wps_pos;
876                         *velocity = wps_vel;
877                         *accuracy = wps_acc;
878                         location_position_free(gps_pos);
879                         location_velocity_free(gps_vel);
880                         location_accuracy_free(gps_acc);
881                 } else {
882                         *position = gps_pos;
883                         *velocity = gps_vel;
884                         *accuracy = gps_acc;
885                         location_position_free(wps_pos);
886                         location_velocity_free(wps_vel);
887                         location_accuracy_free(wps_acc);
888                 }
889         } else if (gps_pos && gps_vel) {
890                 *position = gps_pos;
891                 *velocity = gps_vel;
892                 *accuracy = gps_acc;
893         } else if (wps_pos && wps_vel) {
894                 *position = wps_pos;
895                 *velocity = wps_vel;
896                 *accuracy = wps_acc;
897         } else {
898                 ret = LOCATION_ERROR_NOT_AVAILABLE;
899         }
900
901         return ret;
902 }
903
904 static int
905 location_hybrid_get_velocity(LocationHybrid *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
906 {
907         LOC_FUNC_LOG
908         int ret = LOCATION_ERROR_NOT_AVAILABLE;
909         if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
910                 return LOCATION_ERROR_SETTING_OFF;
911
912         LocationHybridPrivate *priv = GET_PRIVATE(self);
913         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
914         LOCATION_IF_HYBRID_FAIL(VCONFKEY_LOCATION_GPS_STATE, VCONFKEY_LOCATION_WPS_STATE);
915
916         if (priv->vel) {
917                 *velocity = location_velocity_copy(priv->vel);
918                 ret = LOCATION_ERROR_NONE;
919         }
920
921         if (priv->acc)
922                 *accuracy = location_accuracy_copy(priv->acc);
923
924         return ret;
925 }
926
927 static int
928 location_hybrid_get_last_velocity(LocationHybrid *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
929 {
930         LOC_FUNC_LOG
931
932         int ret = LOCATION_ERROR_NONE;
933         LocationHybridPrivate *priv = GET_PRIVATE(self);
934         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
935         LocationVelocity *gps_vel = NULL, *wps_vel = NULL;
936         LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
937
938         if (priv->gps) location_get_last_velocity(priv->gps, &gps_vel, &gps_acc);
939         if (priv->wps) location_get_last_velocity(priv->wps, &wps_vel, &wps_acc);
940
941         if (gps_vel && wps_vel) {
942                 if (wps_vel->timestamp > gps_vel->timestamp) {
943                         *velocity = wps_vel;
944                         *accuracy = wps_acc;
945                         location_velocity_free(gps_vel);
946                         location_accuracy_free(gps_acc);
947                 } else {
948                         *velocity = gps_vel;
949                         *accuracy = gps_acc;
950                         location_velocity_free(wps_vel);
951                         location_accuracy_free(wps_acc);
952                 }
953         } else if (gps_vel) {
954                 *velocity = gps_vel;
955                 *accuracy = gps_acc;
956         } else if (wps_vel) {
957                 *velocity = wps_vel;
958                 *accuracy = wps_acc;
959         } else {
960                 *velocity = NULL;
961                 *accuracy = NULL;
962                 ret = LOCATION_ERROR_NOT_AVAILABLE;
963         }
964
965         return ret;
966 }
967
968 static int
969 location_hybrid_get_satellite(LocationHybrid *self, LocationSatellite **satellite)
970 {
971         LOC_FUNC_LOG
972         int ret = LOCATION_ERROR_NOT_AVAILABLE;
973         if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
974                 return LOCATION_ERROR_SETTING_OFF;
975
976         LocationHybridPrivate *priv = GET_PRIVATE(self);
977         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
978         if (priv->sat) {
979                 *satellite = location_satellite_copy(priv->sat);
980                 ret = LOCATION_ERROR_NONE;
981         }
982
983         return ret;
984 }
985
986 static int
987 location_hybrid_get_last_satellite(LocationHybrid *self, LocationSatellite **satellite)
988 {
989         LOC_FUNC_LOG
990
991         int ret = LOCATION_ERROR_NONE;
992         LocationHybridPrivate *priv = GET_PRIVATE(self);
993         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
994
995         if (priv->gps) {
996                 ret = location_get_last_satellite(priv->gps, satellite);
997         } else {
998                 *satellite = NULL;
999                 ret = LOCATION_ERROR_NOT_AVAILABLE;
1000         }
1001
1002         return ret;
1003 }
1004
1005 static int
1006 location_hybrid_set_option(LocationHybrid *self, const char *option)
1007 {
1008         LOC_FUNC_LOG
1009         LocationHybridPrivate *priv = GET_PRIVATE(self);
1010         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1011
1012         int ret_gps = LOCATION_ERROR_NOT_AVAILABLE;
1013         int ret_wps = LOCATION_ERROR_NOT_AVAILABLE;
1014
1015         if (priv->gps) ret_gps = location_set_option(priv->gps, option);
1016         if (priv->wps) ret_wps = location_set_option(priv->wps, option);
1017
1018         if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE)
1019                 return LOCATION_ERROR_NOT_AVAILABLE;
1020
1021         return LOCATION_ERROR_NONE;
1022 }
1023
1024 static int
1025 location_hybrid_request_single_location(LocationHybrid *self, int timeout)
1026 {
1027         LOC_FUNC_LOG
1028         LocationHybridPrivate *priv = GET_PRIVATE(self);
1029         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1030
1031         int ret = LOCATION_ERROR_NOT_AVAILABLE;
1032         int ret_gps = LOCATION_ERROR_NOT_AVAILABLE;
1033         int ret_wps = LOCATION_ERROR_NOT_AVAILABLE;
1034
1035         ret = __get_availability_use_location(self);
1036         LOC_IF_FAIL(ret, _E, "setting off [%s]", err_msg(LOCATION_ERROR_SETTING_OFF));
1037
1038         if (priv->gps) {
1039                 LOCATION_LOGD("location_request_single_location : gps");
1040                 ret_gps = location_request_single_location(priv->gps, timeout);
1041         }
1042
1043         if (priv->wps) {
1044                 LOCATION_LOGD("location_request_single_location : wps");
1045                 ret_wps = location_request_single_location(priv->wps, timeout);
1046         }
1047
1048         if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE) {
1049                 if (ret_gps == LOCATION_ERROR_NOT_ALLOWED && ret_wps == LOCATION_ERROR_NOT_ALLOWED)
1050                         return LOCATION_ERROR_NOT_ALLOWED;
1051                 else
1052                         return LOCATION_ERROR_NOT_AVAILABLE;
1053         }
1054
1055         return ret;
1056 }
1057
1058 int
1059 location_hybrid_cancel_single_location(LocationHybrid *self, int timeout)
1060 {
1061         LOC_FUNC_LOG
1062         return LOCATION_ERROR_NOT_SUPPORTED;
1063 }
1064
1065
1066 static int
1067 location_hybrid_get_nmea(LocationHybrid *self, char **nmea_data)
1068 {
1069         LOC_FUNC_LOG
1070         LocationHybridPrivate *priv = GET_PRIVATE(self);
1071         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1072
1073         int ret = LOCATION_ERROR_NOT_AVAILABLE;
1074
1075         if (priv->gps) ret = location_get_nmea(priv->gps, nmea_data);
1076
1077         if (ret != LOCATION_ERROR_NONE)
1078                 return LOCATION_ERROR_NOT_AVAILABLE;
1079
1080         return LOCATION_ERROR_NONE;
1081 }
1082
1083 static int
1084 location_hybrid_set_mock_location(LocationHybrid *self, LocationPosition *position, LocationVelocity *velocity, LocationAccuracy *accuracy)
1085 {
1086         LOC_FUNC_LOG
1087         LocationHybridPrivate *priv = GET_PRIVATE(self);
1088         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1089         int ret = LOCATION_ERROR_NONE;
1090
1091         if (priv->gps)
1092                 ret = location_set_mock_location(priv->gps, position, velocity, accuracy);
1093         else if (priv->wps)
1094                 ret = location_set_mock_location(priv->wps, position, velocity, accuracy);
1095         else
1096                 ret = LOCATION_ERROR_NOT_AVAILABLE;
1097
1098         return ret;
1099 }
1100
1101 static int
1102 location_hybrid_clear_mock_location(LocationHybrid *self)
1103 {
1104         LOC_FUNC_LOG
1105         LocationHybridPrivate *priv = GET_PRIVATE(self);
1106         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1107         int ret = LOCATION_ERROR_NONE;
1108
1109         if (priv->gps)
1110                 ret = location_clear_mock_location(priv->gps);
1111         else if (priv->wps)
1112                 ret = location_clear_mock_location(priv->wps);
1113         else
1114                 ret = LOCATION_ERROR_NOT_AVAILABLE;
1115
1116         return ret;
1117 }
1118
1119 static void
1120 location_ielement_interface_init(LocationIElementInterface *iface)
1121 {
1122         iface->start = (TYPE_START_FUNC)location_hybrid_start;
1123         iface->stop = (TYPE_STOP_FUNC)location_hybrid_stop;
1124         iface->get_position = (TYPE_GET_POSITION)location_hybrid_get_position;
1125         iface->get_position_ext = (TYPE_GET_POSITION_EXT)location_hybrid_get_position_ext;
1126         iface->get_last_position = (TYPE_GET_POSITION)location_hybrid_get_last_position;
1127         iface->get_last_position_ext = (TYPE_GET_POSITION_EXT)location_hybrid_get_last_position_ext;
1128         iface->get_velocity = (TYPE_GET_VELOCITY)location_hybrid_get_velocity;
1129         iface->get_last_velocity = (TYPE_GET_VELOCITY)location_hybrid_get_last_velocity;
1130         iface->get_satellite = (TYPE_GET_SATELLITE)location_hybrid_get_satellite;
1131         iface->get_last_satellite = (TYPE_GET_SATELLITE)location_hybrid_get_last_satellite;
1132         iface->set_option = (TYPE_SET_OPTION)location_hybrid_set_option;
1133         iface->request_single_location = (TYPE_REQUEST_SINGLE_LOCATION)location_hybrid_request_single_location;
1134         iface->cancel_single_location = (TYPE_CANCEL_SINGLE_LOCATION)location_hybrid_cancel_single_location;
1135         iface->get_nmea = (TYPE_GET_NMEA)location_hybrid_get_nmea;
1136
1137         iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_hybrid_set_mock_location;
1138         iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_hybrid_clear_mock_location;
1139 }
1140
1141 static void
1142 location_hybrid_init(LocationHybrid *self)
1143 {
1144         LOC_FUNC_LOG
1145         LocationHybridPrivate *priv = GET_PRIVATE(self);
1146         g_return_if_fail(priv);
1147
1148         priv->pos_interval = LOCATION_UPDATE_INTERVAL_NONE;
1149         priv->vel_interval = LOCATION_UPDATE_INTERVAL_NONE;
1150         priv->sat_interval = LOCATION_UPDATE_INTERVAL_NONE;
1151         priv->loc_interval = LOCATION_UPDATE_INTERVAL_NONE;
1152         priv->min_interval = LOCATION_UPDATE_INTERVAL_NONE;
1153
1154         priv->pos_updated_timestamp = 0;
1155         priv->vel_updated_timestamp = 0;
1156         priv->sat_updated_timestamp = 0;
1157         priv->loc_updated_timestamp = 0;
1158
1159         priv->gps_enabled = FALSE;
1160         priv->wps_enabled = FALSE;
1161         priv->gps = NULL;
1162         priv->wps = NULL;
1163
1164         priv->set_noti = FALSE;
1165         priv->signal_type = 0;
1166         priv->pos_timer = 0;
1167         priv->vel_timer = 0;
1168
1169         if (location_is_supported_method(LOCATION_METHOD_GPS)) priv->gps = location_new(LOCATION_METHOD_GPS, TRUE);
1170         if (location_is_supported_method(LOCATION_METHOD_WPS)) priv->wps = location_new(LOCATION_METHOD_WPS, TRUE);
1171
1172         if (priv->gps) {
1173                 g_signal_connect(priv->gps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self);
1174                 g_signal_connect(priv->gps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self);
1175                 g_signal_connect(priv->gps, "service-updated", G_CALLBACK(hybrid_service_updated), self);
1176                 g_signal_connect(priv->gps, "location-updated", G_CALLBACK(hybrid_location_updated), self);
1177         }
1178         if (priv->wps) {
1179                 g_signal_connect(priv->wps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self);
1180                 g_signal_connect(priv->wps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self);
1181                 g_signal_connect(priv->wps, "service-updated", G_CALLBACK(hybrid_service_updated), self);
1182                 g_signal_connect(priv->wps, "location-updated", G_CALLBACK(hybrid_location_updated), self);
1183         }
1184
1185         hybrid_set_current_method(priv, LOCATION_TYPE_HYBRID);
1186         priv->enabled = FALSE;
1187
1188         priv->pos = NULL;
1189         priv->vel = NULL;
1190         priv->acc = NULL;
1191         priv->sat = NULL;
1192
1193         priv->boundary_list = NULL;
1194 }
1195
1196 static void
1197 location_hybrid_class_init(LocationHybridClass *klass)
1198 {
1199         LOC_FUNC_LOG
1200         GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
1201
1202         gobject_class->set_property = location_hybrid_set_property;
1203         gobject_class->get_property = location_hybrid_get_property;
1204
1205         gobject_class->dispose = location_hybrid_dispose;
1206         gobject_class->finalize = location_hybrid_finalize;
1207
1208         g_type_class_add_private(klass, sizeof(LocationHybridPrivate));
1209
1210         signals[SERVICE_ENABLED] =
1211                         g_signal_new("service-enabled", G_TYPE_FROM_CLASS(klass),
1212                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1213                         G_STRUCT_OFFSET(LocationHybridClass, enabled),
1214                         NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1215
1216         signals[SERVICE_DISABLED] =
1217                         g_signal_new("service-disabled", G_TYPE_FROM_CLASS(klass),
1218                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1219                         G_STRUCT_OFFSET(LocationHybridClass, disabled),
1220                         NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1221
1222         signals[SERVICE_UPDATED] =
1223                         g_signal_new("service-updated", G_TYPE_FROM_CLASS(klass),
1224                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1225                         G_STRUCT_OFFSET(LocationHybridClass, service_updated),
1226                         NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER,
1227                         G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1228
1229         signals[LOCATION_UPDATED] =
1230                         g_signal_new("location-updated", G_TYPE_FROM_CLASS(klass),
1231                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1232                         G_STRUCT_OFFSET(LocationHybridClass, location_updated),
1233                         NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER,
1234                         G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1235
1236         signals[ZONE_IN] =
1237                         g_signal_new("zone-in", G_TYPE_FROM_CLASS(klass),
1238                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1239                         G_STRUCT_OFFSET(LocationHybridClass, zone_in),
1240                         NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
1241                         G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1242
1243         signals[ZONE_OUT] =
1244                         g_signal_new("zone-out", G_TYPE_FROM_CLASS(klass),
1245                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1246                         G_STRUCT_OFFSET(LocationHybridClass, zone_out),
1247                         NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
1248                         G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1249
1250         properties[PROP_METHOD_TYPE] =
1251                         g_param_spec_int("method", "method type",
1252                         "location method type name", LOCATION_METHOD_HYBRID,
1253                         LOCATION_METHOD_HYBRID, LOCATION_METHOD_HYBRID, G_PARAM_READABLE);
1254
1255         properties[PROP_LAST_POSITION] =
1256                         g_param_spec_boxed("last-position", "hybrid last position prop",
1257                         "hybrid last position data", LOCATION_TYPE_POSITION, G_PARAM_READABLE);
1258
1259         properties[PROP_POS_INTERVAL] =
1260                         g_param_spec_uint("pos-interval", "position interval prop",
1261                         "position interval data", LOCATION_UPDATE_INTERVAL_MIN,
1262                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1263
1264         properties[PROP_VEL_INTERVAL] =
1265                         g_param_spec_uint("vel-interval", "velocity interval prop",
1266                         "velocity interval data", LOCATION_UPDATE_INTERVAL_MIN,
1267                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1268
1269         properties[PROP_SAT_INTERVAL] =
1270                         g_param_spec_uint("sat-interval", "satellite interval prop",
1271                         "satellite interval data", LOCATION_UPDATE_INTERVAL_MIN,
1272                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1273
1274         properties[PROP_LOC_INTERVAL] =
1275                         g_param_spec_uint("loc-interval", "gps location interval prop",
1276                         "gps location interval data", LOCATION_UPDATE_INTERVAL_MIN,
1277                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1278
1279         properties[PROP_MIN_INTERVAL] =
1280                         g_param_spec_uint("min-interval", "gps distance-based interval prop",
1281                         "gps distance-based interval data", LOCATION_MIN_INTERVAL_MIN,
1282                         LOCATION_MIN_INTERVAL_MAX, LOCATION_MIN_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1283
1284         properties[PROP_MIN_DISTANCE] =
1285                         g_param_spec_double("min-distance", "gps distance-based distance prop",
1286                         "gps distance-based distance data", LOCATION_MIN_DISTANCE_MIN,
1287                         LOCATION_MIN_DISTANCE_MAX, LOCATION_MIN_DISTANCE_DEFAULT, G_PARAM_READWRITE);
1288
1289         properties[PROP_BOUNDARY] =
1290                         g_param_spec_pointer("boundary", "hybrid boundary prop",
1291                         "hybrid boundary data", G_PARAM_READWRITE);
1292
1293         properties[PROP_REMOVAL_BOUNDARY] =
1294                         g_param_spec_boxed("removal-boundary", "hybrid removal boundary prop",
1295                         "hybrid removal boundary data", LOCATION_TYPE_BOUNDARY, G_PARAM_READWRITE);
1296
1297         /* Tizen 3.0 */
1298         properties[PROP_SERVICE_STATUS] =
1299                         g_param_spec_int("service-status", "location service status prop",
1300                         "location service status data", LOCATION_STATUS_NO_FIX,
1301                         LOCATION_STATUS_3D_FIX, LOCATION_STATUS_NO_FIX, G_PARAM_READABLE);
1302
1303         g_object_class_install_properties(gobject_class, PROP_MAX, properties);
1304 }