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