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