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