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);
136 static LocationObject *
137 hybrid_get_current_object(LocationHybridPrivate *priv)
139 LocationMethod method = hybrid_get_current_method(priv);
141 LocationObject *obj = NULL;
143 case LOCATION_METHOD_GPS:
146 case LOCATION_METHOD_WPS:
157 static gboolean /* True : Receive more accurate info. False : Receive less accurate info */
158 hybrid_compare_g_type_method(LocationHybridPrivate *priv, GType g_type)
160 if (g_type == LOCATION_TYPE_GPS) {
161 hybrid_set_current_method(priv, LOCATION_TYPE_GPS);
163 } else if (g_type == LOCATION_TYPE_WPS && hybrid_get_current_method(priv) == LOCATION_METHOD_WPS) {
164 hybrid_set_current_method(priv, LOCATION_TYPE_WPS);
171 _location_timeout_cb(gpointer data)
173 GObject *object = (GObject *)data;
174 if (!object) return FALSE;
175 LocationHybridPrivate *priv = GET_PRIVATE(object);
176 g_return_val_if_fail(priv, FALSE);
178 LocationPosition *pos = NULL;
179 LocationVelocity *vel = NULL;
180 LocationAccuracy *acc = NULL;
183 pos = location_position_copy(priv->pos);
185 pos = location_position_new(0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
188 vel = location_velocity_copy(priv->vel);
190 vel = location_velocity_new(0, 0.0, 0.0, 0.0);
193 acc = location_accuracy_copy(priv->acc);
195 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
197 g_signal_emit(object, signals[SERVICE_UPDATED], 0, priv->signal_type, pos, vel, acc);
198 priv->signal_type = 0;
200 if (pos) location_position_free(pos);
201 if (vel) location_velocity_free(vel);
202 if (acc) location_accuracy_free(acc);
208 _position_timeout_cb(gpointer data)
210 GObject *object = (GObject *)data;
211 if (!object) return FALSE;
212 LocationHybridPrivate *priv = GET_PRIVATE(object);
213 g_return_val_if_fail(priv, FALSE);
215 if (priv->pos_interval == priv->vel_interval) {
216 priv->signal_type |= POSITION_UPDATED;
217 priv->signal_type |= VELOCITY_UPDATED;
219 priv->signal_type |= POSITION_UPDATED;
221 _location_timeout_cb(object);
227 _velocity_timeout_cb(gpointer data)
229 GObject *object = (GObject *)data;
230 LocationHybridPrivate *priv = GET_PRIVATE(object);
231 g_return_val_if_fail(priv, FALSE);
233 if (priv->pos_interval != priv->vel_interval) {
234 priv->signal_type |= VELOCITY_UPDATED;
235 _location_timeout_cb(object);
242 location_hybrid_gps_cb(keynode_t *key, gpointer self)
245 g_return_if_fail(key);
246 g_return_if_fail(self);
247 LocationHybridPrivate *priv = GET_PRIVATE(self);
248 g_return_if_fail(priv);
249 g_return_if_fail(priv->wps);
251 gboolean wps_started = FALSE;
252 int ret = LOCATION_ERROR_NONE;
255 onoff = location_setting_get_key_val(key);
257 /* restart WPS when GPS stopped by setting */
258 g_object_get(priv->wps, "is_started", &wps_started, NULL);
259 if (wps_started == FALSE && 1 == location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED)) {
260 LOCATION_LOGD("GPS stoped by setting, so restart WPS");
261 ret = location_start(priv->wps);
262 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Fail hybrid/wps location_start : [%s]", err_msg(ret));
264 } else if (1 == onoff) {
265 LOCATION_LOGD("Hybrid GPS resumed by setting");
268 LOCATION_LOGD("Invalid Value[%d]", onoff);
274 hybrid_location_updated(GObject *obj, guint error, gpointer position, gpointer velocity, gpointer accuracy, gpointer self)
277 LocationPosition *pos = (LocationPosition *)position;
278 LocationVelocity *vel = (LocationVelocity *)velocity;
279 LocationAccuracy *acc = (LocationAccuracy *)accuracy;
281 LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
282 g_return_if_fail(priv);
284 g_signal_emit(self, signals[LOCATION_UPDATED], 0, error, pos, vel, acc);
288 hybrid_service_updated(GObject *obj, gint type, gpointer data, gpointer velocity, gpointer accuracy, gpointer self)
291 LocationPosition *pos = NULL;
292 LocationVelocity *vel = NULL;
293 LocationAccuracy *acc = NULL;
294 LocationSatellite *sat = NULL;
295 gboolean wps_started = FALSE;
296 int ret = LOCATION_ERROR_NONE;
298 if (type == SATELLITE_UPDATED) {
299 sat = (LocationSatellite *) data;
300 if (!sat->timestamp) return;
302 pos = (LocationPosition *) data;
303 vel = (LocationVelocity *) velocity;
304 acc = (LocationAccuracy *) accuracy;
305 if (!pos->timestamp) return;
306 if (!vel->timestamp) return;
309 LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
310 g_return_if_fail(priv);
312 GType g_type = G_TYPE_FROM_INSTANCE(obj);
313 if (g_type == LOCATION_TYPE_GPS) {
314 if (type == SATELLITE_UPDATED) {
315 satellite_signaling(self, signals, &(priv->enabled), priv->sat_interval, TRUE, &(priv->sat_updated_timestamp), &(priv->sat), sat);
317 } else if (location_setting_get_int(VCONFKEY_LOCATION_GPS_STATE) == VCONFKEY_LOCATION_GPS_SEARCHING
318 && location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED) == 0) {
319 LOCATION_LOGD("Searching GPS");
321 /* restart WPS when GPS not available */
322 if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
323 if (priv->wps && wps_started == FALSE) {
324 LOCATION_LOGD("Starting WPS");
325 ret = location_start(priv->wps);
326 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Fail hyhrid location_start : [%s]", err_msg(ret));
332 if (hybrid_compare_g_type_method(priv, g_type)) {
333 if (priv->pos) location_position_free(priv->pos);
334 if (priv->vel) location_velocity_free(priv->vel);
335 if (priv->acc) location_accuracy_free(priv->acc);
337 if (pos) priv->pos = location_position_copy(pos);
338 if (vel) priv->vel = location_velocity_copy(vel);
339 if (acc) priv->acc = location_accuracy_copy(acc);
343 enable_signaling(self, signals, &(priv->enabled), TRUE, pos->status);
345 if (type == DISTANCE_UPDATED) {
346 distance_based_position_signaling(self, signals, priv->enabled, pos, vel, acc,
347 priv->min_interval, priv->min_distance, &(priv->enabled),
348 &(priv->dist_updated_timestamp), &(priv->pos), &(priv->vel), &(priv->acc));
350 position_velocity_signaling(self, signals, priv->pos_interval, priv->vel_interval, priv->loc_interval,
351 &(priv->pos_updated_timestamp), &(priv->vel_updated_timestamp), &(priv->loc_updated_timestamp),
352 priv->boundary_list, pos, vel, acc);
356 /* if receive GPS position then stop WPS.. */
357 if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
358 if (g_type == LOCATION_TYPE_GPS && wps_started == TRUE) {
359 LOCATION_LOGD("Calling WPS stop");
360 ret = location_stop(priv->wps);
361 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Fail hyhrid location_stop : [%s]", err_msg(ret));
364 } else if (g_type == LOCATION_TYPE_WPS && location_setting_get_int(VCONFKEY_LOCATION_GPS_STATE) == VCONFKEY_LOCATION_GPS_SEARCHING) {
365 LOCATION_LOGD("g_type is LOCATION_TYPE_WPS and GPS is searching");
366 hybrid_set_current_method(priv, g_type);
368 if (priv->pos) location_position_free(priv->pos);
369 if (priv->vel) location_velocity_free(priv->vel);
370 if (priv->acc) location_accuracy_free(priv->acc);
372 if (pos) priv->pos = location_position_copy(pos);
373 if (vel) priv->vel = location_velocity_copy(vel);
374 if (acc) priv->acc = location_accuracy_copy(acc);
378 enable_signaling(self, signals, &(priv->enabled), TRUE, pos->status);
380 if (type == DISTANCE_UPDATED) {
381 distance_based_position_signaling(self, signals, priv->enabled, pos, vel, acc,
382 priv->min_interval, priv->min_distance, &(priv->enabled),
383 &(priv->dist_updated_timestamp), &(priv->pos), &(priv->vel), &(priv->acc));
385 LOCATION_LOGD("position_velocity_signaling");
386 position_velocity_signaling(self, signals, priv->pos_interval, priv->vel_interval, priv->loc_interval,
387 &(priv->pos_updated_timestamp), &(priv->vel_updated_timestamp), &(priv->loc_updated_timestamp),
388 priv->boundary_list, pos, vel, acc);
395 hybrid_service_enabled(GObject *obj, guint status, gpointer self)
398 LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
399 g_return_if_fail(priv);
401 GType g_type = G_TYPE_FROM_INSTANCE(obj);
402 if (g_type == LOCATION_TYPE_GPS) {
403 priv->gps_enabled = TRUE;
404 } else if (g_type == LOCATION_TYPE_WPS) {
405 priv->wps_enabled = TRUE;
407 LOCATION_LOGW("Undefined GType enabled");
410 hybrid_get_update_method(priv);
414 hybrid_service_disabled(GObject *obj, guint status, gpointer self)
417 LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self);
418 g_return_if_fail(priv);
419 GType g_type = G_TYPE_FROM_INSTANCE(obj);
420 if (g_type == LOCATION_TYPE_GPS) {
421 priv->gps_enabled = FALSE;
422 } else if (g_type == LOCATION_TYPE_WPS) {
423 priv->wps_enabled = FALSE;
425 LOCATION_LOGW("Undefined GType disabled");
428 hybrid_get_update_method(priv);
429 if (!priv->gps_enabled && !priv->wps_enabled)
430 enable_signaling(self, signals, &(priv->enabled), FALSE, status);
435 location_hybrid_start(LocationHybrid *self)
439 int ret_gps = LOCATION_ERROR_NONE;
440 int ret_wps = LOCATION_ERROR_NONE;
441 gboolean gps_started = FALSE;
442 gboolean wps_started = FALSE;
444 LocationHybridPrivate *priv = GET_PRIVATE(self);
445 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
446 LOC_COND_RET(!priv->gps && !priv->wps, LOCATION_ERROR_NOT_AVAILABLE, _E, "GPS and WPS Object are not created.");
448 if (priv->gps) g_object_get(priv->gps, "is_started", &gps_started, NULL);
449 if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
451 if ((gps_started == TRUE) || (wps_started == TRUE)) {
452 LOCATION_LOGD("Already started");
453 return LOCATION_ERROR_NONE;
456 if (priv->gps) ret_gps = location_start(priv->gps);
457 if (priv->wps) ret_wps = location_start(priv->wps);
459 if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE) {
460 LOCATION_LOGD("ret_gps = %d, ret_wps = %d", ret_gps, ret_wps);
461 if (ret_gps == LOCATION_ERROR_SECURITY_DENIED || ret_wps == LOCATION_ERROR_SECURITY_DENIED)
462 return LOCATION_ERROR_SECURITY_DENIED;
463 else if (ret_gps == LOCATION_ERROR_SETTING_OFF || ret_wps == LOCATION_ERROR_SETTING_OFF)
464 return LOCATION_ERROR_SETTING_OFF;
465 else if (ret_gps == LOCATION_ERROR_NOT_ALLOWED || ret_wps == LOCATION_ERROR_NOT_ALLOWED)
466 return LOCATION_ERROR_NOT_ALLOWED;
468 return LOCATION_ERROR_NOT_AVAILABLE;
471 if (priv->set_noti == FALSE) {
472 location_setting_add_notify(VCONFKEY_LOCATION_ENABLED, location_hybrid_gps_cb, self);
473 priv->set_noti = TRUE;
476 return LOCATION_ERROR_NONE;
480 location_hybrid_stop(LocationHybrid *self)
484 LocationHybridPrivate *priv = GET_PRIVATE(self);
485 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
487 LOCATION_LOGD("location_hybrid_stop started......!!!");
489 int ret_gps = LOCATION_ERROR_NOT_AVAILABLE;
490 int ret_wps = LOCATION_ERROR_NOT_AVAILABLE;
491 gboolean gps_started = FALSE;
492 gboolean wps_started = FALSE;
494 if (priv->gps) g_object_get(priv->gps, "is_started", &gps_started, NULL);
495 if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL);
497 if ((gps_started == FALSE) && (wps_started == FALSE))
498 return LOCATION_ERROR_NONE;
500 if (priv->gps) ret_gps = location_stop(priv->gps);
501 if (priv->wps) ret_wps = location_stop(priv->wps);
503 if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE)
504 return LOCATION_ERROR_NOT_AVAILABLE;
506 if (priv->pos_timer) g_source_remove(priv->pos_timer);
507 if (priv->vel_timer) g_source_remove(priv->vel_timer);
511 if (priv->set_noti == TRUE) {
512 location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_hybrid_gps_cb);
513 priv->set_noti = FALSE;
516 priv->gps_enabled = FALSE;
517 priv->wps_enabled = FALSE;
519 return LOCATION_ERROR_NONE;
523 location_hybrid_dispose(GObject *gobject)
526 LocationHybridPrivate *priv = GET_PRIVATE(gobject);
527 g_return_if_fail(priv);
529 if (priv->pos_timer) g_source_remove(priv->pos_timer);
530 if (priv->vel_timer) g_source_remove(priv->vel_timer);
534 if (priv->set_noti == TRUE) {
535 location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_hybrid_gps_cb);
536 priv->set_noti = FALSE;
539 G_OBJECT_CLASS(location_hybrid_parent_class)->dispose(gobject);
543 location_hybrid_finalize(GObject *gobject)
546 LocationHybridPrivate *priv = GET_PRIVATE(gobject);
547 g_return_if_fail(priv);
550 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_enabled), gobject);
551 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_disabled), gobject);
552 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_updated), gobject);
553 g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_location_updated), gobject);
554 location_free(priv->gps, TRUE);
557 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_enabled), gobject);
558 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_disabled), gobject);
559 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_updated), gobject);
560 g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_location_updated), gobject);
561 location_free(priv->wps, TRUE);
564 if (priv->boundary_list) {
565 g_list_free_full(priv->boundary_list, free_boundary_list);
566 priv->boundary_list = NULL;
570 location_position_free(priv->pos);
575 location_velocity_free(priv->vel);
580 location_accuracy_free(priv->acc);
585 location_satellite_free(priv->sat);
589 G_OBJECT_CLASS(location_hybrid_parent_class)->finalize(gobject);
593 location_hybrid_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
595 LocationHybridPrivate *priv = GET_PRIVATE(object);
596 g_return_if_fail(priv);
597 if (!priv->gps && !priv->wps) {
598 LOCATION_LOGW("Set property is not available now");
603 switch (property_id) {
604 case PROP_BOUNDARY: {
605 GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
606 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
607 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Set boundary. Error[%s]", err_msg(ret));
610 case PROP_REMOVAL_BOUNDARY: {
611 LocationBoundary *req_boundary = (LocationBoundary *) g_value_dup_boxed(value);
612 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
613 LOC_COND_VOID(ret != LOCATION_ERROR_NONE, _E, "Removal boundary. Error[%s]", err_msg(ret));
616 case PROP_POS_INTERVAL: {
617 guint interval = g_value_get_uint(value);
618 LOCATION_LOGD("Set prop>> PROP_POS_INTERVAL: %u", interval);
620 if (interval < LOCATION_UPDATE_INTERVAL_MAX)
621 priv->pos_interval = interval;
623 priv->pos_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
625 priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
628 if (priv->pos_timer) {
629 g_source_remove(priv->pos_timer);
630 priv->pos_timer = g_timeout_add(priv->pos_interval * 1000, _position_timeout_cb, object);
633 if (priv->gps) g_object_set(priv->gps, "pos-interval", priv->pos_interval, NULL);
634 if (priv->wps) g_object_set(priv->wps, "pos-interval", priv->pos_interval, NULL);
638 case PROP_VEL_INTERVAL: {
639 guint interval = g_value_get_uint(value);
640 LOCATION_LOGD("Set prop>> PROP_VEL_INTERVAL: %u", interval);
642 if (interval < LOCATION_UPDATE_INTERVAL_MAX)
643 priv->vel_interval = interval;
645 priv->vel_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
648 priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
650 if (priv->vel_timer) {
651 g_source_remove(priv->vel_timer);
652 priv->vel_timer = g_timeout_add(priv->vel_interval * 1000, _velocity_timeout_cb, object);
655 if (priv->gps) g_object_set(priv->gps, "vel-interval", priv->vel_interval, NULL);
656 if (priv->wps) g_object_set(priv->wps, "vel-interval", priv->vel_interval, NULL);
660 case PROP_SAT_INTERVAL: {
661 guint interval = g_value_get_uint(value);
662 LOCATION_LOGD("Set prop>> PROP_SAT_INTERVAL: %u", interval);
664 if (interval < LOCATION_UPDATE_INTERVAL_MAX)
665 priv->sat_interval = interval;
667 priv->sat_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
670 priv->sat_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
674 case PROP_LOC_INTERVAL: {
675 guint interval = g_value_get_uint(value);
676 LOCATION_LOGD("Set prop>> PROP_LOC_INTERVAL: %u", interval);
678 if (interval < LOCATION_UPDATE_INTERVAL_MAX)
679 priv->loc_interval = interval;
681 priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
683 priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
685 if (priv->gps) g_object_set(priv->gps, "loc-interval", priv->loc_interval, NULL);
686 if (priv->wps) g_object_set(priv->wps, "loc-interval", priv->loc_interval, NULL);
690 case PROP_MIN_INTERVAL: {
691 guint interval = g_value_get_uint(value);
692 LOCATION_LOGD("Set prop>> PROP_MIN_INTERVAL: %u", interval);
694 if (interval < LOCATION_MIN_INTERVAL_MAX)
695 priv->min_interval = interval;
697 priv->min_interval = (guint)LOCATION_MIN_INTERVAL_MAX;
699 priv->min_interval = (guint)LOCATION_MIN_INTERVAL_DEFAULT;
701 if (priv->gps) g_object_set(priv->gps, "min-interval", priv->min_interval, NULL);
702 if (priv->wps) g_object_set(priv->wps, "min-interval", priv->min_interval, NULL);
706 case PROP_MIN_DISTANCE: {
707 gdouble distance = g_value_get_double(value);
708 LOCATION_LOGD("Set prop>> PROP_MIN_DISTANCE: %u", distance);
710 if (distance < LOCATION_MIN_DISTANCE_MAX)
711 priv->min_distance = distance;
713 priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_MAX;
715 priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_DEFAULT;
717 if (priv->gps) g_object_set(priv->gps, "min-distance", priv->min_distance, NULL);
718 if (priv->wps) g_object_set(priv->wps, "min-distance", priv->min_distance, NULL);
723 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
729 location_hybrid_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
731 LocationHybridPrivate *priv = GET_PRIVATE(object);
732 g_return_if_fail(priv);
734 LOC_COND_VOID(!priv->gps && !priv->wps, _E, "Error : Get property is not available now");
736 LOCATION_LOGW("Get Propery ID[%d]", property_id);
738 switch (property_id) {
739 case PROP_METHOD_TYPE:
740 g_value_set_int(value, hybrid_get_current_method(priv));
742 case PROP_LAST_POSITION:
743 g_value_set_boxed(value, priv->pos);
746 g_value_set_pointer(value, g_list_first(priv->boundary_list));
748 case PROP_POS_INTERVAL:
749 g_value_set_uint(value, priv->pos_interval);
751 case PROP_VEL_INTERVAL:
752 g_value_set_uint(value, priv->vel_interval);
754 case PROP_SAT_INTERVAL:
755 g_value_set_uint(value, priv->sat_interval);
757 case PROP_LOC_INTERVAL:
758 g_value_set_uint(value, priv->loc_interval);
760 case PROP_MIN_INTERVAL:
761 g_value_set_uint(value, priv->min_interval);
763 case PROP_MIN_DISTANCE:
764 g_value_set_double(value, priv->min_distance);
766 case PROP_SERVICE_STATUS:
767 g_value_set_int(value, priv->enabled);
770 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
776 location_hybrid_get_position(LocationHybrid *self, LocationPosition **position, LocationAccuracy **accuracy)
779 int ret = LOCATION_ERROR_NOT_AVAILABLE;
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);
788 *position = location_position_copy(priv->pos);
789 ret = LOCATION_ERROR_NONE;
793 *accuracy = location_accuracy_copy(priv->acc);
799 location_hybrid_get_position_ext(LocationHybrid *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
802 if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
803 return LOCATION_ERROR_SETTING_OFF;
805 LocationHybridPrivate *priv = GET_PRIVATE(self);
806 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
807 LOCATION_IF_HYBRID_FAIL(VCONFKEY_LOCATION_GPS_STATE, VCONFKEY_LOCATION_WPS_STATE);
809 if (priv->pos && priv->vel) {
810 *position = location_position_copy(priv->pos);
811 *velocity = location_velocity_copy(priv->vel);
813 LOCATION_LOGE("There is invalid data.");
814 return LOCATION_ERROR_NOT_AVAILABLE;
818 *accuracy = location_accuracy_copy(priv->acc);
820 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
822 return LOCATION_ERROR_NONE;
827 location_hybrid_get_last_position(LocationHybrid *self, LocationPosition **position, LocationAccuracy **accuracy)
831 int ret = LOCATION_ERROR_NONE;
832 LocationPosition *gps_pos = NULL, *wps_pos = NULL;
833 LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
834 LocationHybridPrivate *priv = GET_PRIVATE(self);
835 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
837 if (priv->gps) location_get_last_position(priv->gps, &gps_pos, &gps_acc);
838 if (priv->wps) location_get_last_position(priv->wps, &wps_pos, &wps_acc);
840 if (gps_pos && wps_pos) {
841 if (wps_pos->timestamp > gps_pos->timestamp) {
844 location_position_free(gps_pos);
845 location_accuracy_free(gps_acc);
849 location_position_free(wps_pos);
850 location_accuracy_free(wps_acc);
852 } else if (gps_pos) {
855 } else if (wps_pos) {
859 ret = LOCATION_ERROR_NOT_AVAILABLE;
866 location_hybrid_get_last_position_ext(LocationHybrid *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
870 int ret = LOCATION_ERROR_NONE;
871 LocationPosition *gps_pos = NULL, *wps_pos = NULL;
872 LocationVelocity *gps_vel = NULL, *wps_vel = NULL;
873 LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
874 LocationHybridPrivate *priv = GET_PRIVATE(self);
875 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
877 if (priv->gps) location_get_last_position_ext(priv->gps, &gps_pos, &gps_vel, &gps_acc);
878 if (priv->wps) location_get_last_position_ext(priv->wps, &wps_pos, &wps_vel, &wps_acc);
880 if (gps_pos && wps_pos && gps_vel && wps_vel) {
881 if (wps_pos->timestamp > gps_pos->timestamp) {
885 location_position_free(gps_pos);
886 location_velocity_free(gps_vel);
887 location_accuracy_free(gps_acc);
892 location_position_free(wps_pos);
893 location_velocity_free(wps_vel);
894 location_accuracy_free(wps_acc);
896 } else if (gps_pos && gps_vel) {
900 } else if (wps_pos && wps_vel) {
905 ret = LOCATION_ERROR_NOT_AVAILABLE;
912 location_hybrid_get_velocity(LocationHybrid *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
915 int ret = LOCATION_ERROR_NOT_AVAILABLE;
916 if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
917 return LOCATION_ERROR_SETTING_OFF;
919 LocationHybridPrivate *priv = GET_PRIVATE(self);
920 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
921 LOCATION_IF_HYBRID_FAIL(VCONFKEY_LOCATION_GPS_STATE, VCONFKEY_LOCATION_WPS_STATE);
924 *velocity = location_velocity_copy(priv->vel);
925 ret = LOCATION_ERROR_NONE;
929 *accuracy = location_accuracy_copy(priv->acc);
935 location_hybrid_get_last_velocity(LocationHybrid *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
939 int ret = LOCATION_ERROR_NONE;
940 LocationHybridPrivate *priv = GET_PRIVATE(self);
941 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
942 LocationVelocity *gps_vel = NULL, *wps_vel = NULL;
943 LocationAccuracy *gps_acc = NULL, *wps_acc = NULL;
945 if (priv->gps) location_get_last_velocity(priv->gps, &gps_vel, &gps_acc);
946 if (priv->wps) location_get_last_velocity(priv->wps, &wps_vel, &wps_acc);
948 if (gps_vel && wps_vel) {
949 if (wps_vel->timestamp > gps_vel->timestamp) {
952 location_velocity_free(gps_vel);
953 location_accuracy_free(gps_acc);
957 location_velocity_free(wps_vel);
958 location_accuracy_free(wps_acc);
960 } else if (gps_vel) {
963 } else if (wps_vel) {
969 ret = LOCATION_ERROR_NOT_AVAILABLE;
976 location_hybrid_get_satellite(LocationHybrid *self, LocationSatellite **satellite)
979 int ret = LOCATION_ERROR_NOT_AVAILABLE;
980 if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED) && !location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED))
981 return LOCATION_ERROR_SETTING_OFF;
983 LocationHybridPrivate *priv = GET_PRIVATE(self);
984 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
986 *satellite = location_satellite_copy(priv->sat);
987 ret = LOCATION_ERROR_NONE;
994 location_hybrid_get_last_satellite(LocationHybrid *self, LocationSatellite **satellite)
998 int ret = LOCATION_ERROR_NONE;
999 LocationHybridPrivate *priv = GET_PRIVATE(self);
1000 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1003 ret = location_get_last_satellite(priv->gps, satellite);
1006 ret = LOCATION_ERROR_NOT_AVAILABLE;
1013 location_hybrid_set_option(LocationHybrid *self, const char *option)
1016 LocationHybridPrivate *priv = GET_PRIVATE(self);
1017 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1019 int ret_gps = LOCATION_ERROR_NOT_AVAILABLE;
1020 int ret_wps = LOCATION_ERROR_NOT_AVAILABLE;
1022 if (priv->gps) ret_gps = location_set_option(priv->gps, option);
1023 if (priv->wps) ret_wps = location_set_option(priv->wps, option);
1025 if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE)
1026 return LOCATION_ERROR_NOT_AVAILABLE;
1028 return LOCATION_ERROR_NONE;
1032 location_hybrid_request_single_location(LocationHybrid *self, int timeout)
1035 LocationHybridPrivate *priv = GET_PRIVATE(self);
1036 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1038 int ret = LOCATION_ERROR_NOT_AVAILABLE;
1041 ret = location_request_single_location(priv->gps, timeout);
1043 ret = location_request_single_location(priv->wps, timeout);
1049 location_hybrid_get_nmea(LocationHybrid *self, char **nmea_data)
1052 LocationHybridPrivate *priv = GET_PRIVATE(self);
1053 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1055 int ret = LOCATION_ERROR_NOT_AVAILABLE;
1057 if (priv->gps) ret = location_get_nmea(priv->gps, nmea_data);
1059 if (ret != LOCATION_ERROR_NONE)
1060 return LOCATION_ERROR_NOT_AVAILABLE;
1062 return LOCATION_ERROR_NONE;
1066 location_hybrid_set_mock_location(LocationHybrid *self, LocationPosition *position, LocationVelocity *velocity, LocationAccuracy *accuracy)
1069 LocationHybridPrivate *priv = GET_PRIVATE(self);
1070 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1071 int ret = LOCATION_ERROR_NONE;
1074 ret = location_set_mock_location(priv->gps, position, velocity, accuracy);
1076 ret = location_set_mock_location(priv->wps, position, velocity, accuracy);
1078 ret = LOCATION_ERROR_NOT_AVAILABLE;
1084 location_hybrid_clear_mock_location(LocationHybrid *self)
1087 LocationHybridPrivate *priv = GET_PRIVATE(self);
1088 g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
1089 int ret = LOCATION_ERROR_NONE;
1092 ret = location_clear_mock_location(priv->gps);
1094 ret = location_clear_mock_location(priv->wps);
1096 ret = LOCATION_ERROR_NOT_AVAILABLE;
1102 location_ielement_interface_init(LocationIElementInterface *iface)
1104 iface->start = (TYPE_START_FUNC)location_hybrid_start;
1105 iface->stop = (TYPE_STOP_FUNC)location_hybrid_stop;
1106 iface->get_position = (TYPE_GET_POSITION)location_hybrid_get_position;
1107 iface->get_position_ext = (TYPE_GET_POSITION_EXT)location_hybrid_get_position_ext;
1108 iface->get_last_position = (TYPE_GET_POSITION)location_hybrid_get_last_position;
1109 iface->get_last_position_ext = (TYPE_GET_POSITION_EXT)location_hybrid_get_last_position_ext;
1110 iface->get_velocity = (TYPE_GET_VELOCITY)location_hybrid_get_velocity;
1111 iface->get_last_velocity = (TYPE_GET_VELOCITY)location_hybrid_get_last_velocity;
1112 iface->get_satellite = (TYPE_GET_SATELLITE)location_hybrid_get_satellite;
1113 iface->get_last_satellite = (TYPE_GET_SATELLITE)location_hybrid_get_last_satellite;
1114 iface->set_option = (TYPE_SET_OPTION)location_hybrid_set_option;
1115 iface->request_single_location = (TYPE_REQUEST_SINGLE_LOCATION)location_hybrid_request_single_location;
1116 iface->get_nmea = (TYPE_GET_NMEA)location_hybrid_get_nmea;
1118 iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_hybrid_set_mock_location;
1119 iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_hybrid_clear_mock_location;
1123 location_hybrid_init(LocationHybrid *self)
1126 LocationHybridPrivate *priv = GET_PRIVATE(self);
1127 g_return_if_fail(priv);
1129 priv->pos_interval = LOCATION_UPDATE_INTERVAL_NONE;
1130 priv->vel_interval = LOCATION_UPDATE_INTERVAL_NONE;
1131 priv->sat_interval = LOCATION_UPDATE_INTERVAL_NONE;
1132 priv->loc_interval = LOCATION_UPDATE_INTERVAL_NONE;
1133 priv->min_interval = LOCATION_UPDATE_INTERVAL_NONE;
1135 priv->pos_updated_timestamp = 0;
1136 priv->vel_updated_timestamp = 0;
1137 priv->sat_updated_timestamp = 0;
1138 priv->loc_updated_timestamp = 0;
1140 priv->gps_enabled = FALSE;
1141 priv->wps_enabled = FALSE;
1145 priv->set_noti = FALSE;
1146 priv->signal_type = 0;
1147 priv->pos_timer = 0;
1148 priv->vel_timer = 0;
1150 if (location_is_supported_method(LOCATION_METHOD_GPS)) priv->gps = location_new(LOCATION_METHOD_GPS, TRUE);
1151 if (location_is_supported_method(LOCATION_METHOD_WPS)) priv->wps = location_new(LOCATION_METHOD_WPS, TRUE);
1154 g_signal_connect(priv->gps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self);
1155 g_signal_connect(priv->gps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self);
1156 g_signal_connect(priv->gps, "service-updated", G_CALLBACK(hybrid_service_updated), self);
1157 g_signal_connect(priv->gps, "location-updated", G_CALLBACK(hybrid_location_updated), self);
1160 g_signal_connect(priv->wps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self);
1161 g_signal_connect(priv->wps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self);
1162 g_signal_connect(priv->wps, "service-updated", G_CALLBACK(hybrid_service_updated), self);
1163 g_signal_connect(priv->wps, "location-updated", G_CALLBACK(hybrid_location_updated), self);
1166 hybrid_set_current_method(priv, LOCATION_TYPE_HYBRID);
1167 priv->enabled = FALSE;
1174 priv->boundary_list = NULL;
1178 location_hybrid_class_init(LocationHybridClass *klass)
1181 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
1183 gobject_class->set_property = location_hybrid_set_property;
1184 gobject_class->get_property = location_hybrid_get_property;
1186 gobject_class->dispose = location_hybrid_dispose;
1187 gobject_class->finalize = location_hybrid_finalize;
1189 g_type_class_add_private(klass, sizeof(LocationHybridPrivate));
1191 signals[SERVICE_ENABLED] =
1192 g_signal_new("service-enabled", G_TYPE_FROM_CLASS(klass),
1193 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1194 G_STRUCT_OFFSET(LocationHybridClass, enabled),
1195 NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1197 signals[SERVICE_DISABLED] =
1198 g_signal_new("service-disabled", G_TYPE_FROM_CLASS(klass),
1199 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1200 G_STRUCT_OFFSET(LocationHybridClass, disabled),
1201 NULL, NULL, location_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
1203 signals[SERVICE_UPDATED] =
1204 g_signal_new("service-updated", G_TYPE_FROM_CLASS(klass),
1205 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1206 G_STRUCT_OFFSET(LocationHybridClass, service_updated),
1207 NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER,
1208 G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1210 signals[LOCATION_UPDATED] =
1211 g_signal_new("location-updated", G_TYPE_FROM_CLASS(klass),
1212 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1213 G_STRUCT_OFFSET(LocationHybridClass, location_updated),
1214 NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER,
1215 G_TYPE_NONE, 4, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1218 g_signal_new("zone-in", G_TYPE_FROM_CLASS(klass),
1219 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1220 G_STRUCT_OFFSET(LocationHybridClass, zone_in),
1221 NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
1222 G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1225 g_signal_new("zone-out", G_TYPE_FROM_CLASS(klass),
1226 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE,
1227 G_STRUCT_OFFSET(LocationHybridClass, zone_out),
1228 NULL, NULL, location_VOID__POINTER_POINTER_POINTER,
1229 G_TYPE_NONE, 3, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER);
1231 properties[PROP_METHOD_TYPE] =
1232 g_param_spec_int("method", "method type",
1233 "location method type name", LOCATION_METHOD_HYBRID,
1234 LOCATION_METHOD_HYBRID, LOCATION_METHOD_HYBRID, G_PARAM_READABLE);
1236 properties[PROP_LAST_POSITION] =
1237 g_param_spec_boxed("last-position", "hybrid last position prop",
1238 "hybrid last position data", LOCATION_TYPE_POSITION, G_PARAM_READABLE);
1240 properties[PROP_POS_INTERVAL] =
1241 g_param_spec_uint("pos-interval", "position interval prop",
1242 "position interval data", LOCATION_UPDATE_INTERVAL_MIN,
1243 LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1245 properties[PROP_VEL_INTERVAL] =
1246 g_param_spec_uint("vel-interval", "velocity interval prop",
1247 "velocity interval data", LOCATION_UPDATE_INTERVAL_MIN,
1248 LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1250 properties[PROP_SAT_INTERVAL] =
1251 g_param_spec_uint("sat-interval", "satellite interval prop",
1252 "satellite interval data", LOCATION_UPDATE_INTERVAL_MIN,
1253 LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1255 properties[PROP_LOC_INTERVAL] =
1256 g_param_spec_uint("loc-interval", "gps location interval prop",
1257 "gps location interval data", LOCATION_UPDATE_INTERVAL_MIN,
1258 LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1260 properties[PROP_MIN_INTERVAL] =
1261 g_param_spec_uint("min-interval", "gps distance-based interval prop",
1262 "gps distance-based interval data", LOCATION_MIN_INTERVAL_MIN,
1263 LOCATION_MIN_INTERVAL_MAX, LOCATION_MIN_INTERVAL_DEFAULT, G_PARAM_READWRITE);
1265 properties[PROP_MIN_DISTANCE] =
1266 g_param_spec_double("min-distance", "gps distance-based distance prop",
1267 "gps distance-based distance data", LOCATION_MIN_DISTANCE_MIN,
1268 LOCATION_MIN_DISTANCE_MAX, LOCATION_MIN_DISTANCE_DEFAULT, G_PARAM_READWRITE);
1270 properties[PROP_BOUNDARY] =
1271 g_param_spec_pointer("boundary", "hybrid boundary prop",
1272 "hybrid boundary data", G_PARAM_READWRITE);
1274 properties[PROP_REMOVAL_BOUNDARY] =
1275 g_param_spec_boxed("removal-boundary", "hybrid removal boundary prop",
1276 "hybrid removal boundary data", LOCATION_TYPE_BOUNDARY, G_PARAM_READWRITE);
1279 properties[PROP_SERVICE_STATUS] =
1280 g_param_spec_int("service-status", "location service status prop",
1281 "location service status data", LOCATION_STATUS_NO_FIX,
1282 LOCATION_STATUS_3D_FIX, LOCATION_STATUS_NO_FIX, G_PARAM_READABLE);
1284 g_object_class_install_properties(gobject_class, PROP_MAX, properties);