Support gps searching state in wearable profile
[platform/core/location/lbs-location.git] / location / manager / location-gps.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 <app_manager.h>
27 #include <sensor.h>
28 #include "location-setting.h"
29 #include "location-log.h"
30
31 #include "module-internal.h"
32
33 #include "location-gps.h"
34 #include "location-marshal.h"
35 #include "location-ielement.h"
36 #include "location-signaling-util.h"
37 #include "location-common-util.h"
38 #include "location-privacy.h"
39
40 #include <vconf-internal-location-keys.h>
41
42 typedef struct _LocationGpsPrivate {
43         LocationGpsMod          *mod;
44         GMutex                          mutex;
45         gboolean                        is_started;
46         gboolean                        is_batch_invoked;
47         gboolean                        is_mock;
48         guint                           app_type;
49         gboolean                        set_noti;
50         gboolean                        enabled;
51         gint                            signal_type;
52         guint                           pos_updated_timestamp;
53         guint                           pos_interval;
54         guint                           vel_updated_timestamp;
55         guint                           vel_interval;
56         guint                           sat_updated_timestamp;
57         guint                           sat_interval;
58         guint                           loc_updated_timestamp;
59         guint                           loc_interval;
60         guint                           loc_timeout;
61         guint                           batch_interval;
62         guint                           batch_period;
63         guint                           dist_updated_timestamp;
64         guint                           min_interval;
65         gdouble                         min_distance;
66         LocationPosition        *pos;
67         LocationBatch           *batch;
68         LocationVelocity        *vel;
69         LocationAccuracy        *acc;
70         LocationSatellite       *sat;
71         GList                           *boundary_list;
72 #if defined(TIZEN_DEVICE) && !defined(TIZEN_PROFILE_TV)
73         sensor_h sensor;
74         sensor_listener_h sensor_listener;
75 #endif
76 } LocationGpsPrivate;
77
78 enum {
79         PROP_0,
80         PROP_METHOD_TYPE,
81         PROP_IS_STARTED,
82         PROP_LAST_POSITION,
83         PROP_POS_INTERVAL,
84         PROP_VEL_INTERVAL,
85         PROP_SAT_INTERVAL,
86         PROP_LOC_INTERVAL,
87         PROP_BATCH_INTERVAL,
88         PROP_BATCH_PERIOD,
89         PROP_BOUNDARY,
90         PROP_REMOVAL_BOUNDARY,
91         PROP_NMEA,
92         PROP_SATELLITE,
93         PROP_MIN_INTERVAL,
94         PROP_MIN_DISTANCE,
95         PROP_SERVICE_STATUS,
96         PROP_MAX
97 };
98
99 static guint32 signals[LAST_SIGNAL] = {0, };
100 static GParamSpec *properties[PROP_MAX] = {NULL, };
101
102 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), LOCATION_TYPE_GPS, LocationGpsPrivate))
103
104 static void location_ielement_interface_init(LocationIElementInterface *iface);
105
106 G_DEFINE_TYPE_WITH_CODE(LocationGps, location_gps, G_TYPE_OBJECT,
107                                                 G_IMPLEMENT_INTERFACE(LOCATION_TYPE_IELEMENT, location_ielement_interface_init));
108
109 static void __reset_pos_data_from_priv(LocationGpsPrivate *priv)
110 {
111         LOC_FUNC_LOG
112         g_return_if_fail(priv);
113
114         if (priv->pos) {
115                 location_position_free(priv->pos);
116                 priv->pos = NULL;
117         }
118
119         if (priv->batch) {
120                 location_batch_free(priv->batch);
121                 priv->batch = NULL;
122         }
123
124         if (priv->vel) {
125                 location_velocity_free(priv->vel);
126                 priv->vel = NULL;
127         }
128
129         if (priv->sat) {
130                 location_satellite_free(priv->sat);
131                 priv->sat = NULL;
132         }
133
134         if (priv->acc) {
135                 location_accuracy_free(priv->acc);
136                 priv->acc = NULL;
137         }
138         priv->pos_updated_timestamp = 0;
139         priv->vel_updated_timestamp = 0;
140         priv->sat_updated_timestamp = 0;
141         priv->loc_updated_timestamp = 0;
142
143         priv->signal_type = 0;
144 }
145
146 static gboolean __get_started(gpointer self)
147 {
148         g_return_val_if_fail(self, FALSE);
149
150         LocationGpsPrivate *priv = GET_PRIVATE(self);
151         g_return_val_if_fail(priv, FALSE);
152
153         return priv->is_started;
154 }
155
156 static int __set_started(gpointer self, gboolean started)
157 {
158         g_return_val_if_fail(self, -1);
159
160         LocationGpsPrivate *priv = GET_PRIVATE(self);
161         g_return_val_if_fail(priv, -1);
162
163         if (priv->is_started != started) {
164                 g_mutex_lock(&priv->mutex);
165                 priv->is_started = started;
166                 g_mutex_unlock(&priv->mutex);
167         }
168
169         return 0;
170 }
171
172 static void gps_status_cb(gboolean enabled, LocationStatus status, gpointer self)
173 {
174         LOC_FUNC_LOG
175         g_return_if_fail(self);
176         LocationGpsPrivate *priv = GET_PRIVATE(self);
177         g_return_if_fail(priv);
178         if (!priv->enabled && enabled) {        /* Update satellite at searching status. */
179                 return; /* Ignored: Support to get position at enabled callback */
180         } else if (priv->enabled == TRUE && enabled == FALSE) {
181                 __set_started(self, FALSE);
182                 enable_signaling(self, signals, &(priv->enabled), enabled, status);
183         }
184 }
185
186 static void gps_location_cb(gboolean enabled, LocationPosition *pos, LocationVelocity *vel, LocationAccuracy *acc, gpointer self)
187 {
188         g_return_if_fail(self);
189         g_return_if_fail(pos);
190         g_return_if_fail(vel);
191         g_return_if_fail(acc);
192
193         LocationGpsPrivate *priv = GET_PRIVATE(self);
194         g_return_if_fail(priv);
195
196         if (priv->min_interval != LOCATION_UPDATE_INTERVAL_NONE) {
197                 distance_based_position_signaling(self, signals, enabled, pos, vel, acc,
198                                                         priv->min_interval, priv->min_distance, &(priv->enabled),
199                                                         &(priv->dist_updated_timestamp), &(priv->pos), &(priv->vel), &(priv->acc));
200         }
201         location_signaling(self, signals, enabled, priv->boundary_list, pos, vel, acc,
202                                                 priv->pos_interval, priv->vel_interval, priv->loc_interval, &(priv->enabled),
203                                                 &(priv->pos_updated_timestamp), &(priv->vel_updated_timestamp),
204                                                 &(priv->loc_updated_timestamp), &(priv->pos), &(priv->vel), &(priv->acc));
205 }
206
207 #ifndef TIZEN_DEVICE
208 static void gps_batch_cb(gboolean enabled, guint num_of_location, gpointer self)
209 {
210         g_return_if_fail(self);
211         LocationGpsPrivate *priv = GET_PRIVATE(self);
212         g_return_if_fail(priv);
213
214         if (priv->batch != NULL)
215                 location_batch_free(priv->batch);
216
217         priv->batch = location_get_batch_file(num_of_location);
218
219         g_signal_emit(self, signals[BATCH_UPDATED], 0, num_of_location);
220 }
221 #endif
222
223 static void gps_satellite_cb(gboolean enabled, LocationSatellite *sat, gpointer self)
224 {
225         g_return_if_fail(self);
226         LocationGpsPrivate *priv = GET_PRIVATE(self);
227         g_return_if_fail(priv);
228
229         satellite_signaling(self, signals, &(priv->enabled), priv->sat_interval, TRUE, &(priv->sat_updated_timestamp), &(priv->sat), sat);
230 }
231
232 static void location_setting_search_cb(keynode_t *key, gpointer self)
233 {
234         LOC_FUNC_LOG
235         g_return_if_fail(key);
236         g_return_if_fail(self);
237         LocationGpsPrivate *priv = GET_PRIVATE(self);
238         g_return_if_fail(priv);
239
240         if (location_setting_get_key_val(key) == VCONFKEY_LOCATION_GPS_SEARCHING) {
241                 if (!location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED)) {
242                         LOCATION_LOGD("enable_signaling : SERVICE_DISABLED");
243                         enable_signaling(self, signals, &(priv->enabled), FALSE, LOCATION_STATUS_NO_FIX);
244                 }
245         }
246 }
247
248 static void location_setting_gps_cb(keynode_t *key, gpointer self)
249 {
250         LOC_FUNC_LOG
251         g_return_if_fail(key);
252         g_return_if_fail(self);
253         LocationGpsPrivate *priv = GET_PRIVATE(self);
254         g_return_if_fail(priv);
255         g_return_if_fail(priv->mod);
256         g_return_if_fail(priv->mod->handler);
257
258         int ret = LOCATION_ERROR_NONE;
259
260         if (0 == location_setting_get_key_val(key) && priv->mod->ops.stop && __get_started(self)) {
261                 LOCATION_LOGD("location stopped by setting");
262                 __set_started(self, FALSE);
263                 ret = priv->mod->ops.stop(priv->mod->handler);
264                 if (ret == LOCATION_ERROR_NONE)
265                         __reset_pos_data_from_priv(priv);
266                 else
267                         LOCATION_LOGI("Fail to stop[%d]", ret);
268
269         } else if (1 == location_setting_get_key_val(key) && priv->mod->ops.start && !__get_started(self)) {
270                 LOCATION_LOGD("location resumed by setting");
271                 __set_started(self, TRUE);
272                 ret = priv->mod->ops.start(priv->mod->handler, priv->pos_interval, gps_status_cb, gps_location_cb, gps_satellite_cb, self);
273                 if (ret != LOCATION_ERROR_NONE) {
274                         __set_started(self, FALSE);
275                         LOCATION_LOGI("Fail to start[%d]", ret);
276                 }
277         }
278 }
279
280 static int location_gps_start(LocationGps *self)
281 {
282         LOC_FUNC_LOG
283         LocationGpsPrivate *priv = GET_PRIVATE(self);
284         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
285         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
286         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
287         g_return_val_if_fail(priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE);
288
289         if (__get_started(self) == TRUE) return LOCATION_ERROR_NONE;
290
291         int ret = LOCATION_ERROR_NONE;
292
293         if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED)) {
294                 ret = LOCATION_ERROR_SETTING_OFF;
295         } else if (location_setting_get_int(VCONFKEY_SETAPPL_PSMODE) == SETTING_PSMODE_WEARABLE_ENHANCED) {
296                 return LOCATION_ACCESS_DENIED;
297         } else {
298                 __set_started(self, TRUE);
299                 ret = priv->mod->ops.start(priv->mod->handler, priv->pos_interval, gps_status_cb, gps_location_cb, gps_satellite_cb, self);
300                 if (ret != LOCATION_ERROR_NONE) {
301                         LOCATION_LOGE("Fail to start gps. Error[%d]", ret);
302                         __set_started(self, FALSE);
303                         return ret;
304                 }
305         }
306
307         if (priv->app_type != CPPAPP && priv->set_noti == FALSE) {
308                 location_setting_add_notify(VCONFKEY_LOCATION_ENABLED, location_setting_gps_cb, self);
309
310                 location_state_add_notify(VCONFKEY_LOCATION_GPS_STATE, location_setting_search_cb, self);
311                 priv->set_noti = TRUE;
312         }
313
314         LOCATION_LOGD("EXIT <<<");
315         return ret;
316 }
317
318 static int location_gps_stop(LocationGps *self)
319 {
320         LOC_FUNC_LOG
321         LocationGpsPrivate *priv = GET_PRIVATE(self);
322         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
323         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
324         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
325         g_return_val_if_fail(priv->mod->ops.stop, LOCATION_ERROR_NOT_AVAILABLE);
326
327         int ret = LOCATION_ERROR_NONE;
328
329         if (__get_started(self) == TRUE) {
330                 __set_started(self, FALSE);
331                 ret = priv->mod->ops.stop(priv->mod->handler);
332                 LOC_IF_FAIL_LOG(ret, _E, "Failed to stop [%s]", err_msg(ret));
333         } else {
334                 return LOCATION_ERROR_NONE;
335         }
336
337         if (priv->app_type != CPPAPP && priv->set_noti == TRUE) {
338                 location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_setting_gps_cb);
339                 location_state_ignore_notify(VCONFKEY_LOCATION_GPS_STATE, location_setting_search_cb);
340                 priv->set_noti = FALSE;
341         }
342
343         __reset_pos_data_from_priv(priv);
344
345         return ret;
346 }
347
348 #if defined(TIZEN_DEVICE) && !defined(TIZEN_PROFILE_TV)
349 static void __sensor_event_cb(sensor_h s, sensor_event_s *event, void *data)
350 {
351         LocationGpsPrivate *priv = GET_PRIVATE(data);
352         g_return_if_fail(priv);
353         g_return_if_fail(event);
354
355         int remain_idx = (int)(event->values[4]);
356
357         if (priv->is_batch_invoked) {
358                 location_batch_free(priv->batch);
359                 priv->is_batch_invoked = FALSE;
360                 priv->batch = NULL;
361         }
362
363         if (priv->batch == NULL) {
364                 g_return_if_fail(event->value_count <= 5);
365                 priv->batch = location_batch_new(remain_idx + 1);
366                 g_return_if_fail(priv->batch);
367                 priv->batch->num_of_location = remain_idx + 1;
368                 time_t start;
369                 time(&start);
370                 priv->batch->start_time = start + (time_t)((event->timestamp / 1001000) % 100000);
371         }
372
373         location_set_sensor_batch(priv->batch, event);
374
375         if (remain_idx == 0) {
376                 g_signal_emit(data, signals[BATCH_UPDATED], 0, priv->batch->num_of_location);
377                 priv->is_batch_invoked = TRUE;
378         }
379 }
380
381 static int __set_sensor_batch(LocationGps *self, int batch_interval)
382 {
383         LOC_FUNC_LOG
384         LocationGpsPrivate *priv = GET_PRIVATE(self);
385         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
386
387         if (priv->batch != NULL) {
388                 location_batch_free(priv->batch);
389                 priv->batch = NULL;
390         }
391
392         int update_interval = batch_interval * 1000;    /* in ms */
393         int ret = 0;
394         bool supported = false;
395
396         ret = sensor_is_supported((sensor_type_e)0x1A02, &supported);
397         LOC_IF_FAIL(ret, _E, "Fail to sensor_is_supported [%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
398         LOC_COND_RET(!supported, LOCATION_ERROR_NOT_SUPPORTED, _E, "Batch sensor is not supported [%s]", err_msg(LOCATION_ERROR_NOT_SUPPORTED));
399
400         ret = sensor_get_default_sensor((sensor_type_e)0x1A02, &priv->sensor);
401         LOC_IF_FAIL(ret, _E, "Fail to sensor_get_default_sensor [%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
402
403         ret = sensor_create_listener(priv->sensor, &priv->sensor_listener);
404         LOC_IF_FAIL(ret, _E, "Fail to sensor_create_listener [%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
405
406         ret = sensor_listener_set_event_cb(priv->sensor_listener, update_interval, __sensor_event_cb, self);
407         if (ret != SENSOR_ERROR_NONE) {
408                 LOCATION_LOGE("sensor_listener_set_event_cb() failed");
409                 sensor_destroy_listener(priv->sensor_listener);
410                 return LOCATION_ERROR_NOT_AVAILABLE;
411         }
412
413         ret = sensor_listener_set_option(priv->sensor_listener, SENSOR_OPTION_ALWAYS_ON);
414         if (ret != SENSOR_ERROR_NONE) {
415                 LOCATION_LOGE("sensor_listener_set_option() failed");
416                 sensor_destroy_listener(priv->sensor_listener);
417                 return LOCATION_ERROR_NOT_AVAILABLE;
418         }
419         ret = sensor_listener_start(priv->sensor_listener);
420         if (ret != SENSOR_ERROR_NONE) {
421                 LOCATION_LOGE("sensor_listener_set_event_cb() failed");
422                 sensor_destroy_listener(priv->sensor_listener);
423                 return LOCATION_ERROR_NOT_AVAILABLE;
424         }
425
426         return LOCATION_ERROR_NONE;
427 }
428 #endif
429
430 static int location_gps_start_batch(LocationGps *self)
431 {
432         LOC_FUNC_LOG
433         LocationGpsPrivate *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         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
437         g_return_val_if_fail(priv->mod->ops.start_batch, LOCATION_ERROR_NOT_AVAILABLE);
438
439         if (__get_started(self) == TRUE) return LOCATION_ERROR_NONE;
440
441         int ret = LOCATION_ERROR_NONE;
442
443         if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED)) {
444                 ret = LOCATION_ERROR_SETTING_OFF;
445         } else {
446 #ifndef TIZEN_DEVICE
447                 __set_started(self, TRUE);
448                 ret = priv->mod->ops.start_batch(priv->mod->handler, gps_batch_cb, priv->batch_interval, priv->batch_period, self);
449                 if (ret != LOCATION_ERROR_NONE) {
450                         LOCATION_LOGE("Fail to start_batch [%s]", err_msg(ret));
451                         __set_started(self, FALSE);
452                         return ret;
453                 }
454 #endif
455
456 #if defined(TIZEN_DEVICE) && !defined(TIZEN_PROFILE_TV)
457                 return  __set_sensor_batch(self, priv->batch_interval);
458 #endif
459         }
460
461         return ret;
462 }
463
464 static int location_gps_stop_batch(LocationGps *self)
465 {
466         LOC_FUNC_LOG
467         LocationGpsPrivate *priv = GET_PRIVATE(self);
468         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
469         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
470         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
471         g_return_val_if_fail(priv->mod->ops.stop_batch, LOCATION_ERROR_NOT_AVAILABLE);
472
473         int ret = LOCATION_ERROR_NONE;
474
475 #if defined(TIZEN_DEVICE) && !defined(TIZEN_PROFILE_TV)
476         ret = sensor_listener_stop(priv->sensor_listener);
477         LOC_IF_FAIL(ret, _E, "Fail to listener_stop [%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
478
479         ret = sensor_listener_unset_event_cb(priv->sensor_listener);
480         LOC_IF_FAIL_LOG(ret, _E, "Fail to listener_unset_event_cb [%s]", err_msg(ret));
481
482         ret = sensor_destroy_listener(priv->sensor_listener);
483         LOC_IF_FAIL_LOG(ret, _E, "Fail to destroy_listener [%s]", err_msg(ret));
484 #else
485         if (__get_started(self) == TRUE) {
486                 __set_started(self, FALSE);
487                 ret = priv->mod->ops.stop_batch(priv->mod->handler);
488                 LOC_IF_FAIL_LOG(ret, _E, "Failed to stop_batch [%s]", err_msg(ret));
489         } else {
490                 return LOCATION_ERROR_NONE;
491         }
492 #endif
493
494         __reset_pos_data_from_priv(priv);
495
496         return ret;
497 }
498
499 static void location_gps_dispose(GObject *gobject)
500 {
501         LOC_FUNC_LOG
502         LocationGpsPrivate *priv = GET_PRIVATE(gobject);
503         g_return_if_fail(priv);
504         g_mutex_clear(&priv->mutex);
505
506         if (priv->loc_timeout) g_source_remove(priv->loc_timeout);
507         priv->loc_timeout = 0;
508
509         if (priv->is_mock) {
510                 priv->mod->ops.clear_mock_location(priv->mod->handler, NULL, gobject);
511                 priv->is_mock = FALSE;
512         }
513
514         if (priv->app_type != CPPAPP && priv->set_noti == TRUE) {
515                 location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_setting_gps_cb);
516                 location_state_ignore_notify(VCONFKEY_LOCATION_GPS_STATE, location_setting_search_cb);
517                 priv->set_noti = FALSE;
518         }
519
520         G_OBJECT_CLASS(location_gps_parent_class)->dispose(gobject);
521 }
522
523 static void location_gps_finalize(GObject *gobject)
524 {
525         LOC_FUNC_LOG
526         LocationGpsPrivate *priv = GET_PRIVATE(gobject);
527         g_return_if_fail(priv);
528
529         module_free(priv->mod, "gps");
530         priv->mod = NULL;
531
532         if (priv->boundary_list) {
533                 g_list_free_full(priv->boundary_list, free_boundary_list);
534                 priv->boundary_list = NULL;
535         }
536
537         if (priv->pos) {
538                 location_position_free(priv->pos);
539                 priv->pos = NULL;
540         }
541
542         if (priv->batch) {
543                 location_batch_free(priv->batch);
544                 priv->batch = NULL;
545         }
546
547         if (priv->vel) {
548                 location_velocity_free(priv->vel);
549                 priv->vel = NULL;
550         }
551
552         if (priv->acc) {
553                 location_accuracy_free(priv->acc);
554                 priv->acc = NULL;
555         }
556
557         if (priv->sat) {
558                 location_satellite_free(priv->sat);
559                 priv->sat = NULL;
560         }
561         G_OBJECT_CLASS(location_gps_parent_class)->finalize(gobject);
562 }
563
564 static void location_gps_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
565 {
566         LocationGpsPrivate *priv = GET_PRIVATE(object);
567         g_return_if_fail(priv);
568         g_return_if_fail(priv->mod);
569         g_return_if_fail(priv->mod->handler);
570
571         int ret = 0;
572         switch (property_id) {
573         case PROP_BOUNDARY: {
574                 GList *boundary_list = g_list_copy(g_value_get_pointer(value));
575                 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
576                 LOC_IF_FAIL_LOG(ret, _E, "Set boundary. Error[%s]", err_msg(ret));
577                 if (boundary_list) g_list_free(boundary_list);
578                 break;
579         }
580         case PROP_REMOVAL_BOUNDARY: {
581                 LocationBoundary *req_boundary = (LocationBoundary *) g_value_dup_boxed(value);
582                 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
583                 LOC_IF_FAIL_LOG(ret, _E, "Removal boundary. Error[%s]", err_msg(ret));
584                 break;
585         }
586         case PROP_POS_INTERVAL: {
587                 guint interval = g_value_get_uint(value);
588                 LOCATION_LOGD("Set prop>> PROP_POS_INTERVAL: %u", interval);
589                 /* We don't need to set interval when new one is same as the previous one */
590                 if (interval == priv->pos_interval) break;
591
592                 if (interval > 0) {
593                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
594                                 priv->pos_interval = interval;
595                         else
596                                 priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
597                 } else {
598                         priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
599                 }
600
601                 if (__get_started(object) == TRUE) {
602                         LOCATION_LOGD("[update_pos_interval]: update pos-interval while pos-tracking");
603                         g_return_if_fail(priv->mod->ops.set_position_update_interval);
604                         priv->mod->ops.set_position_update_interval(priv->mod->handler, priv->pos_interval);
605                 }
606                 break;
607         }
608         case PROP_VEL_INTERVAL: {
609                 guint interval = g_value_get_uint(value);
610                 LOCATION_LOGD("Set prop>> PROP_VEL_INTERVAL: %u", interval);
611                 if (interval == priv->vel_interval) break;
612
613                 if (interval > 0) {
614                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
615                                 priv->vel_interval = interval;
616                         else
617                                 priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
618                 } else {
619                         priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
620                 }
621                 break;
622         }
623         case PROP_SAT_INTERVAL: {
624                 guint interval = g_value_get_uint(value);
625                 LOCATION_LOGD("Set prop>> PROP_SAT_INTERVAL: %u", interval);
626                 if (interval > 0) {
627                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
628                                 priv->sat_interval = interval;
629                         else
630                                 priv->sat_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
631                 } else {
632                         priv->sat_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
633                 }
634                 break;
635         }
636         case PROP_LOC_INTERVAL: {
637                 guint interval = g_value_get_uint(value);
638                 LOCATION_LOGD("Set prop>> PROP_LOC_INTERVAL: %u", interval);
639                 if (interval > 0) {
640                         if (interval < LOCATION_UPDATE_INTERVAL_MAX)
641                                 priv->loc_interval = interval;
642                         else
643                                 priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
644                 } else {
645                         priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
646                 }
647                 break;
648         }
649         case PROP_BATCH_INTERVAL: {
650                 guint interval = g_value_get_uint(value);
651                 LOCATION_LOGD("Set prop>> PROP_BATCH_INTERVAL: %u", interval);
652                 if (interval > 0) {
653                         if (interval < LOCATION_BATCH_INTERVAL_MAX)
654                                 priv->batch_interval = interval;
655                         else
656                                 priv->batch_interval = (guint)LOCATION_BATCH_INTERVAL_MAX;
657                 } else {
658                         priv->batch_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
659                 }
660
661                 if (__get_started(object) == TRUE) {
662                         LOCATION_LOGD("[update_batch_interval]: update batch-interval while pos-tracking");
663                         g_return_if_fail(priv->mod->ops.set_position_update_interval);
664                         priv->mod->ops.set_position_update_interval(priv->mod->handler, priv->batch_interval);
665                 }
666                 break;
667         }
668         case PROP_BATCH_PERIOD: {
669                 guint interval = g_value_get_uint(value);
670                 LOCATION_LOGD("Set prop>> PROP_BATCH_PERIOD: %u", interval);
671                 if (interval > 0) {
672                         if (interval < LOCATION_BATCH_PERIOD_MAX)
673                                 priv->batch_period = interval;
674                         else
675                                 priv->batch_period = (guint)LOCATION_BATCH_PERIOD_MAX;
676                 } else {
677                         priv->batch_period = (guint)LOCATION_BATCH_PERIOD_DEFAULT;
678                 }
679                 break;
680         }
681         case PROP_MIN_INTERVAL: {
682                 guint interval = g_value_get_uint(value);
683                 LOCATION_LOGD("Set prop>> PROP_MIN_INTERVAL: %u", interval);
684                 if (interval > 0) {
685                         if (interval < LOCATION_MIN_INTERVAL_MAX)
686                                 priv->min_interval = interval;
687                         else
688                                 priv->min_interval = (guint)LOCATION_MIN_INTERVAL_MAX;
689                 } else {
690                         priv->min_interval = (guint)LOCATION_MIN_INTERVAL_DEFAULT;
691                 }
692                 break;
693         }
694         case PROP_MIN_DISTANCE: {
695                 gdouble distance = g_value_get_double(value);
696                 LOCATION_LOGD("Set prop>> PROP_MIN_DISTANCE: %u", distance);
697                 if (distance > 0) {
698                         if (distance < LOCATION_MIN_DISTANCE_MAX)
699                                 priv->min_distance = distance;
700                         else
701                                 priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_MAX;
702                 } else {
703                         priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_DEFAULT;
704                 }
705
706                 break;
707         }
708         case PROP_SERVICE_STATUS: {
709                 gint enabled = g_value_get_int(value);
710                 LOCATION_LOGD("Set prop>> PROP_SERVICE_STATUS: %u", enabled);
711                 priv->enabled = enabled;
712                 break;
713         }
714         default:
715                 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
716                 break;
717         }
718 }
719
720 static void location_gps_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
721 {
722         LocationGpsPrivate *priv = GET_PRIVATE(object);
723         g_return_if_fail(priv);
724         g_return_if_fail(priv->mod);
725         g_return_if_fail(priv->mod->handler);
726         LocModGpsOps ops = priv->mod->ops;
727         switch (property_id) {
728         case PROP_METHOD_TYPE:
729                 g_value_set_int(value, LOCATION_METHOD_GPS);
730                 break;
731         case PROP_IS_STARTED:
732                 g_value_set_boolean(value, __get_started(object));
733                 break;
734         case PROP_LAST_POSITION:
735                 g_value_set_boxed(value, priv->pos);
736                 break;
737         case PROP_POS_INTERVAL:
738                 g_value_set_uint(value, priv->pos_interval);
739                 break;
740         case PROP_VEL_INTERVAL:
741                 g_value_set_uint(value, priv->vel_interval);
742                 break;
743         case PROP_SAT_INTERVAL:
744                 g_value_set_uint(value, priv->sat_interval);
745                 break;
746         case PROP_LOC_INTERVAL:
747                 g_value_set_uint(value, priv->loc_interval);
748                 break;
749         case PROP_BATCH_INTERVAL:
750                 g_value_set_uint(value, priv->batch_interval);
751                 break;
752         case PROP_BATCH_PERIOD:
753                 g_value_set_uint(value, priv->batch_period);
754                 break;
755         case PROP_MIN_INTERVAL:
756                 g_value_set_uint(value, priv->min_interval);
757                 break;
758         case PROP_MIN_DISTANCE:
759                 g_value_set_double(value, priv->min_distance);
760                 break;
761         case PROP_BOUNDARY:
762                 g_value_set_pointer(value, g_list_first(priv->boundary_list));
763                 break;
764         case PROP_NMEA: {
765                 char *nmea_data = NULL;
766                 if (ops.get_nmea && LOCATION_ERROR_NONE == ops.get_nmea(priv->mod->handler, &nmea_data) && nmea_data) {
767                         LOCATION_SECLOG("Get prop>> Lastest nmea: \n%s", nmea_data);
768                         g_value_set_string(value, nmea_data);
769                         g_free(nmea_data);
770                 } else {
771                         LOCATION_LOGW("Get prop>> Lastest nmea: failed");
772                         g_value_set_string(value, NULL);
773                 }
774                 break;
775         }
776         case PROP_SATELLITE: {
777                 LocationSatellite *satellite = NULL;
778                 if (ops.get_satellite && priv->mod->handler && LOCATION_ERROR_NONE == ops.get_satellite(priv->mod->handler, &satellite) && satellite) {
779                         LOCATION_LOGD("Get prop>> Last sat: num_used(%d) num_view(%d)", satellite->num_of_sat_used, satellite->num_of_sat_inview);
780                         g_value_set_boxed(value, satellite);
781                         location_satellite_free(satellite);
782                 } else {
783                         LOCATION_LOGW("Get prop>> Last sat: failed");
784                         g_value_set_boxed(value, NULL);
785                 }
786                 break;
787         }
788         case PROP_SERVICE_STATUS:
789                 g_value_set_int(value, priv->enabled);
790                 break;
791         default:
792                 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
793                 break;
794         }
795 }
796
797 static int location_gps_get_position(LocationGps *self, LocationPosition **position, LocationAccuracy **accuracy)
798 {
799         int ret = LOCATION_ERROR_NOT_AVAILABLE;
800         LocationGpsPrivate *priv = GET_PRIVATE(self);
801         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
802         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
803
804         LOC_COND_RET(__get_started(self) != TRUE, LOCATION_ERROR_NOT_AVAILABLE, _E, "Location is not started [%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
805         LOCATION_IF_POS_FAIL(VCONFKEY_LOCATION_GPS_STATE);
806
807         if (priv->pos) {
808                 *position = location_position_copy(priv->pos);
809                 if (priv->acc) *accuracy = location_accuracy_copy(priv->acc);
810                 else *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
811                 ret = LOCATION_ERROR_NONE;
812         }
813
814         return ret;
815 }
816
817 static int
818 location_gps_get_position_ext(LocationGps *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
819 {
820         int ret = LOCATION_ERROR_NOT_AVAILABLE;
821         LocationGpsPrivate *priv = GET_PRIVATE(self);
822         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
823         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
824
825         LOC_COND_RET(__get_started(self) != TRUE, LOCATION_ERROR_NOT_AVAILABLE, _E, "Location is not started [%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
826         LOCATION_IF_POS_FAIL(VCONFKEY_LOCATION_GPS_STATE);
827
828         if (priv->pos && priv->vel) {
829                 *position = location_position_copy(priv->pos);
830                 *velocity = location_velocity_copy(priv->vel);
831                 if (priv->acc) *accuracy = location_accuracy_copy(priv->acc);
832                 else *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
833                 ret = LOCATION_ERROR_NONE;
834         }
835
836         return ret;
837 }
838
839 static int
840 location_gps_get_last_position(LocationGps *self, LocationPosition **position, LocationAccuracy **accuracy)
841 {
842         LocationGpsPrivate *priv = GET_PRIVATE(self);
843         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
844         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
845         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
846
847         int ret = LOCATION_ERROR_NONE;
848         LocationVelocity *_velocity = NULL;
849
850         LocModGpsOps ops = priv->mod->ops;
851         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
852         g_return_val_if_fail(ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
853         ret = ops.get_last_position(priv->mod->handler, position, &_velocity, accuracy);
854         if (_velocity) location_velocity_free(_velocity);
855
856         return ret;
857 }
858
859 static int
860 location_gps_get_last_position_ext(LocationGps *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
861 {
862         LocationGpsPrivate *priv = GET_PRIVATE(self);
863         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
864         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
865         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
866
867         LocModGpsOps ops = priv->mod->ops;
868         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
869         g_return_val_if_fail(ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
870         return ops.get_last_position(priv->mod->handler, position, velocity, accuracy);
871 }
872
873
874 static int
875 location_gps_get_velocity(LocationGps *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
876 {
877         int ret = LOCATION_ERROR_NOT_AVAILABLE;
878
879         LocationGpsPrivate *priv = GET_PRIVATE(self);
880         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
881         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
882
883         LOC_COND_RET(__get_started(self) != TRUE, LOCATION_ERROR_NOT_AVAILABLE, _E, "Location is not started [%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
884         LOCATION_IF_POS_FAIL(VCONFKEY_LOCATION_GPS_STATE);
885
886         if (priv->vel) {
887                 *velocity = location_velocity_copy(priv->vel);
888                 if (priv->acc) *accuracy = location_accuracy_copy(priv->acc);
889                 else *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
890                 ret = LOCATION_ERROR_NONE;
891         }
892
893         return ret;
894 }
895
896 static int
897 location_gps_get_last_velocity(LocationGps *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
898 {
899         LocationGpsPrivate *priv = GET_PRIVATE(self);
900         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
901         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
902         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
903
904         int ret = LOCATION_ERROR_NONE;
905         LocationPosition *_position = NULL;
906
907         LocModGpsOps ops = priv->mod->ops;
908         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
909         g_return_val_if_fail(ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
910         ret = ops.get_last_position(priv->mod->handler, &_position, velocity, accuracy);
911         if (_position) location_position_free(_position);
912
913         return ret;
914 }
915
916 static gboolean __single_location_timeout_cb(void *data)
917 {
918         LOC_FUNC_LOG
919         LocationGps *self = (LocationGps *)data;
920         LocationGpsPrivate *priv = GET_PRIVATE(self);
921         g_return_val_if_fail(priv, FALSE);
922
923         LocationPosition *pos = location_position_new(0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
924         LocationVelocity *vel = location_velocity_new(0, 0.0, 0.0, 0.0);
925         LocationAccuracy *acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
926
927         if (priv->loc_timeout) g_source_remove(priv->loc_timeout);
928         priv->loc_timeout = 0;
929
930         g_signal_emit(self, signals[LOCATION_UPDATED], 0, LOCATION_ERROR_NOT_AVAILABLE, pos, vel, acc);
931         location_gps_stop(self);
932
933         return FALSE;
934 }
935
936 static void
937 gps_single_location_cb(gboolean enabled, LocationPosition *pos, LocationVelocity *vel, LocationAccuracy *acc, gpointer self)
938 {
939         LOC_FUNC_LOG
940         g_return_if_fail(self);
941         g_return_if_fail(pos);
942         g_return_if_fail(vel);
943         g_return_if_fail(acc);
944
945         LocationGps *obj = (LocationGps *)self;
946         LocationGpsPrivate *priv = GET_PRIVATE(obj);
947         g_return_if_fail(priv);
948
949         g_signal_emit(self, signals[LOCATION_UPDATED], 0, LOCATION_ERROR_NONE, pos, vel, acc);
950         if (priv->loc_timeout) {
951                 g_source_remove(priv->loc_timeout);
952                 priv->loc_timeout = 0;
953         }
954         location_gps_stop(self);
955 }
956
957 static int
958 location_gps_request_single_location(LocationGps *self, int timeout)
959 {
960         LOC_FUNC_LOG
961         LocationGpsPrivate *priv = GET_PRIVATE(self);
962         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
963         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
964         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
965         g_return_val_if_fail(priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE);
966
967         if (__get_started(self) == TRUE) return LOCATION_ERROR_NONE;
968
969         int ret = LOCATION_ERROR_NONE;
970
971         __set_started(self, TRUE);
972         ret = priv->mod->ops.start(priv->mod->handler, priv->pos_interval, gps_status_cb, gps_single_location_cb, NULL, self);
973         if (ret != LOCATION_ERROR_NONE) {
974                 LOCATION_LOGE("Fail to start request single. Error[%d]", ret);
975                 __set_started(self, FALSE);
976                 return ret;
977         } else {
978                 if (priv->loc_timeout != 0)
979                         g_source_remove(priv->loc_timeout);
980
981                 priv->loc_timeout = g_timeout_add_seconds(timeout, __single_location_timeout_cb, self);
982         }
983
984         return ret;
985 }
986
987 static int location_gps_get_nmea(LocationGps *self, char **nmea_data)
988 {
989         int ret = LOCATION_ERROR_NOT_AVAILABLE;
990
991         LocationGpsPrivate *priv = GET_PRIVATE(self);
992         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
993         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
994         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
995         g_return_val_if_fail(priv->mod->ops.get_nmea, LOCATION_ERROR_NOT_AVAILABLE);
996         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
997
998         ret = priv->mod->ops.get_nmea(priv->mod->handler, nmea_data);
999         LOC_IF_FAIL_LOG(ret, _E, "Failed to get_nmea [%s]", err_msg(ret));
1000
1001         return ret;
1002 }
1003
1004 static int location_gps_get_batch(LocationGps *self, LocationBatch **batch)
1005 {
1006         int ret = LOCATION_ERROR_NOT_AVAILABLE;
1007
1008         LocationGpsPrivate *priv = GET_PRIVATE(self);
1009         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1010         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
1011         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
1012
1013 #ifndef TIZEN_DEVICE
1014         LOC_COND_RET(__get_started(self) != TRUE, LOCATION_ERROR_NOT_AVAILABLE, _E, "Location is not started [%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
1015 #endif
1016
1017         if (priv->batch) {
1018                 *batch = location_batch_copy(priv->batch);
1019                 ret = LOCATION_ERROR_NONE;
1020         } else {
1021                 LOCATION_LOGE("priv->batch is null");
1022                 ret = LOCATION_ERROR_NOT_AVAILABLE;
1023         }
1024
1025         return ret;
1026 }
1027
1028 static int location_gps_get_satellite(LocationGps *self, LocationSatellite **satellite)
1029 {
1030         int ret = LOCATION_ERROR_NOT_AVAILABLE;
1031
1032         LocationGpsPrivate *priv = GET_PRIVATE(self);
1033         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1034         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
1035
1036         LOC_COND_RET(__get_started(self) != TRUE, LOCATION_ERROR_NOT_AVAILABLE, _E, "Location is not started [%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
1037
1038         if (priv->sat) {
1039                 *satellite = location_satellite_copy(priv->sat);
1040                 ret = LOCATION_ERROR_NONE;
1041         }
1042
1043         return ret;
1044 }
1045
1046 static int location_gps_get_last_satellite(LocationGps *self, LocationSatellite **satellite)
1047 {
1048         return location_gps_get_satellite(self, satellite);
1049 }
1050
1051 static int location_gps_set_option(LocationGps *self, const char *option)
1052 {
1053         LocationGpsPrivate *priv = GET_PRIVATE(self);
1054         g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1055         g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
1056         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
1057         g_return_val_if_fail(priv->mod->ops.set_option, LOCATION_ERROR_NOT_AVAILABLE);
1058
1059         int ret = LOCATION_ERROR_NONE;
1060         ret = priv->mod->ops.set_option(priv->mod->handler, option);
1061         LOC_IF_FAIL_LOG(ret, _E, "Failed to set_option [%s]", err_msg(ret));
1062
1063         return ret;
1064 }
1065
1066 static int
1067 location_gps_set_mock_location(LocationGps *self, LocationPosition *position, LocationVelocity *velocity, LocationAccuracy *accuracy)
1068 {
1069         LOC_FUNC_LOG
1070         LocationGpsPrivate *priv = GET_PRIVATE(self);
1071         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
1072         g_return_val_if_fail(priv->mod->ops.set_mock_location, LOCATION_ERROR_NOT_AVAILABLE);
1073
1074         int ret = LOCATION_ERROR_NONE;
1075         if (!location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED)) {
1076                 ret = LOCATION_ERROR_SETTING_OFF;
1077         } else {
1078                 ret = priv->mod->ops.set_mock_location(priv->mod->handler, position, velocity, accuracy, NULL, self);
1079                 LOC_IF_FAIL_LOG(ret, _E, "Failed to set_mock_location [%s]", err_msg(ret));
1080                 priv->is_mock = TRUE;
1081         }
1082
1083         return ret;
1084 }
1085
1086 static int
1087 location_gps_clear_mock_location(LocationGps *self)
1088 {
1089         LOC_FUNC_LOG
1090         LocationGpsPrivate *priv = GET_PRIVATE(self);
1091         g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
1092         g_return_val_if_fail(priv->mod->ops.clear_mock_location, LOCATION_ERROR_NOT_AVAILABLE);
1093
1094         int ret = LOCATION_ERROR_NONE;
1095         if (!location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED)) {
1096                 ret = LOCATION_ERROR_SETTING_OFF;
1097         } else {
1098                 ret = priv->mod->ops.clear_mock_location(priv->mod->handler, NULL, self);
1099                 LOC_IF_FAIL_LOG(ret, _E, "Failed to clear_mock_location [%s]", err_msg(ret));
1100                 priv->is_mock = FALSE;
1101         }
1102
1103         return ret;
1104 }
1105
1106 static void location_ielement_interface_init(LocationIElementInterface *iface)
1107 {
1108         iface->start = (TYPE_START_FUNC)location_gps_start;
1109         iface->stop = (TYPE_STOP_FUNC)location_gps_stop;
1110         iface->get_position = (TYPE_GET_POSITION)location_gps_get_position;
1111         iface->get_position_ext = (TYPE_GET_POSITION_EXT)location_gps_get_position_ext;
1112         iface->get_last_position = (TYPE_GET_POSITION)location_gps_get_last_position;
1113         iface->get_last_position_ext = (TYPE_GET_POSITION_EXT)location_gps_get_last_position_ext;
1114         iface->get_velocity = (TYPE_GET_VELOCITY)location_gps_get_velocity;
1115         iface->get_last_velocity = (TYPE_GET_VELOCITY)location_gps_get_last_velocity;
1116         iface->get_satellite = (TYPE_GET_SATELLITE)location_gps_get_satellite;
1117         iface->get_last_satellite = (TYPE_GET_SATELLITE)location_gps_get_last_satellite;
1118         iface->set_option = (TYPE_SET_OPTION)location_gps_set_option;
1119         iface->get_batch = (TYPE_GET_BATCH)location_gps_get_batch;
1120         iface->start_batch = (TYPE_START_BATCH)location_gps_start_batch;
1121         iface->stop_batch = (TYPE_STOP_BATCH)location_gps_stop_batch;
1122         iface->request_single_location = (TYPE_REQUEST_SINGLE_LOCATION)location_gps_request_single_location;
1123         iface->get_nmea = (TYPE_GET_NMEA)location_gps_get_nmea;
1124         iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_gps_set_mock_location;
1125         iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_gps_clear_mock_location;
1126 }
1127
1128 static void location_gps_init(LocationGps *self)
1129 {
1130         LOC_FUNC_LOG
1131         LocationGpsPrivate *priv = GET_PRIVATE(self);
1132         g_return_if_fail(priv);
1133
1134         priv->mod = (LocationGpsMod *)module_new("gps");
1135         LOC_COND_LOG(!priv->mod, _E, "Module loading failed");
1136
1137         g_mutex_init(&priv->mutex);
1138         priv->is_started = FALSE;
1139         priv->is_batch_invoked = FALSE;
1140         priv->is_mock = FALSE;
1141         priv->set_noti = FALSE;
1142         priv->enabled = FALSE;
1143         priv->signal_type = 0;
1144
1145         priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
1146         priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
1147         priv->sat_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
1148         priv->loc_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
1149         priv->batch_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
1150         priv->batch_period = LOCATION_BATCH_PERIOD_DEFAULT;
1151         priv->min_interval = LOCATION_UPDATE_INTERVAL_NONE;
1152
1153         priv->pos_updated_timestamp = 0;
1154         priv->vel_updated_timestamp = 0;
1155         priv->sat_updated_timestamp = 0;
1156         priv->loc_updated_timestamp = 0;
1157
1158         priv->pos = NULL;
1159         priv->batch = NULL;
1160         priv->vel = NULL;
1161         priv->acc = NULL;
1162         priv->sat = NULL;
1163         priv->boundary_list = NULL;
1164         priv->loc_timeout = 0;
1165
1166 #if defined(TIZEN_DEVICE) && !defined(TIZEN_PROFILE_TV)
1167         priv->sensor = NULL;
1168         priv->sensor_listener = NULL;
1169 #endif
1170
1171         priv->app_type = location_get_app_type(NULL);
1172         LOC_COND_LOG(priv->app_type == 0, _W, "Fail to get app_type");
1173 }
1174
1175 static void location_gps_class_init(LocationGpsClass *klass)
1176 {
1177         LOC_FUNC_LOG
1178         GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
1179
1180         gobject_class->set_property = location_gps_set_property;
1181         gobject_class->get_property = location_gps_get_property;
1182
1183         gobject_class->dispose = location_gps_dispose;
1184         gobject_class->finalize = location_gps_finalize;
1185
1186         g_type_class_add_private(klass, sizeof(LocationGpsPrivate));
1187
1188         signals[SERVICE_ENABLED] =
1189                         g_signal_new("service-enabled", G_TYPE_FROM_CLASS(klass),
1190                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1191                         G_STRUCT_OFFSET(LocationGpsClass, enabled),
1192                         NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1193
1194         signals[SERVICE_DISABLED] =
1195                         g_signal_new("service-disabled", G_TYPE_FROM_CLASS(klass),
1196                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1197                         G_STRUCT_OFFSET(LocationGpsClass, disabled),
1198                         NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1199
1200 #if 0 /* TODO: STATUS_CHANGED will aggregate SERVICE_ENABLED and SERVICE_DISABLED */
1201         signals[STATUS_CHANGED] =
1202                         g_signal_new("status-changed", G_TYPE_FROM_CLASS(klass),
1203                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1204                         G_STRUCT_OFFSET(LocationGpsClass, status_changed),
1205                         NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1206 #endif
1207
1208         signals[SERVICE_UPDATED] =
1209                         g_signal_new("service-updated", G_TYPE_FROM_CLASS(klass),
1210                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1211                         G_STRUCT_OFFSET(LocationGpsClass, service_updated),
1212                         NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER,
1213                         G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1214
1215         signals[LOCATION_UPDATED] =
1216                         g_signal_new("location-updated", G_TYPE_FROM_CLASS(klass),
1217                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1218                         G_STRUCT_OFFSET(LocationGpsClass, location_updated),
1219                         NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER,
1220                         G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1221
1222         signals[BATCH_UPDATED] =
1223                         g_signal_new("batch-updated", G_TYPE_FROM_CLASS(klass),
1224                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1225                         G_STRUCT_OFFSET(LocationGpsClass, batch_updated),
1226                         NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1227
1228         signals[ZONE_IN] =
1229                         g_signal_new("zone-in", G_TYPE_FROM_CLASS(klass),
1230                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1231                         G_STRUCT_OFFSET(LocationGpsClass, zone_in),
1232                         NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
1233                         G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1234
1235         signals[ZONE_OUT] =
1236                         g_signal_new("zone-out", G_TYPE_FROM_CLASS(klass),
1237                         G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1238                         G_STRUCT_OFFSET(LocationGpsClass, zone_out),
1239                         NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
1240                         G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1241
1242         properties[PROP_METHOD_TYPE] =
1243                         g_param_spec_int("method", "method type", "location method type name",
1244                         LOCATION_METHOD_GPS, LOCATION_METHOD_GPS, LOCATION_METHOD_GPS, G_PARAM_READABLE);
1245
1246         properties[PROP_IS_STARTED] =
1247                         g_param_spec_boolean("is_started", "gps is started prop",
1248                         "gps is started status", FALSE, G_PARAM_READWRITE);
1249
1250         properties[PROP_LAST_POSITION] =
1251                         g_param_spec_boxed("last-position", "gps last position prop",
1252                         "gps last position data", LOCATION_TYPE_POSITION, G_PARAM_READABLE);
1253
1254         properties[PROP_POS_INTERVAL] =
1255                         g_param_spec_uint("pos-interval", "gps position interval prop",
1256                         "gps position interval data", LOCATION_UPDATE_INTERVAL_MIN,
1257                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1258
1259         properties[PROP_VEL_INTERVAL] =
1260                         g_param_spec_uint("vel-interval", "gps velocity interval prop",
1261                         "gps velocity interval data", LOCATION_UPDATE_INTERVAL_MIN,
1262                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1263
1264         properties[PROP_SAT_INTERVAL] =
1265                         g_param_spec_uint("sat-interval", "gps satellite interval prop",
1266                         "gps satellite interval data", LOCATION_UPDATE_INTERVAL_MIN,
1267                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1268
1269         properties[PROP_LOC_INTERVAL] =
1270                         g_param_spec_uint("loc-interval", "gps location interval prop",
1271                         "gps location interval data", LOCATION_UPDATE_INTERVAL_MIN,
1272                         LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1273
1274         properties[PROP_BATCH_INTERVAL] =
1275                         g_param_spec_uint("batch-interval", "gps batch interval interval prop",
1276                         "gps batch interval interval data", LOCATION_UPDATE_INTERVAL_MIN,
1277                         LOCATION_BATCH_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1278
1279         properties[PROP_BATCH_PERIOD] =
1280                         g_param_spec_uint("batch-period", "gps batch period prop",
1281                         "gps batch period data", LOCATION_BATCH_PERIOD_MIN,
1282                         LOCATION_BATCH_PERIOD_MAX, LOCATION_BATCH_PERIOD_DEFAULT, G_PARAM_READWRITE);
1283
1284         properties[PROP_MIN_INTERVAL] =
1285                         g_param_spec_uint("min-interval", "gps distance-based interval prop",
1286                         "gps distance-based interval data", LOCATION_MIN_INTERVAL_MIN,
1287                         LOCATION_MIN_INTERVAL_MAX, LOCATION_MIN_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1288
1289         properties[PROP_MIN_DISTANCE] =
1290                         g_param_spec_double("min-distance", "gps distance-based distance prop",
1291                         "gps distance-based distance data", LOCATION_MIN_DISTANCE_MIN,
1292                         LOCATION_MIN_DISTANCE_MAX, LOCATION_MIN_DISTANCE_DEFAULT, G_PARAM_READWRITE);
1293
1294         properties[PROP_BOUNDARY] =
1295                         g_param_spec_pointer("boundary", "gps boundary prop",
1296                         "gps boundary data", G_PARAM_READWRITE);
1297
1298         properties[PROP_REMOVAL_BOUNDARY] =
1299                         g_param_spec_boxed("removal-boundary", "gps removal boundary prop",
1300                         "gps removal boundary data", LOCATION_TYPE_BOUNDARY, G_PARAM_READWRITE);
1301
1302         properties[PROP_NMEA] =
1303                         g_param_spec_string("nmea", "gps NMEA name prop", "gps NMEA",
1304                         NULL, G_PARAM_READABLE);
1305
1306         properties[PROP_SATELLITE] =
1307                         g_param_spec_boxed("satellite", "gps satellite prop",
1308                         "gps satellite data", LOCATION_TYPE_SATELLITE, G_PARAM_READABLE);
1309
1310         properties[PROP_SERVICE_STATUS] =
1311                         g_param_spec_int("service-status", "location service status prop",
1312                         "location service status data", LOCATION_STATUS_NO_FIX,
1313                         LOCATION_STATUS_3D_FIX, LOCATION_STATUS_NO_FIX, G_PARAM_READABLE);
1314
1315         g_object_class_install_properties(gobject_class, PROP_MAX, properties);
1316 }