Dynamic interval table for multi handle
[platform/core/location/lbs-location.git] / location / manager / location-passive.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-passive.h"
32 #include "location-marshal.h"
33 #include "location-ielement.h"
34 #include "location-signaling-util.h"
35 #include "location-common-util.h"
36 #include "location-privacy.h"
37
38 #include <vconf-internal-location-keys.h>
39
40 /*
41  * forward definitions
42  */
43
44 typedef struct _LocationPassivePrivate {
45         LocationPassiveMod              *mod;
46         GMutex                          mutex;
47         gboolean                        is_started;
48         guint                           app_type;
49         gboolean                        set_noti;
50         gboolean                        enabled;
51         guint                           pos_updated_timestamp;
52         guint                           vel_updated_timestamp;
53         guint                           loc_updated_timestamp;
54         guint                           dist_updated_timestamp;
55         guint                           pos_interval;
56         guint                           vel_interval;
57         guint                           loc_interval;
58         guint                           loc_timeout;
59         guint                           min_interval;
60         gdouble                         min_distance;
61         LocationPosition        *pos;
62         LocationVelocity        *vel;
63         LocationAccuracy        *acc;
64         GList                           *boundary_list;
65 } LocationPassivePrivate;
66
67 enum {
68         PROP_0,
69         PROP_METHOD_TYPE,
70         PROP_IS_STARTED,
71         PROP_LAST_POSITION,
72         PROP_POS_INTERVAL,
73         PROP_VEL_INTERVAL,
74         PROP_LOC_INTERVAL,
75         PROP_BOUNDARY,
76         PROP_REMOVAL_BOUNDARY,
77         PROP_MIN_INTERVAL,
78         PROP_MIN_DISTANCE,
79         PROP_SERVICE_STATUS,
80         PROP_MAX
81 };
82
83 static guint32 signals[LAST_SIGNAL] = {0, };
84 static GParamSpec *properties[PROP_MAX] = {NULL, };
85
86 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), LOCATION_TYPE_PASSIVE, LocationPassivePrivate))
87
88 static void location_ielement_interface_init(LocationIElementInterface *iface);
89
90 G_DEFINE_TYPE_WITH_CODE(LocationPassive, location_passive, G_TYPE_OBJECT,
91                                                 G_IMPLEMENT_INTERFACE(LOCATION_TYPE_IELEMENT, location_ielement_interface_init));
92
93 static void __reset_pos_data_from_priv(LocationPassivePrivate *priv)
94 {
95         LOC_FUNC_LOG
96         g_return_if_fail(priv);
97
98         if (priv->pos) {
99                 location_position_free(priv->pos);
100                 priv->pos = NULL;
101         }
102         if (priv->vel) {
103                 location_velocity_free(priv->vel);
104                 priv->vel = NULL;
105         }
106         if (priv->acc) {
107                 location_accuracy_free(priv->acc);
108                 priv->acc = NULL;
109         }
110         priv->pos_updated_timestamp = 0;
111         priv->vel_updated_timestamp = 0;
112 }
113
114 static gboolean __get_started(gpointer self)
115 {
116         LocationPassivePrivate *priv = GET_PRIVATE(self);
117         g_return_val_if_fail(priv, FALSE);
118
119         return priv->is_started;
120 }
121
122 static int __set_started(gpointer self, gboolean started)
123 {
124         LocationPassivePrivate *priv = GET_PRIVATE(self);
125         g_return_val_if_fail(priv, -1);
126
127         if (priv->is_started != started) {
128                 g_mutex_lock(&priv->mutex);
129                 priv->is_started = started;
130                 g_mutex_unlock(&priv->mutex);
131         }
132
133         return 0;
134 }
135
136 static void passive_gps_cb(keynode_t * key, gpointer self)
137 {
138         LOC_FUNC_LOG
139         g_return_if_fail(key);
140         g_return_if_fail(self);
141         LocationPassivePrivate *priv = GET_PRIVATE(self);
142         g_return_if_fail(priv);
143         g_return_if_fail(priv->mod);
144         g_return_if_fail(priv->mod->handler);
145
146         LocationPosition *pos = NULL;
147         LocationVelocity *vel = NULL;
148         LocationAccuracy *acc = NULL;
149
150         LocModPassiveOps ops = priv->mod->ops;
151         int ret = ops.get_last_position(priv->mod->handler, &pos, &vel, &acc);
152         if (ret != LOCATION_ERROR_NONE) {
153                 LOCATION_LOGE("Fail to get position[%d]", ret);
154                 return ;
155         }
156
157         location_signaling(self, signals, TRUE, priv->boundary_list,
158                                         pos, vel, acc, priv->pos_interval, priv->vel_interval, priv->loc_interval,
159                                         &(priv->enabled), &(priv->pos_updated_timestamp),
160                                         &(priv->vel_updated_timestamp), &(priv->loc_updated_timestamp),
161                                         &(priv->pos), &(priv->vel), &(priv->acc));
162 }
163
164 static void passive_wps_cb(keynode_t *key, gpointer self)
165 {
166         LOC_FUNC_LOG
167         g_return_if_fail(key);
168         g_return_if_fail(self);
169         LocationPassivePrivate *priv = GET_PRIVATE(self);
170         g_return_if_fail(priv);
171         g_return_if_fail(priv->mod);
172         g_return_if_fail(priv->mod->handler);
173
174         LocationPosition *pos = NULL;
175         LocationVelocity *vel = NULL;
176         LocationAccuracy *acc = NULL;
177
178         LocModPassiveOps ops = priv->mod->ops;
179         int ret = ops.get_last_wps_position(priv->mod->handler, &pos, &vel, &acc);
180         if (ret != LOCATION_ERROR_NONE) {
181                 LOCATION_LOGE("Fail to get position[%d]", ret);
182                 return ;
183         }
184
185         if (location_setting_get_int(VCONFKEY_LOCATION_GPS_STATE) == VCONFKEY_LOCATION_GPS_CONNECTED)
186                 return ;
187
188         location_signaling(self, signals, TRUE, priv->boundary_list,
189                                         pos, vel, acc, priv->pos_interval, priv->vel_interval, priv->loc_interval,
190                                         &(priv->enabled), &(priv->pos_updated_timestamp),
191                                         &(priv->vel_updated_timestamp), &(priv->loc_updated_timestamp),
192                                         &(priv->pos), &(priv->vel), &(priv->acc));
193 }
194
195 static int location_passive_start(LocationPassive *self)
196 {
197         LOC_FUNC_LOG
198         LocationPassivePrivate *priv = GET_PRIVATE(self);
199         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
200         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
201         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
202
203         LOC_COND_RET(__get_started(self) == TRUE, LOCATION_ERROR_NONE, _E, "__get_started. Error[%s]", err_msg(LOCATION_ERROR_NONE));
204
205         int ret = LOCATION_ERROR_NONE;
206
207         if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED)) {
208                 ret = LOCATION_ERROR_SETTING_OFF;
209         } else {
210                 __set_started(self, TRUE);
211
212                 ret = location_setting_add_notify(VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP, passive_gps_cb, self);
213                 LOC_COND_RET(ret != LOCATION_ERROR_NONE, ret, _E, "Add vconf notify. Error[%s]", err_msg(ret));
214
215                 ret = location_setting_add_notify(VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP, passive_wps_cb, self);
216                 LOC_COND_RET(ret != LOCATION_ERROR_NONE, ret, _E, "Add vconf notify. Error[%s]", err_msg(ret));
217         }
218
219         if (priv->app_type != CPPAPP && priv->set_noti == FALSE)
220                 priv->set_noti = TRUE;
221
222         return ret;
223 }
224
225 static int location_passive_stop(LocationPassive *self)
226 {
227         LOC_FUNC_LOG
228         LocationPassivePrivate *priv = GET_PRIVATE(self);
229         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
230         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
231         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
232
233         int ret = LOCATION_ERROR_NONE;
234
235         if (__get_started(self) == TRUE) {
236                 __set_started(self, FALSE);
237                 g_signal_emit(self, signals[SERVICE_DISABLED], 0, LOCATION_STATUS_NO_FIX);
238         }
239
240         if (priv->app_type != CPPAPP && priv->set_noti == TRUE)
241                 priv->set_noti = FALSE;
242
243         __reset_pos_data_from_priv(priv);
244
245         return ret;
246 }
247
248 static void location_passive_dispose(GObject *gobject)
249 {
250         LOC_FUNC_LOG
251         LocationPassivePrivate *priv = GET_PRIVATE(gobject);
252         g_return_if_fail(priv);
253
254         g_mutex_clear(&priv->mutex);
255
256         if (priv->app_type != CPPAPP && priv->set_noti == TRUE)
257                 priv->set_noti = FALSE;
258
259         G_OBJECT_CLASS(location_passive_parent_class)->dispose(gobject);
260 }
261
262 static void location_passive_finalize(GObject *gobject)
263 {
264         LOC_FUNC_LOG
265         LocationPassivePrivate *priv = GET_PRIVATE(gobject);
266         g_return_if_fail(priv);
267
268         if (priv->boundary_list) {
269                 g_list_free_full(priv->boundary_list, free_boundary_list);
270                 priv->boundary_list = NULL;
271         }
272
273         if (priv->pos) {
274                 location_position_free(priv->pos);
275                 priv->pos = NULL;
276         }
277
278         if (priv->vel) {
279                 location_velocity_free(priv->vel);
280                 priv->vel = NULL;
281         }
282
283         if (priv->acc) {
284                 location_accuracy_free(priv->acc);
285                 priv->acc = NULL;
286         }
287         G_OBJECT_CLASS(location_passive_parent_class)->finalize(gobject);
288 }
289
290 static void location_passive_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
291 {
292         LocationPassivePrivate *priv = GET_PRIVATE(object);
293         g_return_if_fail(priv);
294         int ret = 0;
295
296         switch (property_id) {
297         case PROP_BOUNDARY: {
298                 GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
299                 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
300                 if (ret != LOCATION_ERROR_NONE)
301                         LOCATION_LOGE("Set boundary. Error[%d]", ret);
302                 if (boundary_list)
303                         g_list_free(boundary_list);
304                 break;
305         }
306         case PROP_REMOVAL_BOUNDARY: {
307                 LocationBoundary *req_boundary = (LocationBoundary *) g_value_dup_boxed(value);
308                 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
309                 if (ret != 0) LOCATION_LOGD("Set removal boundary. Error[%d]", ret);
310                 break;
311         }
312         case PROP_POS_INTERVAL: {
313                 guint interval = g_value_get_uint(value);
314                 if (interval > 0) {
315                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
316                                 priv->pos_interval = interval;
317                         else
318                                 priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
319                 } else {
320                         priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
321                 }
322
323                 break;
324         }
325         case PROP_VEL_INTERVAL: {
326                 guint interval = g_value_get_uint(value);
327                 if (interval > 0) {
328                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
329                                 priv->vel_interval = interval;
330                         else
331                                 priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
332                 } else {
333                         priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
334                 }
335                 break;
336         }
337         case PROP_LOC_INTERVAL: {
338                 guint interval = g_value_get_uint(value);
339                 LOCATION_LOGD("Set prop>> PROP_LOC_INTERVAL: %u", interval);
340                 if (interval > 0) {
341                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
342                                 priv->loc_interval = interval;
343                         else
344                                 priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
345                 } else {
346                         priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
347                 }
348
349                 break;
350         }
351         case PROP_MIN_INTERVAL: {
352                 guint interval = g_value_get_uint(value);
353                 LOCATION_LOGD("Set prop>> update-min-interval: %u", interval);
354                 if (interval > 0) {
355                         if (interval < LOCATION_MIN_INTERVAL_MAX)
356                                 priv->min_interval = interval;
357                         else
358                                 priv->min_interval = (guint)LOCATION_MIN_INTERVAL_MAX;
359                 } else {
360                         priv->min_interval = (guint)LOCATION_MIN_INTERVAL_DEFAULT;
361                 }
362
363                 break;
364         }
365         case PROP_MIN_DISTANCE: {
366                 gdouble distance = g_value_get_double(value);
367                 LOCATION_LOGD("Set prop>> update-min-distance: %u", distance);
368                 if (distance > 0) {
369                         if (distance < LOCATION_MIN_DISTANCE_MAX)
370                                 priv->min_distance = distance;
371                         else
372                                 priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_MAX;
373                 } else {
374                         priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_DEFAULT;
375                 }
376
377                 break;
378         }
379         case PROP_SERVICE_STATUS: {
380                 gint enabled = g_value_get_int(value);
381                 LOCATION_LOGD("Set prop>> PROP_SERVICE_STATUS: %u", enabled);
382                 priv->enabled = enabled;
383                 break;
384         }
385         default:
386                 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
387                 break;
388         }
389 }
390
391 static void location_passive_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
392 {
393         LocationPassivePrivate *priv = GET_PRIVATE(object);
394         g_return_if_fail(priv);
395
396         switch (property_id) {
397         case PROP_METHOD_TYPE:
398                 g_value_set_int(value, LOCATION_METHOD_PASSIVE);
399                 break;
400         case PROP_IS_STARTED:
401                 g_value_set_boolean(value, __get_started(object));
402                 break;
403         case PROP_LAST_POSITION:
404                 g_value_set_boxed(value, priv->pos);
405                 break;
406         case PROP_BOUNDARY:
407                 g_value_set_pointer(value, g_list_first(priv->boundary_list));
408                 break;
409         case PROP_POS_INTERVAL:
410                 g_value_set_uint(value, priv->pos_interval);
411                 break;
412         case PROP_VEL_INTERVAL:
413                 g_value_set_uint(value, priv->vel_interval);
414                 break;
415         case PROP_LOC_INTERVAL:
416                 g_value_set_uint(value, priv->loc_interval);
417                 break;
418         case PROP_MIN_INTERVAL:
419                 g_value_set_uint(value, priv->min_interval);
420                 break;
421         case PROP_MIN_DISTANCE:
422                 g_value_set_double(value, priv->min_distance);
423                 break;
424         case PROP_SERVICE_STATUS:
425                 g_value_set_int(value, priv->enabled);
426                 break;
427         default:
428                 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
429                 break;
430         }
431 }
432
433 static int location_passive_get_position(LocationPassive *self, LocationPosition **position, LocationAccuracy **accuracy)
434 {
435         int ret = LOCATION_ERROR_NOT_AVAILABLE;
436
437         LocationPassivePrivate *priv = GET_PRIVATE(self);
438         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
439         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
440         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
441
442         if (__get_started(self) != TRUE) {
443                 LOCATION_LOGE("location is not started");
444                 return LOCATION_ERROR_NOT_AVAILABLE;
445         }
446
447         if (priv->pos) {
448                 *position = location_position_copy(priv->pos);
449                 if (priv->acc) *accuracy = location_accuracy_copy(priv->acc);
450                 else *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
451                 ret = LOCATION_ERROR_NONE;
452         }
453
454         return ret;
455 }
456
457 static int location_passive_get_position_ext(LocationPassive *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
458 {
459         int ret = LOCATION_ERROR_NOT_AVAILABLE;
460
461         LocationPassivePrivate *priv = GET_PRIVATE(self);
462         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
463         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
464         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
465
466         if (__get_started(self) != TRUE) {
467                 LOCATION_LOGE("location is not started");
468                 return LOCATION_ERROR_NOT_AVAILABLE;
469         }
470
471         if (priv->pos && priv->vel) {
472                 *position = location_position_copy(priv->pos);
473                 *velocity = location_velocity_copy(priv->vel);
474                 if (priv->acc) *accuracy = location_accuracy_copy(priv->acc);
475                 else *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
476                 ret = LOCATION_ERROR_NONE;
477         }
478
479         return ret;
480 }
481
482
483 static int location_passive_get_last_position(LocationPassive *self, LocationPosition **position, LocationAccuracy **accuracy)
484 {
485         LocationPassivePrivate *priv = GET_PRIVATE(self);
486         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
487         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
488         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
489
490         int ret = LOCATION_ERROR_NONE;
491         LocationVelocity *_velocity = NULL;
492
493         LocModPassiveOps ops = priv->mod->ops;
494         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
495         g_return_val_if_fail(ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
496
497         ret = ops.get_last_position(priv->mod->handler, position, &_velocity, accuracy);
498         if (_velocity) location_velocity_free(_velocity);
499
500         return ret;
501 }
502
503 static int location_passive_get_last_position_ext(LocationPassive *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
504 {
505         LocationPassivePrivate *priv = GET_PRIVATE(self);
506         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
507         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
508         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
509
510         LocModPassiveOps ops = priv->mod->ops;
511         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
512         g_return_val_if_fail(ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
513
514         return ops.get_last_position(priv->mod->handler, position, velocity, accuracy);
515 }
516
517 static int location_passive_get_velocity(LocationPassive *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
518 {
519         int ret = LOCATION_ERROR_NOT_AVAILABLE;
520
521         LocationPassivePrivate *priv = GET_PRIVATE(self);
522         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
523         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
524         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
525
526         if (__get_started(self) != TRUE) {
527                 LOCATION_LOGE("location is not started");
528                 return LOCATION_ERROR_NOT_AVAILABLE;
529         }
530
531         if (priv->vel) {
532                 *velocity = location_velocity_copy(priv->vel);
533                 if (priv->acc) *accuracy = location_accuracy_copy(priv->acc);
534                 else *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
535                 ret = LOCATION_ERROR_NONE;
536         }
537
538         return ret;
539 }
540
541 static int location_passive_get_last_velocity(LocationPassive *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
542 {
543         LocationPassivePrivate *priv = GET_PRIVATE(self);
544         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
545         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
546         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
547
548         int ret = LOCATION_ERROR_NONE;
549         LocationPosition *_position = NULL;
550
551         LocModPassiveOps ops = priv->mod->ops;
552         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
553         ret = ops.get_last_position(priv->mod->handler, &_position, velocity, accuracy);
554         if (!_position) location_position_free(_position);
555
556         return ret;
557 }
558
559 static int location_passive_request_single_location(LocationPassive *self, int timeout)
560 {
561         return LOCATION_ERROR_NOT_SUPPORTED;
562 }
563
564 static int location_passive_get_satellite(LocationPassive *self, LocationSatellite **satellite)
565 {
566         return LOCATION_ERROR_NOT_SUPPORTED;
567 }
568
569 static int location_passive_get_last_satellite(LocationPassive *self, LocationSatellite **satellite)
570 {
571         return LOCATION_ERROR_NOT_SUPPORTED;
572 }
573
574 static int location_passive_set_option(LocationPassive *self, const char *option)
575 {
576         LocationPassivePrivate *priv = GET_PRIVATE(self);
577         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
578
579         return LOCATION_ERROR_NONE;
580 }
581
582 static int location_passive_get_nmea(LocationPassive *self, char **nmea_data)
583 {
584         return LOCATION_ERROR_NOT_SUPPORTED;
585 }
586
587 static void location_ielement_interface_init(LocationIElementInterface *iface)
588 {
589         iface->start = (TYPE_START_FUNC)location_passive_start;
590         iface->stop = (TYPE_STOP_FUNC)location_passive_stop;
591         iface->get_position = (TYPE_GET_POSITION)location_passive_get_position;
592         iface->get_position_ext = (TYPE_GET_POSITION_EXT)location_passive_get_position_ext;
593         iface->get_last_position = (TYPE_GET_POSITION)location_passive_get_last_position;
594         iface->get_last_position_ext = (TYPE_GET_POSITION_EXT)location_passive_get_last_position_ext;
595         iface->get_velocity = (TYPE_GET_VELOCITY)location_passive_get_velocity;
596         iface->get_last_velocity = (TYPE_GET_VELOCITY)location_passive_get_last_velocity;
597         iface->get_satellite = (TYPE_GET_SATELLITE)location_passive_get_satellite;
598         iface->get_last_satellite = (TYPE_GET_SATELLITE)location_passive_get_last_satellite;
599         iface->set_option = (TYPE_SET_OPTION)location_passive_set_option;
600         iface->request_single_location = (TYPE_REQUEST_SINGLE_LOCATION)location_passive_request_single_location;
601         iface->get_nmea = (TYPE_GET_NMEA)location_passive_get_nmea;
602 }
603
604 static void location_passive_init(LocationPassive *self)
605 {
606         LOC_FUNC_LOG
607         LocationPassivePrivate *priv = GET_PRIVATE(self);
608         g_return_if_fail(priv);
609
610         priv->mod = (LocationPassiveMod *)module_new("passive");
611         if (!priv->mod) LOCATION_LOGW("module loading failed");
612
613         g_mutex_init(&priv->mutex);
614         priv->is_started = FALSE;
615         priv->set_noti = FALSE;
616         priv->enabled = FALSE;
617
618         priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
619         priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
620         priv->loc_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
621         priv->min_interval = LOCATION_UPDATE_INTERVAL_NONE;
622
623         priv->pos_updated_timestamp = 0;
624         priv->vel_updated_timestamp = 0;
625         priv->loc_updated_timestamp = 0;
626
627         priv->pos = NULL;
628         priv->vel = NULL;
629         priv->acc = NULL;
630         priv->boundary_list = NULL;
631
632         priv->loc_timeout = 0;
633
634         priv->app_type = location_get_app_type(NULL);
635         if (priv->app_type == 0)
636                 LOCATION_LOGW("Fail to get app_type");
637 }
638
639 static void location_passive_class_init(LocationPassiveClass *klass)
640 {
641         LOC_FUNC_LOG
642         GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
643
644         gobject_class->set_property = location_passive_set_property;
645         gobject_class->get_property = location_passive_get_property;
646
647         gobject_class->dispose = location_passive_dispose;
648         gobject_class->finalize = location_passive_finalize;
649
650         g_type_class_add_private(klass, sizeof(LocationPassivePrivate));
651
652         signals[SERVICE_ENABLED] =
653                         g_signal_new("service-enabled", G_TYPE_FROM_CLASS(klass),
654                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
655                         G_STRUCT_OFFSET(LocationPassiveClass, enabled),
656                         NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
657
658         signals[SERVICE_DISABLED] =
659                         g_signal_new("service-disabled", G_TYPE_FROM_CLASS(klass),
660                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
661                         G_STRUCT_OFFSET(LocationPassiveClass, disabled),
662                         NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
663
664         signals[SERVICE_UPDATED] =
665                         g_signal_new("service-updated", G_TYPE_FROM_CLASS(klass),
666                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
667                         G_STRUCT_OFFSET(LocationPassiveClass, service_updated),
668                         NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER, G_TYPE_NONE, 4,
669                         G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
670
671         signals[LOCATION_UPDATED] =
672                         g_signal_new("location-updated", G_TYPE_FROM_CLASS(klass),
673                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
674                         G_STRUCT_OFFSET(LocationPassiveClass, location_updated),
675                         NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER,
676                         G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
677
678         signals[ZONE_IN] =
679                         g_signal_new("zone-in", G_TYPE_FROM_CLASS(klass),
680                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
681                         G_STRUCT_OFFSET(LocationPassiveClass, zone_in),
682                         NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
683                         G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
684
685         signals[ZONE_OUT] =
686                         g_signal_new("zone-out", G_TYPE_FROM_CLASS(klass),
687                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
688                         G_STRUCT_OFFSET(LocationPassiveClass, zone_out),
689                         NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
690                         G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
691
692         properties[PROP_METHOD_TYPE] =
693                         g_param_spec_int("method", "method type", "location method type name",
694                         LOCATION_METHOD_PASSIVE, LOCATION_METHOD_PASSIVE, LOCATION_METHOD_PASSIVE, G_PARAM_READABLE);
695
696         properties[PROP_IS_STARTED] =
697                         g_param_spec_boolean("is_started", "passive is started prop",
698                         "passive is started status", FALSE, G_PARAM_READWRITE);
699
700         properties[PROP_LAST_POSITION] =
701                         g_param_spec_boxed("last-position", "passive last position prop",
702                         "passive last position data", LOCATION_TYPE_POSITION, G_PARAM_READABLE);
703
704         properties[PROP_POS_INTERVAL] =
705                         g_param_spec_uint("pos-interval", "passive position interval prop",
706                         "passive position interval data", LOCATION_UPDATE_INTERVAL_MIN,
707                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
708
709         properties[PROP_VEL_INTERVAL] =
710                         g_param_spec_uint("vel-interval", "passive velocity interval prop",
711                         "passive velocity interval data", LOCATION_UPDATE_INTERVAL_MIN,
712                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
713
714         properties[PROP_LOC_INTERVAL] =
715                         g_param_spec_uint("loc-interval", "passive location interval prop",
716                         "passive location interval data", LOCATION_UPDATE_INTERVAL_MIN,
717                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
718
719         properties[PROP_MIN_INTERVAL] =
720                         g_param_spec_uint("min-interval", "passive distance-based interval prop",
721                         "passive distance-based interval data", LOCATION_MIN_INTERVAL_MIN,
722                         LOCATION_MIN_INTERVAL_MAX, LOCATION_MIN_INTERVAL_DEFAULT, G_PARAM_READWRITE);
723
724         properties[PROP_MIN_DISTANCE] =
725                         g_param_spec_double("min-distance", "passive distance-based distance prop",
726                         "passive distance-based distance data", LOCATION_MIN_DISTANCE_MIN,
727                         LOCATION_MIN_DISTANCE_MAX, LOCATION_MIN_DISTANCE_DEFAULT, G_PARAM_READWRITE);
728
729         properties[PROP_BOUNDARY] =
730                         g_param_spec_pointer("boundary", "passive boundary prop",
731                         "passive boundary data", G_PARAM_READWRITE);
732
733         properties[PROP_REMOVAL_BOUNDARY] =
734                         g_param_spec_boxed("removal-boundary", "passive removal boundary prop",
735                         "passive removal boundary data", LOCATION_TYPE_BOUNDARY, G_PARAM_READWRITE);
736
737         /* Tizen 3.0 */
738         properties[PROP_SERVICE_STATUS] =
739                         g_param_spec_int("service-status", "location service status prop",
740                         "location service status data", LOCATION_STATUS_NO_FIX,
741                         LOCATION_STATUS_3D_FIX, LOCATION_STATUS_NO_FIX, G_PARAM_READABLE);
742
743         g_object_class_install_properties(gobject_class, PROP_MAX, properties);
744 }
745