4 * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
7 * Genie Kim <daejins.kim@samsung.com>
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #include "location-setting.h"
27 #include "location-log.h"
29 #include "module-internal.h"
31 #include "location-hybrid.h"
32 #include "location-marshal.h"
33 #include "location-ielement.h"
34 #include "location-signaling-util.h"
35 #include "location-common-util.h"
37 #include "location-gps.h"
38 #include "location-wps.h"
40 typedef struct _LocationHybridPrivate {
44 guint pos_updated_timestamp;
45 guint vel_updated_timestamp;
46 guint sat_updated_timestamp;
47 guint dist_updated_timestamp;
48 guint loc_updated_timestamp;
58 LocationMethod current_method;
59 LocationPosition *pos;
60 LocationVelocity *vel;
61 LocationAccuracy *acc;
62 LocationSatellite *sat;
67 } LocationHybridPrivate;
78 PROP_REMOVAL_BOUNDARY,
85 static guint32 signals[LAST_SIGNAL] = {0, };
86 static GParamSpec *properties[PROP_MAX] = {NULL, };
88 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), LOCATION_TYPE_HYBRID, LocationHybridPrivate))
90 static void location_ielement_interface_init(LocationIElementInterface *iface);
92 G_DEFINE_TYPE_WITH_CODE(LocationHybrid, location_hybrid, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(LOCATION_TYPE_IELEMENT, location_ielement_interface_init));
95 hybrid_get_current_method(LocationHybridPrivate *priv)
97 g_return_val_if_fail(priv, LOCATION_METHOD_NONE);
98 LOCATION_LOGD("Current Method [%d]", priv->current_method);
99 return priv->current_method;
103 hybrid_set_current_method(LocationHybridPrivate *priv, GType g_type)
105 g_return_val_if_fail(priv, FALSE);
107 if (g_type == LOCATION_TYPE_GPS)
108 priv->current_method = LOCATION_METHOD_GPS;
109 else if (g_type == LOCATION_TYPE_WPS)
110 priv->current_method = LOCATION_METHOD_WPS;
111 else if (g_type == LOCATION_TYPE_HYBRID)
112 priv->current_method = LOCATION_METHOD_HYBRID;
120 hybrid_get_update_method(LocationHybridPrivate *priv)
122 if (!priv->gps && !priv->wps)
125 if (priv->gps_enabled)
126 hybrid_set_current_method(priv, LOCATION_TYPE_GPS);
127 else if (priv->wps_enabled)
128 hybrid_set_current_method(priv, LOCATION_TYPE_WPS);
130 hybrid_set_current_method(priv, LOCATION_TYPE_HYBRID);
135 static gboolean /* True : Receive more accurate info. False : Receive less accurate info */
136 hybrid_compare_g_type_method(LocationHybridPrivate *priv, GType g_type)
138 if (g_type == LOCATION_TYPE_GPS) {
139 hybrid_set_current_method(priv, LOCATION_TYPE_GPS);
141 } else if (g_type == LOCATION_TYPE_WPS && hybrid_get_current_method(priv) == LOCATION_METHOD_WPS) {
142 hybrid_set_current_method(priv, LOCATION_TYPE_WPS);
149 _location_timeout_cb(gpointer data)
151 GObject *object = (GObject *)data;
152 if (!object) return FALSE;
153 LocationHybridPrivate *priv = GET_PRIVATE(object);
154 g_return_val_if_fail(priv, FALSE);
156 LocationPosition *pos = NULL;
157 LocationVelocity *vel = NULL;
158 LocationAccuracy *acc = NULL;
161 pos = location_position_copy(priv->pos);
163 pos = location_position_new(0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
166 vel = location_velocity_copy(priv->vel);
168 vel = location_velocity_new(0, 0.0, 0.0, 0.0);
171 acc = location_accuracy_copy(priv->acc);
173 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
175 g_signal_emit(object, signals[SERVICE_UPDATED], 0, priv->signal_type, pos, vel, acc);
176 priv->signal_type = 0;
178 if (pos) location_position_free(pos);
179 if (vel) location_velocity_free(vel);
180 if (acc) location_accuracy_free(acc);
186 _position_timeout_cb(gpointer data)
188 GObject *object = (GObject *)data;
189 if (!object) return FALSE;
190 LocationHybridPrivate *priv = GET_PRIVATE(object);
191 g_return_val_if_fail(priv, FALSE);
193 if (priv->pos_interval == priv->vel_interval) {
194 priv->signal_type |= POSITION_UPDATED;
195 priv->signal_type |= VELOCITY_UPDATED;
197 priv->signal_type |= POSITION_UPDATED;
199 _location_timeout_cb(object);
205 _velocity_timeout_cb(gpointer data)
207 GObject *object = (GObject *)data;
208 LocationHybridPrivate *priv = GET_PRIVATE(object);
209 g_return_val_if_fail(priv, FALSE);
211 if (priv->pos_interval != priv->vel_interval) {
212 priv->signal_type |= VELOCITY_UPDATED;
213 _location_timeout_cb(object);
220 location_hybrid_gps_cb(keynode_t *key, gpointer self)
223 g_return_if_fail(key);
224 g_return_if_fail(self);
225 LocationHybridPrivate *priv = GET_PRIVATE(self);
226 g_return_if_fail(priv);
227 g_return_if_fail(priv->wps);
229 gboolean wps_started = FALSE;
230 int ret = LOCATION_ERROR_NONE;
233 onoff = location_setting_get_key_val(key);
235 /* restart WPS when GPS stopped by setting */
236 g_object_get(priv->wps, "is_started", &wps_started, NULL);
237 if (wps_started == FALSE && 1 == location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED)) {
238 LOCATION_LOGD("GPS stoped by setting, so restart WPS");
239 ret = location_start(priv->wps);
240 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Fail hybrid/wps location_start : [%s]", err_msg(ret));
242 } else if (1 == onoff) {
243 LOCATION_LOGD("Hybrid GPS resumed by setting");
246 LOCATION_LOGD("Invalid Value[%d]", onoff);
252 hybrid_location_updated(GObject *obj, guint error, gpointer position, gpointer velocity, gpointer accuracy, gpointer self)
255 LocationPosition *pos = (LocationPosition *)position;
256 LocationVelocity *vel = (LocationVelocity *)velocity;
257 LocationAccuracy *acc = (LocationAccuracy *)accuracy;
259 LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
260 g_return_if_fail(priv);
262 g_signal_emit(self, signals[LOCATION_UPDATED], 0, error, pos, vel, acc);
266 hybrid_service_updated(GObject *obj, gint type, gpointer data, gpointer velocity, gpointer accuracy, gpointer self)
269 LocationPosition *pos = NULL;
270 LocationVelocity *vel = NULL;
271 LocationAccuracy *acc = NULL;
272 LocationSatellite *sat = NULL;
273 gboolean wps_started = FALSE;
274 int ret = LOCATION_ERROR_NONE;
276 if (type == SATELLITE_UPDATED) {
277 sat = (LocationSatellite *) data;
278 if (!sat->timestamp) return;
280 pos = (LocationPosition *) data;
281 vel = (LocationVelocity *) velocity;
282 acc = (LocationAccuracy *) accuracy;
283 if (!pos->timestamp) return;
284 if (!vel->timestamp) return;
287 LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
288 g_return_if_fail(priv);
290 GType g_type = G_TYPE_FROM_INSTANCE(obj);
291 if (g_type == LOCATION_TYPE_GPS) {
292 if (type == SATELLITE_UPDATED) {
293 satellite_signaling(self, signals, &(priv->enabled), priv->sat_interval, TRUE, &(priv->sat_updated_timestamp), &(priv->sat), sat);
295 } else if (location_setting_get_int(VCONFKEY_LOCATION_GPS_STATE) == VCONFKEY_LOCATION_GPS_SEARCHING
296 && location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED) == 0) {
297 LOCATION_LOGD("Searching GPS");
299 /* restart WPS when GPS not available */
300 if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
301 if (priv->wps && wps_started == FALSE) {
302 LOCATION_LOGD("Starting WPS");
303 ret = location_start(priv->wps);
304 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Fail hyhrid location_start : [%s]", err_msg(ret));
310 if (hybrid_compare_g_type_method(priv, g_type)) {
311 if (priv->pos) location_position_free(priv->pos);
312 if (priv->vel) location_velocity_free(priv->vel);
313 if (priv->acc) location_accuracy_free(priv->acc);
315 if (pos) priv->pos = location_position_copy(pos);
316 if (vel) priv->vel = location_velocity_copy(vel);
317 if (acc) priv->acc = location_accuracy_copy(acc);
321 enable_signaling(self, signals, &(priv->enabled), TRUE, pos->status);
323 if (type == DISTANCE_UPDATED) {
324 distance_based_position_signaling(self, signals, priv->enabled, pos, vel, acc,
325 priv->min_interval, priv->min_distance, &(priv->enabled),
326 &(priv->dist_updated_timestamp), &(priv->pos), &(priv->vel), &(priv->acc));
328 position_velocity_signaling(self, signals, priv->pos_interval, priv->vel_interval, priv->loc_interval,
329 &(priv->pos_updated_timestamp), &(priv->vel_updated_timestamp), &(priv->loc_updated_timestamp),
330 priv->boundary_list, pos, vel, acc);
334 /* if receive GPS position then stop WPS.. */
335 if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
336 if (g_type == LOCATION_TYPE_GPS && wps_started == TRUE) {
337 LOCATION_LOGD("Calling WPS stop");
338 ret = location_stop(priv->wps);
339 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Fail hyhrid location_stop : [%s]", err_msg(ret));
342 } else if (g_type == LOCATION_TYPE_WPS && location_setting_get_int(VCONFKEY_LOCATION_GPS_STATE) == VCONFKEY_LOCATION_GPS_SEARCHING) {
343 LOCATION_LOGD("g_type is LOCATION_TYPE_WPS and GPS is searching");
344 hybrid_set_current_method(priv, g_type);
346 if (priv->pos) location_position_free(priv->pos);
347 if (priv->vel) location_velocity_free(priv->vel);
348 if (priv->acc) location_accuracy_free(priv->acc);
350 if (pos) priv->pos = location_position_copy(pos);
351 if (vel) priv->vel = location_velocity_copy(vel);
352 if (acc) priv->acc = location_accuracy_copy(acc);
356 enable_signaling(self, signals, &(priv->enabled), TRUE, pos->status);
358 if (type == DISTANCE_UPDATED) {
359 distance_based_position_signaling(self, signals, priv->enabled, pos, vel, acc,
360 priv->min_interval, priv->min_distance, &(priv->enabled),
361 &(priv->dist_updated_timestamp), &(priv->pos), &(priv->vel), &(priv->acc));
363 LOCATION_LOGD("position_velocity_signaling");
364 position_velocity_signaling(self, signals, priv->pos_interval, priv->vel_interval, priv->loc_interval,
365 &(priv->pos_updated_timestamp), &(priv->vel_updated_timestamp), &(priv->loc_updated_timestamp),
366 priv->boundary_list, pos, vel, acc);
373 hybrid_service_enabled(GObject *obj, guint status, gpointer self)
376 LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
377 g_return_if_fail(priv);
379 GType g_type = G_TYPE_FROM_INSTANCE(obj);
380 if (g_type == LOCATION_TYPE_GPS) {
381 priv->gps_enabled = TRUE;
382 } else if (g_type == LOCATION_TYPE_WPS) {
383 priv->wps_enabled = TRUE;
385 LOCATION_LOGW("Undefined GType enabled");
388 hybrid_get_update_method(priv);
392 hybrid_service_disabled(GObject *obj, guint status, gpointer self)
395 LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
396 g_return_if_fail(priv);
397 GType g_type = G_TYPE_FROM_INSTANCE(obj);
398 if (g_type == LOCATION_TYPE_GPS) {
399 priv->gps_enabled = FALSE;
400 } else if (g_type == LOCATION_TYPE_WPS) {
401 priv->wps_enabled = FALSE;
403 LOCATION_LOGW("Undefined GType disabled");
406 hybrid_get_update_method(priv);
407 if (!priv->gps_enabled && !priv->wps_enabled)
408 enable_signaling(self, signals, &(priv->enabled), FALSE, status);
413 location_hybrid_start(LocationHybrid *self)
417 int ret_gps = LOCATION_ERROR_NONE;
418 int ret_wps = LOCATION_ERROR_NONE;
419 gboolean gps_started = FALSE;
420 gboolean wps_started = FALSE;
422 LocationHybridPrivate *priv = GET_PRIVATE(self);
423 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
424 LOC_COND_RET(!priv->gps && !priv->wps, LOCATION_ERROR_NOT_AVAILABLE, _E, "GPS and WPS Object are not created.");
426 if (priv->gps) g_object_get(priv->gps, "is_started", &gps_started, NULL);
427 if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
429 if ((gps_started == TRUE) || (wps_started == TRUE)) {
430 LOCATION_LOGD("Already started");
431 return LOCATION_ERROR_NONE;
434 if (priv->gps) ret_gps = location_start(priv->gps);
435 if (priv->wps) ret_wps = location_start(priv->wps);
437 if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE) {
438 LOCATION_LOGD("ret_gps = %d, ret_wps = %d", ret_gps, ret_wps);
439 if (ret_gps == LOCATION_ERROR_SECURITY_DENIED || ret_wps == LOCATION_ERROR_SECURITY_DENIED)
440 return LOCATION_ERROR_SECURITY_DENIED;
441 else if (ret_gps == LOCATION_ERROR_SETTING_OFF || ret_wps == LOCATION_ERROR_SETTING_OFF)
442 return LOCATION_ERROR_SETTING_OFF;
443 else if (ret_gps == LOCATION_ERROR_NOT_ALLOWED || ret_wps == LOCATION_ERROR_NOT_ALLOWED)
444 return LOCATION_ERROR_NOT_ALLOWED;
446 return LOCATION_ERROR_NOT_AVAILABLE;
449 if (priv->set_noti == FALSE) {
450 location_setting_add_notify(VCONFKEY_LOCATION_ENABLED, location_hybrid_gps_cb, self);
451 priv->set_noti = TRUE;
454 return LOCATION_ERROR_NONE;
458 location_hybrid_stop(LocationHybrid *self)
462 LocationHybridPrivate *priv = GET_PRIVATE(self);
463 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
465 LOCATION_LOGD("location_hybrid_stop started......!!!");
467 int ret_gps = LOCATION_ERROR_NOT_AVAILABLE;
468 int ret_wps = LOCATION_ERROR_NOT_AVAILABLE;
469 gboolean gps_started = FALSE;
470 gboolean wps_started = FALSE;
472 if (priv->gps) g_object_get(priv->gps, "is_started", &gps_started, NULL);
473 if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
475 if ((gps_started == FALSE) && (wps_started == FALSE))
476 return LOCATION_ERROR_NONE;
478 if (priv->gps) ret_gps = location_stop(priv->gps);
479 if (priv->wps) ret_wps = location_stop(priv->wps);
481 if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE)
482 return LOCATION_ERROR_NOT_AVAILABLE;
484 if (priv->pos_timer) g_source_remove(priv->pos_timer);
485 if (priv->vel_timer) g_source_remove(priv->vel_timer);
489 if (priv->set_noti == TRUE) {
490 location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_hybrid_gps_cb);
491 priv->set_noti = FALSE;
494 priv->gps_enabled = FALSE;
495 priv->wps_enabled = FALSE;
497 return LOCATION_ERROR_NONE;
501 location_hybrid_dispose(GObject *gobject)
504 LocationHybridPrivate *priv = GET_PRIVATE(gobject);
505 g_return_if_fail(priv);
507 if (priv->pos_timer) g_source_remove(priv->pos_timer);
508 if (priv->vel_timer) g_source_remove(priv->vel_timer);
512 if (priv->set_noti == TRUE) {
513 location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_hybrid_gps_cb);
514 priv->set_noti = FALSE;
517 G_OBJECT_CLASS(location_hybrid_parent_class)->dispose(gobject);
521 location_hybrid_finalize(GObject *gobject)
524 LocationHybridPrivate *priv = GET_PRIVATE(gobject);
525 g_return_if_fail(priv);
528 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_enabled), gobject);
529 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_disabled), gobject);
530 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_updated), gobject);
531 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_location_updated), gobject);
532 location_free(priv->gps, TRUE);
535 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_enabled), gobject);
536 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_disabled), gobject);
537 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_updated), gobject);
538 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_location_updated), gobject);
539 location_free(priv->wps, TRUE);
542 if (priv->boundary_list) {
543 g_list_free_full(priv->boundary_list, free_boundary_list);
544 priv->boundary_list = NULL;
548 location_position_free(priv->pos);
553 location_velocity_free(priv->vel);
558 location_accuracy_free(priv->acc);
563 location_satellite_free(priv->sat);
567 G_OBJECT_CLASS(location_hybrid_parent_class)->finalize(gobject);
571 location_hybrid_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
573 LocationHybridPrivate *priv = GET_PRIVATE(object);
574 g_return_if_fail(priv);
575 if (!priv->gps && !priv->wps) {
576 LOCATION_LOGW("Set property is not available now");
581 switch (property_id) {
582 case PROP_BOUNDARY: {
583 GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
584 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
585 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Set boundary. Error[%s]", err_msg(ret));
588 case PROP_REMOVAL_BOUNDARY: {
589 LocationBoundary *req_boundary = (LocationBoundary *) g_value_dup_boxed(value);
590 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
591 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Removal boundary. Error[%s]", err_msg(ret));
594 case PROP_POS_INTERVAL: {
595 guint interval = g_value_get_uint(value);
596 LOCATION_LOGD("Set prop>> PROP_POS_INTERVAL: %u", interval);
598 if (interval < LOCATION_UPDATE_INTERVAL_MAX)
599 priv->pos_interval = interval;
601 priv->pos_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
603 priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
606 if (priv->pos_timer) {
607 g_source_remove(priv->pos_timer);
608 priv->pos_timer = g_timeout_add(priv->pos_interval * 1000, _position_timeout_cb, object);
611 if (priv->gps) g_object_set(priv->gps, "pos-interval", priv->pos_interval, NULL);
612 if (priv->wps) g_object_set(priv->wps, "pos-interval", priv->pos_interval, NULL);
616 case PROP_VEL_INTERVAL: {
617 guint interval = g_value_get_uint(value);
618 LOCATION_LOGD("Set prop>> PROP_VEL_INTERVAL: %u", interval);
620 if (interval < LOCATION_UPDATE_INTERVAL_MAX)
621 priv->vel_interval = interval;
623 priv->vel_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
626 priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
628 if (priv->vel_timer) {
629 g_source_remove(priv->vel_timer);
630 priv->vel_timer = g_timeout_add(priv->vel_interval * 1000, _velocity_timeout_cb, object);
633 if (priv->gps) g_object_set(priv->gps, "vel-interval", priv->vel_interval, NULL);
634 if (priv->wps) g_object_set(priv->wps, "vel-interval", priv->vel_interval, NULL);
638 case PROP_SAT_INTERVAL: {
639 guint interval = g_value_get_uint(value);
640 LOCATION_LOGD("Set prop>> PROP_SAT_INTERVAL: %u", interval);
642 if (interval < LOCATION_UPDATE_INTERVAL_MAX)
643 priv->sat_interval = interval;
645 priv->sat_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
648 priv->sat_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
652 case PROP_LOC_INTERVAL: {
653 guint interval = g_value_get_uint(value);
654 LOCATION_LOGD("Set prop>> PROP_LOC_INTERVAL: %u", interval);
656 if (interval < LOCATION_UPDATE_INTERVAL_MAX)
657 priv->loc_interval = interval;
659 priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
661 priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
663 if (priv->gps) g_object_set(priv->gps, "loc-interval", priv->loc_interval, NULL);
664 if (priv->wps) g_object_set(priv->wps, "loc-interval", priv->loc_interval, NULL);
668 case PROP_MIN_INTERVAL: {
669 guint interval = g_value_get_uint(value);
670 LOCATION_LOGD("Set prop>> PROP_MIN_INTERVAL: %u", interval);
672 if (interval < LOCATION_MIN_INTERVAL_MAX)
673 priv->min_interval = interval;
675 priv->min_interval = (guint)LOCATION_MIN_INTERVAL_MAX;
677 priv->min_interval = (guint)LOCATION_MIN_INTERVAL_DEFAULT;
679 if (priv->gps) g_object_set(priv->gps, "min-interval", priv->min_interval, NULL);
680 if (priv->wps) g_object_set(priv->wps, "min-interval", priv->min_interval, NULL);
684 case PROP_MIN_DISTANCE: {
685 gdouble distance = g_value_get_double(value);
686 LOCATION_LOGD("Set prop>> PROP_MIN_DISTANCE: %u", distance);
688 if (distance < LOCATION_MIN_DISTANCE_MAX)
689 priv->min_distance = distance;
691 priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_MAX;
693 priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_DEFAULT;
695 if (priv->gps) g_object_set(priv->gps, "min-distance", priv->min_distance, NULL);
696 if (priv->wps) g_object_set(priv->wps, "min-distance", priv->min_distance, NULL);
701 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
707 location_hybrid_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
709 LocationHybridPrivate *priv = GET_PRIVATE(object);
710 g_return_if_fail(priv);
712 LOC_COND_VOID(!priv->gps && !priv->wps, _E, "Error : Get property is not available now");
714 LOCATION_LOGW("Get Propery ID[%d]", property_id);
716 switch (property_id) {
717 case PROP_METHOD_TYPE:
718 g_value_set_int(value, hybrid_get_current_method(priv));
720 case PROP_LAST_POSITION:
721 g_value_set_boxed(value, priv->pos);
724 g_value_set_pointer(value, g_list_first(priv->boundary_list));
726 case PROP_POS_INTERVAL:
727 g_value_set_uint(value, priv->pos_interval);
729 case PROP_VEL_INTERVAL:
730 g_value_set_uint(value, priv->vel_interval);
732 case PROP_SAT_INTERVAL:
733 g_value_set_uint(value, priv->sat_interval);
735 case PROP_LOC_INTERVAL:
736 g_value_set_uint(value, priv->loc_interval);
738 case PROP_MIN_INTERVAL:
739 g_value_set_uint(value, priv->min_interval);
741 case PROP_MIN_DISTANCE:
742 g_value_set_double(value, priv->min_distance);
744 case PROP_SERVICE_STATUS:
745 g_value_set_int(value, priv->enabled);
748 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
754 location_hybrid_get_position(LocationHybrid *self, LocationPosition **position, LocationAccuracy **accuracy)
757 int ret = LOCATION_ERROR_NOT_AVAILABLE;
758 if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
759 return LOCATION_ERROR_SETTING_OFF;
761 LocationHybridPrivate *priv = GET_PRIVATE(self);
762 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
763 LOCATION_IF_HYBRID_FAIL(VCONFKEY_LOCATION_GPS_STATE, VCONFKEY_LOCATION_WPS_STATE);
766 *position = location_position_copy(priv->pos);
767 ret = LOCATION_ERROR_NONE;
771 *accuracy = location_accuracy_copy(priv->acc);
777 location_hybrid_get_position_ext(LocationHybrid *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
780 if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
781 return LOCATION_ERROR_SETTING_OFF;
783 LocationHybridPrivate *priv = GET_PRIVATE(self);
784 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
785 LOCATION_IF_HYBRID_FAIL(VCONFKEY_LOCATION_GPS_STATE, VCONFKEY_LOCATION_WPS_STATE);
787 if (priv->pos && priv->vel) {
788 *position = location_position_copy(priv->pos);
789 *velocity = location_velocity_copy(priv->vel);
791 LOCATION_LOGE("There is invalid data.");
792 return LOCATION_ERROR_NOT_AVAILABLE;
796 *accuracy = location_accuracy_copy(priv->acc);
798 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
800 return LOCATION_ERROR_NONE;
805 location_hybrid_get_last_position(LocationHybrid *self, LocationPosition **position, LocationAccuracy **accuracy)
809 int ret = LOCATION_ERROR_NONE;
810 LocationPosition *gps_pos = NULL, *wps_pos = NULL;
811 LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
812 LocationHybridPrivate *priv = GET_PRIVATE(self);
813 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
815 if (priv->gps) location_get_last_position(priv->gps, &gps_pos, &gps_acc);
816 if (priv->wps) location_get_last_position(priv->wps, &wps_pos, &wps_acc);
818 if (gps_pos && wps_pos) {
819 if (wps_pos->timestamp > gps_pos->timestamp) {
822 location_position_free(gps_pos);
823 location_accuracy_free(gps_acc);
827 location_position_free(wps_pos);
828 location_accuracy_free(wps_acc);
830 } else if (gps_pos) {
833 } else if (wps_pos) {
837 ret = LOCATION_ERROR_NOT_AVAILABLE;
844 location_hybrid_get_last_position_ext(LocationHybrid *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
848 int ret = LOCATION_ERROR_NONE;
849 LocationPosition *gps_pos = NULL, *wps_pos = NULL;
850 LocationVelocity *gps_vel = NULL, *wps_vel = NULL;
851 LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
852 LocationHybridPrivate *priv = GET_PRIVATE(self);
853 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
855 if (priv->gps) location_get_last_position_ext(priv->gps, &gps_pos, &gps_vel, &gps_acc);
856 if (priv->wps) location_get_last_position_ext(priv->wps, &wps_pos, &wps_vel, &wps_acc);
858 if (gps_pos && wps_pos && gps_vel && wps_vel) {
859 if (wps_pos->timestamp > gps_pos->timestamp) {
863 location_position_free(gps_pos);
864 location_velocity_free(gps_vel);
865 location_accuracy_free(gps_acc);
870 location_position_free(wps_pos);
871 location_velocity_free(wps_vel);
872 location_accuracy_free(wps_acc);
874 } else if (gps_pos && gps_vel) {
878 } else if (wps_pos && wps_vel) {
883 ret = LOCATION_ERROR_NOT_AVAILABLE;
890 location_hybrid_get_velocity(LocationHybrid *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
893 int ret = LOCATION_ERROR_NOT_AVAILABLE;
894 if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
895 return LOCATION_ERROR_SETTING_OFF;
897 LocationHybridPrivate *priv = GET_PRIVATE(self);
898 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
899 LOCATION_IF_HYBRID_FAIL(VCONFKEY_LOCATION_GPS_STATE, VCONFKEY_LOCATION_WPS_STATE);
902 *velocity = location_velocity_copy(priv->vel);
903 ret = LOCATION_ERROR_NONE;
907 *accuracy = location_accuracy_copy(priv->acc);
913 location_hybrid_get_last_velocity(LocationHybrid *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
917 int ret = LOCATION_ERROR_NONE;
918 LocationHybridPrivate *priv = GET_PRIVATE(self);
919 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
920 LocationVelocity *gps_vel = NULL, *wps_vel = NULL;
921 LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
923 if (priv->gps) location_get_last_velocity(priv->gps, &gps_vel, &gps_acc);
924 if (priv->wps) location_get_last_velocity(priv->wps, &wps_vel, &wps_acc);
926 if (gps_vel && wps_vel) {
927 if (wps_vel->timestamp > gps_vel->timestamp) {
930 location_velocity_free(gps_vel);
931 location_accuracy_free(gps_acc);
935 location_velocity_free(wps_vel);
936 location_accuracy_free(wps_acc);
938 } else if (gps_vel) {
941 } else if (wps_vel) {
947 ret = LOCATION_ERROR_NOT_AVAILABLE;
954 location_hybrid_get_satellite(LocationHybrid *self, LocationSatellite **satellite)
957 int ret = LOCATION_ERROR_NOT_AVAILABLE;
958 if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
959 return LOCATION_ERROR_SETTING_OFF;
961 LocationHybridPrivate *priv = GET_PRIVATE(self);
962 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
964 *satellite = location_satellite_copy(priv->sat);
965 ret = LOCATION_ERROR_NONE;
972 location_hybrid_get_last_satellite(LocationHybrid *self, LocationSatellite **satellite)
976 int ret = LOCATION_ERROR_NONE;
977 LocationHybridPrivate *priv = GET_PRIVATE(self);
978 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
981 ret = location_get_last_satellite(priv->gps, satellite);
984 ret = LOCATION_ERROR_NOT_AVAILABLE;
991 location_hybrid_set_option(LocationHybrid *self, const char *option)
994 LocationHybridPrivate *priv = GET_PRIVATE(self);
995 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
997 int ret_gps = LOCATION_ERROR_NOT_AVAILABLE;
998 int ret_wps = LOCATION_ERROR_NOT_AVAILABLE;
1000 if (priv->gps) ret_gps = location_set_option(priv->gps, option);
1001 if (priv->wps) ret_wps = location_set_option(priv->wps, option);
1003 if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE)
1004 return LOCATION_ERROR_NOT_AVAILABLE;
1006 return LOCATION_ERROR_NONE;
1010 location_hybrid_request_single_location(LocationHybrid *self, int timeout)
1013 LocationHybridPrivate *priv = GET_PRIVATE(self);
1014 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1016 int ret = LOCATION_ERROR_NOT_AVAILABLE;
1019 ret = location_request_single_location(priv->gps, timeout);
1021 ret = location_request_single_location(priv->wps, timeout);
1027 location_hybrid_get_nmea(LocationHybrid *self, char **nmea_data)
1030 LocationHybridPrivate *priv = GET_PRIVATE(self);
1031 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1033 int ret = LOCATION_ERROR_NOT_AVAILABLE;
1035 if (priv->gps) ret = location_get_nmea(priv->gps, nmea_data);
1037 if (ret != LOCATION_ERROR_NONE)
1038 return LOCATION_ERROR_NOT_AVAILABLE;
1040 return LOCATION_ERROR_NONE;
1044 location_hybrid_set_mock_location(LocationHybrid *self, LocationPosition *position, LocationVelocity *velocity, LocationAccuracy *accuracy)
1047 LocationHybridPrivate *priv = GET_PRIVATE(self);
1048 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1049 int ret = LOCATION_ERROR_NONE;
1052 ret = location_set_mock_location(priv->gps, position, velocity, accuracy);
1054 ret = location_set_mock_location(priv->wps, position, velocity, accuracy);
1056 ret = LOCATION_ERROR_NOT_AVAILABLE;
1062 location_hybrid_clear_mock_location(LocationHybrid *self)
1065 LocationHybridPrivate *priv = GET_PRIVATE(self);
1066 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1067 int ret = LOCATION_ERROR_NONE;
1070 ret = location_clear_mock_location(priv->gps);
1072 ret = location_clear_mock_location(priv->wps);
1074 ret = LOCATION_ERROR_NOT_AVAILABLE;
1080 location_ielement_interface_init(LocationIElementInterface *iface)
1082 iface->start = (TYPE_START_FUNC)location_hybrid_start;
1083 iface->stop = (TYPE_STOP_FUNC)location_hybrid_stop;
1084 iface->get_position = (TYPE_GET_POSITION)location_hybrid_get_position;
1085 iface->get_position_ext = (TYPE_GET_POSITION_EXT)location_hybrid_get_position_ext;
1086 iface->get_last_position = (TYPE_GET_POSITION)location_hybrid_get_last_position;
1087 iface->get_last_position_ext = (TYPE_GET_POSITION_EXT)location_hybrid_get_last_position_ext;
1088 iface->get_velocity = (TYPE_GET_VELOCITY)location_hybrid_get_velocity;
1089 iface->get_last_velocity = (TYPE_GET_VELOCITY)location_hybrid_get_last_velocity;
1090 iface->get_satellite = (TYPE_GET_SATELLITE)location_hybrid_get_satellite;
1091 iface->get_last_satellite = (TYPE_GET_SATELLITE)location_hybrid_get_last_satellite;
1092 iface->set_option = (TYPE_SET_OPTION)location_hybrid_set_option;
1093 iface->request_single_location = (TYPE_REQUEST_SINGLE_LOCATION)location_hybrid_request_single_location;
1094 iface->get_nmea = (TYPE_GET_NMEA)location_hybrid_get_nmea;
1096 iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_hybrid_set_mock_location;
1097 iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_hybrid_clear_mock_location;
1101 location_hybrid_init(LocationHybrid *self)
1104 LocationHybridPrivate *priv = GET_PRIVATE(self);
1105 g_return_if_fail(priv);
1107 priv->pos_interval = LOCATION_UPDATE_INTERVAL_NONE;
1108 priv->vel_interval = LOCATION_UPDATE_INTERVAL_NONE;
1109 priv->sat_interval = LOCATION_UPDATE_INTERVAL_NONE;
1110 priv->loc_interval = LOCATION_UPDATE_INTERVAL_NONE;
1111 priv->min_interval = LOCATION_UPDATE_INTERVAL_NONE;
1113 priv->pos_updated_timestamp = 0;
1114 priv->vel_updated_timestamp = 0;
1115 priv->sat_updated_timestamp = 0;
1116 priv->loc_updated_timestamp = 0;
1118 priv->gps_enabled = FALSE;
1119 priv->wps_enabled = FALSE;
1123 priv->set_noti = FALSE;
1124 priv->signal_type = 0;
1125 priv->pos_timer = 0;
1126 priv->vel_timer = 0;
1128 if (location_is_supported_method(LOCATION_METHOD_GPS)) priv->gps = location_new(LOCATION_METHOD_GPS, TRUE);
1129 if (location_is_supported_method(LOCATION_METHOD_WPS)) priv->wps = location_new(LOCATION_METHOD_WPS, TRUE);
1132 g_signal_connect(priv->gps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self);
1133 g_signal_connect(priv->gps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self);
1134 g_signal_connect(priv->gps, "service-updated", G_CALLBACK(hybrid_service_updated), self);
1135 g_signal_connect(priv->gps, "location-updated", G_CALLBACK(hybrid_location_updated), self);
1138 g_signal_connect(priv->wps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self);
1139 g_signal_connect(priv->wps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self);
1140 g_signal_connect(priv->wps, "service-updated", G_CALLBACK(hybrid_service_updated), self);
1141 g_signal_connect(priv->wps, "location-updated", G_CALLBACK(hybrid_location_updated), self);
1144 hybrid_set_current_method(priv, LOCATION_TYPE_HYBRID);
1145 priv->enabled = FALSE;
1152 priv->boundary_list = NULL;
1156 location_hybrid_class_init(LocationHybridClass *klass)
1159 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
1161 gobject_class->set_property = location_hybrid_set_property;
1162 gobject_class->get_property = location_hybrid_get_property;
1164 gobject_class->dispose = location_hybrid_dispose;
1165 gobject_class->finalize = location_hybrid_finalize;
1167 g_type_class_add_private(klass, sizeof(LocationHybridPrivate));
1169 signals[SERVICE_ENABLED] =
1170 g_signal_new("service-enabled", G_TYPE_FROM_CLASS(klass),
1171 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1172 G_STRUCT_OFFSET(LocationHybridClass, enabled),
1173 NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1175 signals[SERVICE_DISABLED] =
1176 g_signal_new("service-disabled", G_TYPE_FROM_CLASS(klass),
1177 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1178 G_STRUCT_OFFSET(LocationHybridClass, disabled),
1179 NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1181 signals[SERVICE_UPDATED] =
1182 g_signal_new("service-updated", G_TYPE_FROM_CLASS(klass),
1183 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1184 G_STRUCT_OFFSET(LocationHybridClass, service_updated),
1185 NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER,
1186 G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1188 signals[LOCATION_UPDATED] =
1189 g_signal_new("location-updated", G_TYPE_FROM_CLASS(klass),
1190 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1191 G_STRUCT_OFFSET(LocationHybridClass, location_updated),
1192 NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER,
1193 G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1196 g_signal_new("zone-in", G_TYPE_FROM_CLASS(klass),
1197 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1198 G_STRUCT_OFFSET(LocationHybridClass, zone_in),
1199 NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
1200 G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1203 g_signal_new("zone-out", G_TYPE_FROM_CLASS(klass),
1204 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1205 G_STRUCT_OFFSET(LocationHybridClass, zone_out),
1206 NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
1207 G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1209 properties[PROP_METHOD_TYPE] =
1210 g_param_spec_int("method", "method type",
1211 "location method type name", LOCATION_METHOD_HYBRID,
1212 LOCATION_METHOD_HYBRID, LOCATION_METHOD_HYBRID, G_PARAM_READABLE);
1214 properties[PROP_LAST_POSITION] =
1215 g_param_spec_boxed("last-position", "hybrid last position prop",
1216 "hybrid last position data", LOCATION_TYPE_POSITION, G_PARAM_READABLE);
1218 properties[PROP_POS_INTERVAL] =
1219 g_param_spec_uint("pos-interval", "position interval prop",
1220 "position interval data", LOCATION_UPDATE_INTERVAL_MIN,
1221 LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1223 properties[PROP_VEL_INTERVAL] =
1224 g_param_spec_uint("vel-interval", "velocity interval prop",
1225 "velocity interval data", LOCATION_UPDATE_INTERVAL_MIN,
1226 LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1228 properties[PROP_SAT_INTERVAL] =
1229 g_param_spec_uint("sat-interval", "satellite interval prop",
1230 "satellite interval data", LOCATION_UPDATE_INTERVAL_MIN,
1231 LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1233 properties[PROP_LOC_INTERVAL] =
1234 g_param_spec_uint("loc-interval", "gps location interval prop",
1235 "gps location interval data", LOCATION_UPDATE_INTERVAL_MIN,
1236 LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1238 properties[PROP_MIN_INTERVAL] =
1239 g_param_spec_uint("min-interval", "gps distance-based interval prop",
1240 "gps distance-based interval data", LOCATION_MIN_INTERVAL_MIN,
1241 LOCATION_MIN_INTERVAL_MAX, LOCATION_MIN_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1243 properties[PROP_MIN_DISTANCE] =
1244 g_param_spec_double("min-distance", "gps distance-based distance prop",
1245 "gps distance-based distance data", LOCATION_MIN_DISTANCE_MIN,
1246 LOCATION_MIN_DISTANCE_MAX, LOCATION_MIN_DISTANCE_DEFAULT, G_PARAM_READWRITE);
1248 properties[PROP_BOUNDARY] =
1249 g_param_spec_pointer("boundary", "hybrid boundary prop",
1250 "hybrid boundary data", G_PARAM_READWRITE);
1252 properties[PROP_REMOVAL_BOUNDARY] =
1253 g_param_spec_boxed("removal-boundary", "hybrid removal boundary prop",
1254 "hybrid removal boundary data", LOCATION_TYPE_BOUNDARY, G_PARAM_READWRITE);
1257 properties[PROP_SERVICE_STATUS] =
1258 g_param_spec_int("service-status", "location service status prop",
1259 "location service status data", LOCATION_STATUS_NO_FIX,
1260 LOCATION_STATUS_3D_FIX, LOCATION_STATUS_NO_FIX, G_PARAM_READABLE);
1262 g_object_class_install_properties(gobject_class, PROP_MAX, properties);