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