From 84d20113adcea213f95a8ff37418fcdeb53d2449 Mon Sep 17 00:00:00 2001 From: Young-Ae Kang Date: Fri, 27 Nov 2015 17:02:19 +0900 Subject: [PATCH] [ACR-476] Added mock location APIs. (Version 1.0.0) 1. Fixed SVASE defects. 2. Fixed some bugs. 3. Removed calling eventsystem_request_sending_system_event() because eventsystem made it be invalid in Tizen 3.0 Change-Id: I3bf404e1385eda29f1a481e5386d684e7108192b --- CMakeLists.txt | 4 +- location/CMakeLists.txt | 21 +- location/include/location-log.h | 2 +- location/include/location-types.h | 3 + location/manager/location-batch.c | 0 location/manager/location-gps.c | 36 +- location/manager/location-gps.h | 3 +- location/manager/location-hybrid-mobile.c | 311 ++++++-- location/manager/location-hybrid.h | 3 +- location/manager/location-ielement.c | 34 + location/manager/location-ielement.h | 16 + location/manager/location-mock.c | 1091 ++++++++++++++++++++++++++++ location/manager/location-mock.h | 64 ++ location/manager/location-position.h | 4 +- location/manager/location-satellite.c | 0 location/manager/location-setting.c | 51 -- location/manager/location-setting.h | 8 +- location/manager/location-signaling-util.c | 20 +- location/manager/location-wps.c | 44 +- location/manager/location-wps.h | 3 +- location/manager/location.c | 215 +++++- location/manager/location.h | 48 +- location/module/location-module.h | 17 +- location/module/module-internal.c | 41 +- location/module/module-internal.h | 7 + packaging/liblbs-location.changes | 8 +- packaging/liblbs-location.spec | 2 +- 27 files changed, 1874 insertions(+), 182 deletions(-) mode change 100644 => 100755 location/manager/location-batch.c mode change 100644 => 100755 location/manager/location-hybrid-mobile.c mode change 100644 => 100755 location/manager/location-ielement.c create mode 100755 location/manager/location-mock.c create mode 100755 location/manager/location-mock.h mode change 100644 => 100755 location/manager/location-satellite.c mode change 100644 => 100755 location/manager/location-signaling-util.c mode change 100644 => 100755 location/manager/location-wps.c mode change 100644 => 100755 location/manager/location.c mode change 100644 => 100755 location/manager/location.h mode change 100644 => 100755 location/module/module-internal.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d8e20a5..2131fcb 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(lbs-location C) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(EXEC_PREFIX "\${prefix}") +#SET(EXEC_PREFIX "\${prefix}") #SET(LIBDIR "\${prefix}/lib") #SET(INCLUDEDIR "\${prefix}/include") @@ -47,8 +47,6 @@ MESSAGE(${CMAKE_C_FLAGS}) MESSAGE(${CMAKE_EXE_LINKER_FLAGS}) # pkgconfig file -SET(PREFIX ${CMAKE_INSTALL_PREFIX}) - CONFIGURE_FILE(lbs-location.pc.in lbs-location.pc @ONLY) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/lbs-location.pc DESTINATION ${LIBDIR}/pkgconfig) diff --git a/location/CMakeLists.txt b/location/CMakeLists.txt index 3c66d9b..0c09d2e 100644 --- a/location/CMakeLists.txt +++ b/location/CMakeLists.txt @@ -7,20 +7,18 @@ SET(MANAGER_DIR "manager") SET(MODULE_DIR "module") IF(FEATURE_PROFILE_TV) - SET(PRIVACY_SRC "") - - MESSAGE("<<< TV Profile >>>") + SET (PRIVACY_SRC "") ELSE(FEATURE_PROFILE_TV) - SET(PRIVACY_SRC "${MANAGER_DIR}/location-privacy.c") - - IF(FEATURE_PROFILE_WEARABLE) - MESSAGE("<<< Wearable Profile >>>") - ELSE(FEATURE_PROFILE_WEARABLE) - MESSAGE("<<< Mobile Profile >>>") - ADD_DEFINITIONS("-DTIZEN_PROFILE_MOBILE") - ENDIF(FEATURE_PROFILE_WEARABLE) + SET (PRIVACY_SRC "${MANAGER_DIR}/location-privacy.c") ENDIF(FEATURE_PROFILE_TV) +IF(FEATURE_PROFILE_WEARABLE) + MESSAGE("<<< Wearable Profile >>>") +ELSE(FEATURE_PROFILE_WEARABLE) + MESSAGE("<<< Mobile Profile >>>") + ADD_DEFINITIONS("-DTIZEN_PROFILE_MOBILE") +ENDIF(FEATURE_PROFILE_WEARABLE) + ADD_DEFINITIONS("-DLIBDIR=\"${LIBDIR}\"") INCLUDE_DIRECTORIES( @@ -45,6 +43,7 @@ SET(SRCS ${MANAGER_DIR}/location-common-util.c ${MANAGER_DIR}/location-gps.c ${MANAGER_DIR}/location-wps.c + ${MANAGER_DIR}/location-mock.c ${PRIVACY_SRC} ${MODULE_DIR}/module-internal.c diff --git a/location/include/location-log.h b/location/include/location-log.h index 47f841e..b0fe405 100644 --- a/location/include/location-log.h +++ b/location/include/location-log.h @@ -40,6 +40,6 @@ #define LOCATION_LOGW(fmt,args...) LOGW(fmt, ##args) #define LOCATION_LOGI(fmt,args...) LOGI(fmt, ##args) #define LOCATION_LOGE(fmt,args...) LOGE(fmt, ##args) -#define LOCATION_SECLOG(fmt,args...) SECURE_LOGW(fmt, ##args) +#define LOCATION_SECLOG(fmt,args...) SECURE_LOGD(fmt, ##args) #endif diff --git a/location/include/location-types.h b/location/include/location-types.h index 4f85cad..b6519a3 100644 --- a/location/include/location-types.h +++ b/location/include/location-types.h @@ -64,6 +64,9 @@ typedef enum { LOCATION_METHOD_HYBRID = 0, /*/< This method selects best method. */ LOCATION_METHOD_GPS, /*/< This method uses Global Positioning System. */ LOCATION_METHOD_WPS, /*/< This method uses Wifi Positioning System. */ + LOCATION_METHOD_MOCK, /* < This method is for mock location */ + LOCATION_METHOD_MOCK_GPS, /* < This method is for mock location */ + LOCATION_METHOD_MOCK_WPS, /* < This method is for mock location */ LOCATION_METHOD_MAX, /*/< The numer of methods */ } LocationMethod; diff --git a/location/manager/location-batch.c b/location/manager/location-batch.c old mode 100644 new mode 100755 diff --git a/location/manager/location-gps.c b/location/manager/location-gps.c index d83d126..cf61b31 100755 --- a/location/manager/location-gps.c +++ b/location/manager/location-gps.c @@ -89,13 +89,14 @@ enum { PROP_SATELLITE, PROP_MIN_INTERVAL, PROP_MIN_DISTANCE, + PROP_SERVICE_STATUS, PROP_MAX }; static guint32 signals[LAST_SIGNAL] = {0, }; static GParamSpec *properties[PROP_MAX] = {NULL, }; -#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_GPS, LocationGpsPrivate)) +#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), LOCATION_TYPE_GPS, LocationGpsPrivate)) static void location_ielement_interface_init(LocationIElementInterface *iface); @@ -565,6 +566,8 @@ location_gps_dispose(GObject *gobject) #endif priv->set_noti = FALSE; } + + G_OBJECT_CLASS(location_gps_parent_class)->dispose(gobject); } static void @@ -769,6 +772,12 @@ location_gps_set_property(GObject *object, break; } + case PROP_SERVICE_STATUS: { + gint enabled = g_value_get_int(value); + LOCATION_LOGD("Set prop>> PROP_SERVICE_STATUS: %u", enabled); + priv->enabled = enabled; + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -847,6 +856,9 @@ location_gps_get_property(GObject *object, } break; } + case PROP_SERVICE_STATUS: + g_value_set_int(value, priv->enabled); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -1271,11 +1283,23 @@ location_gps_class_init(LocationGpsClass *klass) G_TYPE_NONE, 1, G_TYPE_UINT); +#if 0 /* TODO: STATUS_CHANGED will aggregate SERVICE_ENABLED and SERVICE_DISABLED */ + signals[STATUS_CHANGED] = g_signal_new("status-changed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationGpsClass, status_changed), + NULL, NULL, + location_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); +#endif + signals[SERVICE_UPDATED] = g_signal_new("service-updated", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET(LocationGpsClass, updated), + G_STRUCT_OFFSET(LocationGpsClass, service_updated), NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER, G_TYPE_NONE, 4, @@ -1439,6 +1463,14 @@ location_gps_class_init(LocationGpsClass *klass) LOCATION_TYPE_SATELLITE, G_PARAM_READABLE); + /* Tizen 3.0 */ + properties[PROP_SERVICE_STATUS] = g_param_spec_int("service-status", + "location service status prop", + "location service status data", + LOCATION_STATUS_NO_FIX, + LOCATION_STATUS_3D_FIX, + LOCATION_STATUS_NO_FIX, + G_PARAM_READABLE); g_object_class_install_properties(gobject_class, PROP_MAX, properties); diff --git a/location/manager/location-gps.h b/location/manager/location-gps.h index 50a0547..7522128 100644 --- a/location/manager/location-gps.h +++ b/location/manager/location-gps.h @@ -50,11 +50,12 @@ struct _LocationGpsClass { void (* enabled)(guint type); void (* disabled)(guint type); - void (* updated)(gint type, gpointer data, gpointer velocity, gpointer accuracy); + void (* service_updated)(gint type, gpointer data, gpointer velocity, gpointer accuracy); void (* location_updated)(gint error, gpointer position, gpointer velocity, gpointer accuracy); void (* batch_updated)(guint batch_interval, guint batch_period); void (* zone_in)(gpointer boundary, gpointer position, gpointer accuracy); void (* zone_out)(gpointer boundary, gpointer position, gpointer accuracy); + void (* status_changed)(guint type); }; GType location_gps_get_type(void); diff --git a/location/manager/location-hybrid-mobile.c b/location/manager/location-hybrid-mobile.c old mode 100644 new mode 100755 index 5e55fcc..b49a144 --- a/location/manager/location-hybrid-mobile.c +++ b/location/manager/location-hybrid-mobile.c @@ -36,6 +36,8 @@ #include "location-gps.h" #include "location-wps.h" +/* Tizen 3.0 */ +#include "location-mock.h" typedef struct _LocationHybridPrivate { gboolean gps_enabled; @@ -64,6 +66,10 @@ typedef struct _LocationHybridPrivate { gboolean set_noti; guint pos_timer; guint vel_timer; + + /* Tizen 3.0 */ + gboolean mock_enabled; + LocationObject *mock; } LocationHybridPrivate; enum { @@ -78,13 +84,14 @@ enum { PROP_REMOVAL_BOUNDARY, PROP_MIN_INTERVAL, PROP_MIN_DISTANCE, + PROP_SERVICE_STATUS, PROP_MAX }; static guint32 signals[LAST_SIGNAL] = {0, }; static GParamSpec *properties[PROP_MAX] = {NULL, }; -#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_HYBRID, LocationHybridPrivate)) +#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), LOCATION_TYPE_HYBRID, LocationHybridPrivate)) static void location_ielement_interface_init(LocationIElementInterface *iface); @@ -96,7 +103,7 @@ static LocationMethod hybrid_get_current_method(LocationHybridPrivate *priv) { g_return_val_if_fail(priv, LOCATION_METHOD_NONE); - LOCATION_LOGW("Current Method [%d]\n", priv->current_method); + LOCATION_LOGW("Current Method [%d]", priv->current_method); return priv->current_method; } @@ -109,6 +116,8 @@ hybrid_set_current_method(LocationHybridPrivate *priv, GType g_type) priv->current_method = LOCATION_METHOD_GPS; } else if (g_type == LOCATION_TYPE_WPS) { priv->current_method = LOCATION_METHOD_WPS; + } else if (g_type == LOCATION_TYPE_MOCK) { + priv->current_method = LOCATION_METHOD_MOCK; } else if (g_type == LOCATION_TYPE_HYBRID) { priv->current_method = LOCATION_METHOD_HYBRID; } else @@ -121,12 +130,14 @@ hybrid_set_current_method(LocationHybridPrivate *priv, GType g_type) static int hybrid_get_update_method(LocationHybridPrivate *priv) { - if (!priv->gps && !priv->wps) return -1; + if (!priv->gps && !priv->wps & !priv->mock) return -1; if (priv->gps_enabled) { hybrid_set_current_method(priv, LOCATION_TYPE_GPS); } else if (priv->wps_enabled) { hybrid_set_current_method(priv, LOCATION_TYPE_WPS); + } else if (priv->mock_enabled) { + hybrid_set_current_method(priv, LOCATION_TYPE_MOCK); } else { hybrid_set_current_method(priv, LOCATION_TYPE_HYBRID); } @@ -159,14 +170,22 @@ hybrid_get_current_object(LocationHybridPrivate *priv) static gboolean /* True : Receive more accurate info. False : Receive less accurate info */ hybrid_compare_g_type_method(LocationHybridPrivate *priv, GType g_type) { - if (g_type == LOCATION_TYPE_GPS) { - hybrid_set_current_method(priv, LOCATION_TYPE_GPS); - return TRUE; - } else if (g_type == LOCATION_TYPE_WPS && hybrid_get_current_method(priv) == LOCATION_METHOD_WPS) { - hybrid_set_current_method(priv, LOCATION_TYPE_WPS); - return TRUE; + if (location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED) == 1 && + location_setting_get_int(VCONFKEY_LOCATION_MOCK_STATE) == VCONFKEY_LOCATION_POSITION_CONNECTED) { + if (g_type == LOCATION_TYPE_MOCK) { + hybrid_set_current_method(priv, LOCATION_TYPE_MOCK); + return TRUE; + } + } else { + if (g_type == LOCATION_TYPE_GPS) { + hybrid_set_current_method(priv, LOCATION_TYPE_GPS); + return TRUE; + } else if (g_type == LOCATION_TYPE_WPS && + (hybrid_get_current_method(priv) == LOCATION_METHOD_WPS || hybrid_get_current_method(priv) == LOCATION_METHOD_MOCK)) { + hybrid_set_current_method(priv, LOCATION_TYPE_WPS); + return TRUE; + } } - return FALSE; } @@ -314,7 +333,6 @@ hybrid_service_updated(GObject *obj, gboolean wps_started = FALSE; int ret = LOCATION_ERROR_NONE; - /* To discard invalid data in a hybrid */ if (type == SATELLITE_UPDATED) { sat = (LocationSatellite *)data; if (!sat->timestamp) return; @@ -349,16 +367,15 @@ hybrid_service_updated(GObject *obj, } return; } - - } else if (g_type == LOCATION_TYPE_WPS && location_setting_get_int(VCONFKEY_LOCATION_WPS_STATE) == VCONFKEY_LOCATION_WPS_SEARCHING) { + } + /* TODO: Why we need this logic? */ + else if (g_type == LOCATION_TYPE_WPS && + location_setting_get_int(VCONFKEY_LOCATION_WPS_STATE) == VCONFKEY_LOCATION_WPS_SEARCHING) { LOCATION_LOGD("Searching WPS"); return; - } else if (g_type == LOCATION_TYPE_WPS) { - LOCATION_LOGD("g_type is LOCATION_TYPE_WPS"); } if (hybrid_compare_g_type_method(priv, g_type)) { - if (priv->pos) location_position_free(priv->pos); if (priv->vel) location_velocity_free(priv->vel); if (priv->acc) location_accuracy_free(priv->acc); @@ -385,14 +402,18 @@ hybrid_service_updated(GObject *obj, /* if receive GPS position then stop WPS.. */ if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL); - if (LOCATION_TYPE_GPS == g_type && wps_started == TRUE) { + if (g_type == LOCATION_TYPE_GPS && wps_started == TRUE) { + LOCATION_LOGD("Calling WPS stop"); ret = location_stop(priv->wps); if (ret != LOCATION_ERROR_NONE) { LOCATION_LOGW("Fail hybrid location_stop : [%d]", ret); return; } } - } else if (g_type == LOCATION_TYPE_WPS && location_setting_get_int(VCONFKEY_LOCATION_GPS_STATE) == VCONFKEY_LOCATION_GPS_SEARCHING) { + + } else if (g_type == LOCATION_TYPE_WPS + && location_setting_get_int(VCONFKEY_LOCATION_GPS_STATE) == VCONFKEY_LOCATION_GPS_SEARCHING) { + LOCATION_LOGD("g_type is LOCATION_TYPE_WPS and GPS is searching"); hybrid_set_current_method(priv, g_type); if (priv->pos) location_position_free(priv->pos); @@ -402,7 +423,7 @@ hybrid_service_updated(GObject *obj, if (pos) priv->pos = location_position_copy(pos); if (vel) priv->vel = location_velocity_copy(vel); if (acc) priv->acc = location_accuracy_copy(acc); - + if (pos) { if (!priv->enabled) { enable_signaling(self, signals, &(priv->enabled), TRUE, pos->status); @@ -430,14 +451,17 @@ hybrid_service_enabled(GObject *obj, LOCATION_LOGD("hybrid_service_enabled"); LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self); g_return_if_fail(priv); + GType g_type = G_TYPE_FROM_INSTANCE(obj); if (g_type == LOCATION_TYPE_GPS) { priv->gps_enabled = TRUE; } else if (g_type == LOCATION_TYPE_WPS) { priv->wps_enabled = TRUE; + } else if (g_type == LOCATION_TYPE_MOCK) { + priv->mock_enabled = TRUE; } else { LOCATION_LOGW("Undefined GType enabled"); - return; + return; } hybrid_get_update_method(priv); } @@ -455,15 +479,92 @@ hybrid_service_disabled(GObject *obj, priv->gps_enabled = FALSE; } else if (g_type == LOCATION_TYPE_WPS) { priv->wps_enabled = FALSE; + } else if (g_type == LOCATION_TYPE_MOCK) { + priv->mock_enabled = FALSE; } else { LOCATION_LOGW("Undefined GType disabled"); return; } hybrid_get_update_method(priv); - if (!priv->gps_enabled && !priv->wps_enabled) - enable_signaling(self, signals, &(priv->enabled), FALSE, status); + if (location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED) == 1) { + if (!priv->gps_enabled && !priv->wps_enabled && !priv->mock_enabled) + enable_signaling(self, signals, &(priv->enabled), FALSE, status); + } else { + if (!priv->gps_enabled && !priv->wps_enabled) + enable_signaling(self, signals, &(priv->enabled), FALSE, status); + } +} + +#if 0 +static void +hybrid_status_changed(GObject *obj, + guint status, + gpointer self) +{ + LOCATION_LOGD("status = %d", status); + LocationHybridPrivate *priv = GET_PRIVATE((LocationHybrid *)self); + g_return_if_fail(priv); + GType g_type = G_TYPE_FROM_INSTANCE(obj); + + + switch (status) { + case LOCATION_STATUS_NO_FIX: + if (g_type == LOCATION_TYPE_GPS) { + priv->gps_enabled = FALSE; + } else if (g_type == LOCATION_TYPE_WPS) { + priv->wps_enabled = FALSE; + } else if (g_type == LOCATION_TYPE_MOCK) { + priv->mock_enabled = FALSE; + } else { + LOCATION_LOGW("Undefined GType disabled"); + return; + } + hybrid_get_update_method(priv); + if (!priv->gps_enabled && !priv->wps_enabled) + enable_signaling(self, signals, &(priv->enabled), FALSE, status); + break; + + case LOCATION_STATUS_2D_FIX: + case LOCATION_STATUS_3D_FIX: + if (g_type == LOCATION_TYPE_GPS) { + priv->gps_enabled = TRUE; + } else if (g_type == LOCATION_TYPE_WPS) { + priv->wps_enabled = TRUE; + } else if (g_type == LOCATION_TYPE_MOCK) { + priv->mock_enabled = TRUE; + } else { + LOCATION_LOGW("Undefined GType enabled"); + return; + } + hybrid_get_update_method(priv); + break; + + case LOCATION_STATUS_MOCK_SET: + LOCATION_LOGD("Succeeded set mock location!!!"); + break; + + case LOCATION_STATUS_MOCK_FAIL: + if (g_type == LOCATION_TYPE_GPS) { + priv->gps_enabled = FALSE; + } else if (g_type == LOCATION_TYPE_WPS) { + priv->wps_enabled = FALSE; + } else { + LOCATION_LOGW("Undefined GType disabled"); + return; + } + hybrid_get_update_method(priv); + if (!priv->gps_enabled && !priv->wps_enabled) + enable_signaling(self, signals, &(priv->enabled), FALSE, status); + break; + + default: + LOCATION_LOGW("Undefined status"); + break; + } } +#endif + static int location_hybrid_start(LocationHybrid *self) @@ -472,8 +573,10 @@ location_hybrid_start(LocationHybrid *self) int ret_gps = LOCATION_ERROR_NONE; int ret_wps = LOCATION_ERROR_NONE; + int ret_mock = LOCATION_ERROR_NONE; gboolean gps_started = FALSE; gboolean wps_started = FALSE; + gboolean mock_started = FALSE; LocationHybridPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); @@ -484,22 +587,24 @@ location_hybrid_start(LocationHybrid *self) if (priv->gps) g_object_get(priv->gps, "is_started", &gps_started, NULL); if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL); + if (priv->mock) g_object_get(priv->mock, "is_started", &mock_started, NULL); - if ((gps_started == TRUE) || (wps_started == TRUE)) { + if ((gps_started == TRUE) || (wps_started == TRUE) || (mock_started == TRUE)) { LOCATION_LOGD("Already started"); return LOCATION_ERROR_NONE; } if (priv->gps) ret_gps = location_start(priv->gps); if (priv->wps) ret_wps = location_start(priv->wps); + if (priv->mock) ret_mock = location_start(priv->mock); - if ((ret_gps != LOCATION_ERROR_NONE) && (ret_wps != LOCATION_ERROR_NONE)) { - LOCATION_LOGD("ret_gps = %d, ret_wps = %d", ret_gps, ret_wps); - if (ret_gps == LOCATION_ERROR_SECURITY_DENIED || ret_wps == LOCATION_ERROR_SECURITY_DENIED) { + if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE && ret_mock != LOCATION_ERROR_NONE) { + LOCATION_LOGD("ret_gps = %d, ret_wps = %d, ret_mock = %d", ret_gps, ret_wps, ret_mock); + if (ret_gps == LOCATION_ERROR_SECURITY_DENIED || ret_wps == LOCATION_ERROR_SECURITY_DENIED || ret_mock == LOCATION_ERROR_SECURITY_DENIED) { return LOCATION_ERROR_SECURITY_DENIED; - } else if (ret_gps == LOCATION_ERROR_SETTING_OFF || ret_wps == LOCATION_ERROR_SETTING_OFF) { + } else if (ret_gps == LOCATION_ERROR_SETTING_OFF || ret_wps == LOCATION_ERROR_SETTING_OFF || ret_mock == LOCATION_ERROR_SETTING_OFF) { return LOCATION_ERROR_SETTING_OFF; - } else if (ret_gps == LOCATION_ERROR_NOT_ALLOWED || ret_wps == LOCATION_ERROR_NOT_ALLOWED) { + } else if (ret_gps == LOCATION_ERROR_NOT_ALLOWED || ret_wps == LOCATION_ERROR_NOT_ALLOWED || ret_mock == LOCATION_ERROR_NOT_ALLOWED) { return LOCATION_ERROR_NOT_ALLOWED; } else { return LOCATION_ERROR_NOT_AVAILABLE; @@ -526,20 +631,24 @@ location_hybrid_stop(LocationHybrid *self) int ret_gps = LOCATION_ERROR_NOT_AVAILABLE; int ret_wps = LOCATION_ERROR_NOT_AVAILABLE; + int ret_mock = LOCATION_ERROR_NOT_AVAILABLE; gboolean gps_started = FALSE; gboolean wps_started = FALSE; + gboolean mock_started = FALSE; - g_object_get(priv->gps, "is_started", &gps_started, NULL); + if (priv->gps) g_object_get(priv->gps, "is_started", &gps_started, NULL); if (priv->wps) g_object_get(priv->wps, "is_started", &wps_started, NULL); + if (priv->mock) g_object_get(priv->mock, "is_started", &mock_started, NULL); - if ((gps_started == FALSE) && (wps_started == FALSE)) { + if ((gps_started == FALSE) && (wps_started == FALSE) && (mock_started == FALSE)) { return LOCATION_ERROR_NONE; } if (priv->gps) ret_gps = location_stop(priv->gps); if (priv->wps) ret_wps = location_stop(priv->wps); + if (priv->mock) ret_mock = location_stop(priv->mock); - if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE) + if (ret_gps != LOCATION_ERROR_NONE && ret_wps != LOCATION_ERROR_NONE && ret_mock != LOCATION_ERROR_NONE) return LOCATION_ERROR_NOT_AVAILABLE; if (priv->pos_timer) g_source_remove(priv->pos_timer); @@ -552,6 +661,10 @@ location_hybrid_stop(LocationHybrid *self) priv->set_noti = FALSE; } + priv->gps_enabled = FALSE; + priv->wps_enabled = FALSE; + priv->mock_enabled = FALSE; + return LOCATION_ERROR_NONE; } @@ -585,6 +698,7 @@ location_hybrid_finalize(GObject *gobject) if (priv->gps) { g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_enabled), gobject); g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_disabled), gobject); + /* g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_status_changed), gobject); */ g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_service_updated), gobject); g_signal_handlers_disconnect_by_func(priv->gps, G_CALLBACK(hybrid_location_updated), gobject); location_free(priv->gps); @@ -592,11 +706,21 @@ location_hybrid_finalize(GObject *gobject) if (priv->wps) { g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_enabled), gobject); g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_disabled), gobject); + /* g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_status_changed), gobject); */ g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_service_updated), gobject); g_signal_handlers_disconnect_by_func(priv->wps, G_CALLBACK(hybrid_location_updated), gobject); location_free(priv->wps); } + if (priv->mock) { + g_signal_handlers_disconnect_by_func(priv->mock, G_CALLBACK(hybrid_service_enabled), gobject); + g_signal_handlers_disconnect_by_func(priv->mock, G_CALLBACK(hybrid_service_disabled), gobject); + /* g_signal_handlers_disconnect_by_func(priv->mock, G_CALLBACK(hybrid_status_changed), gobject); */ + g_signal_handlers_disconnect_by_func(priv->mock, G_CALLBACK(hybrid_service_updated), gobject); + g_signal_handlers_disconnect_by_func(priv->mock, G_CALLBACK(hybrid_location_updated), gobject); + location_free(priv->mock); + } + if (priv->boundary_list) { g_list_free_full(priv->boundary_list, free_boundary_list); priv->boundary_list = NULL; @@ -807,6 +931,9 @@ location_hybrid_get_property(GObject *object, case PROP_MIN_DISTANCE: g_value_set_double(value, priv->min_distance); break; + case PROP_SERVICE_STATUS: + g_value_set_int(value, priv->enabled); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -921,17 +1048,25 @@ location_hybrid_get_last_position_ext(LocationHybrid *self, LOCATION_LOGD("location_hybrid_get_last_position_ext"); int ret = LOCATION_ERROR_NONE; - LocationPosition *gps_pos = NULL, *wps_pos = NULL; - LocationVelocity *gps_vel = NULL, *wps_vel = NULL; - LocationAccuracy *gps_acc = NULL, *wps_acc = NULL; + LocationPosition *gps_pos = NULL, *wps_pos = NULL, *mock_pos = NULL; + LocationVelocity *gps_vel = NULL, *wps_vel = NULL, *mock_vel = NULL; + LocationAccuracy *gps_acc = NULL, *wps_acc = NULL, *mock_acc = NULL; LocationHybridPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); if (priv->gps) location_get_last_position_ext(priv->gps, &gps_pos, &gps_vel, &gps_acc); if (priv->wps) location_get_last_position_ext(priv->wps, &wps_pos, &wps_vel, &wps_acc); + if (priv->mock) location_get_last_position_ext(priv->mock, &mock_pos, &mock_vel, &mock_acc); if (gps_pos && wps_pos && gps_vel && wps_vel) { - if (wps_pos->timestamp > gps_pos->timestamp) { + if (mock_pos && mock_vel && mock_pos->timestamp > gps_pos->timestamp) { + *position = mock_pos; + *velocity = mock_vel; + *accuracy = mock_acc; + location_position_free(mock_pos); + location_velocity_free(mock_vel); + location_accuracy_free(mock_acc); + } else if (wps_pos->timestamp > gps_pos->timestamp) { *position = wps_pos; *velocity = wps_vel; *accuracy = wps_acc; @@ -951,9 +1086,9 @@ location_hybrid_get_last_position_ext(LocationHybrid *self, *velocity = gps_vel; *accuracy = gps_acc; } else if (wps_pos && wps_vel) { - *position = wps_pos; - *velocity = wps_vel; - *accuracy = wps_acc; + *position = mock_pos; + *velocity = mock_vel; + *accuracy = mock_acc; } else { ret = LOCATION_ERROR_NOT_AVAILABLE; } @@ -997,14 +1132,20 @@ location_hybrid_get_last_velocity(LocationHybrid *self, int ret = LOCATION_ERROR_NONE; LocationHybridPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); - LocationVelocity *gps_vel = NULL, *wps_vel = NULL; - LocationAccuracy *gps_acc = NULL, *wps_acc = NULL; + LocationVelocity *gps_vel = NULL, *wps_vel = NULL, *mock_vel = NULL; + LocationAccuracy *gps_acc = NULL, *wps_acc = NULL, *mock_acc = NULL; if (priv->gps) location_get_last_velocity(priv->gps, &gps_vel, &gps_acc); if (priv->wps) location_get_last_velocity(priv->wps, &wps_vel, &wps_acc); + if (priv->mock) location_get_last_velocity(priv->mock, &mock_vel, &mock_acc); if (gps_vel && wps_vel) { - if (wps_vel->timestamp > gps_vel->timestamp) { + if (mock_vel && mock_vel->timestamp > gps_vel->timestamp) { + *velocity = mock_vel; + *accuracy = mock_acc; + location_velocity_free(mock_vel); + location_accuracy_free(mock_acc); + } else if (wps_vel->timestamp > gps_vel->timestamp) { *velocity = wps_vel; *accuracy = wps_acc; location_velocity_free(gps_vel); @@ -1021,6 +1162,9 @@ location_hybrid_get_last_velocity(LocationHybrid *self, } else if (wps_vel) { *velocity = wps_vel; *accuracy = wps_acc; + } else if (mock_vel) { + *velocity = mock_vel; + *accuracy = mock_acc; } else { *velocity = NULL; *accuracy = NULL; @@ -1096,12 +1240,14 @@ location_hybrid_request_single_location(LocationHybrid *self, int timeout) LocationHybridPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); - int ret = LOCATION_ERROR_NONE; + int ret = LOCATION_ERROR_NOT_AVAILABLE; if (priv->gps) { ret = location_request_single_location(priv->gps, timeout); - } else { + } else if (priv->wps) { ret = location_request_single_location(priv->wps, timeout); + } else if (priv->mock) { + ret = location_request_single_location(priv->mock, timeout); } return ret; @@ -1125,6 +1271,49 @@ location_hybrid_get_nmea(LocationHybrid *self, return LOCATION_ERROR_NONE; } +/* + * Tizen 3.0 + */ +static int +location_hybrid_set_mock_location(LocationMock *self, + LocationPosition *position, + LocationVelocity *velocity, + LocationAccuracy *accuracy) +{ + LocationHybridPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + + int ret = LOCATION_ERROR_NONE; + + if (!priv->mock) { + LOCATION_LOGE("MOCK Object is not created."); + return LOCATION_ERROR_NOT_AVAILABLE; + } + + if (priv->mock) ret = location_set_mock_location(priv->mock, position, velocity, accuracy); + if (ret != LOCATION_ERROR_NONE) LOCATION_LOGD("ret = %d", ret); + + return ret; +} + +static int +location_hybrid_clear_mock_location(LocationMock *self) +{ + LocationHybridPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + + int ret = LOCATION_ERROR_NONE; + + if (!priv->mock) { + LOCATION_LOGE("MOCK Object is not created."); + return LOCATION_ERROR_NOT_AVAILABLE; + } + + if (priv->mock) ret = location_clear_mock_location(priv->mock); + if (ret != LOCATION_ERROR_NONE) LOCATION_LOGD("ret = %d", ret); + + return ret; +} static void location_ielement_interface_init(LocationIElementInterface *iface) @@ -1142,6 +1331,9 @@ location_ielement_interface_init(LocationIElementInterface *iface) iface->set_option = (TYPE_SET_OPTION)location_hybrid_set_option; iface->request_single_location = (TYPE_REQUEST_SINGLE_LOCATION)location_hybrid_request_single_location; iface->get_nmea = (TYPE_GET_NMEA)location_hybrid_get_nmea; + + iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_hybrid_set_mock_location; + iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_hybrid_clear_mock_location; } static void @@ -1174,19 +1366,29 @@ location_hybrid_init(LocationHybrid *self) if (location_is_supported_method(LOCATION_METHOD_GPS)) priv->gps = location_new(LOCATION_METHOD_GPS); if (location_is_supported_method(LOCATION_METHOD_WPS)) priv->wps = location_new(LOCATION_METHOD_WPS); + if (location_is_supported_method(LOCATION_METHOD_MOCK)) priv->mock = location_new(LOCATION_METHOD_MOCK); if (priv->gps) { g_signal_connect(priv->gps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self); g_signal_connect(priv->gps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self); + /* g_signal_connect(priv->gps, "status-changed", G_CALLBACK(hybrid_status_changed), self); */ g_signal_connect(priv->gps, "service-updated", G_CALLBACK(hybrid_service_updated), self); g_signal_connect(priv->gps, "location-updated", G_CALLBACK(hybrid_location_updated), self); } if (priv->wps) { g_signal_connect(priv->wps, "service-enabled", G_CALLBACK(hybrid_service_enabled), self); g_signal_connect(priv->wps, "service-disabled", G_CALLBACK(hybrid_service_disabled), self); + /* g_signal_connect(priv->wps, "status-changed", G_CALLBACK(hybrid_status_changed), self); */ g_signal_connect(priv->wps, "service-updated", G_CALLBACK(hybrid_service_updated), self); g_signal_connect(priv->wps, "location-updated", G_CALLBACK(hybrid_location_updated), self); } + if (priv->mock) { + g_signal_connect(priv->mock, "service-enabled", G_CALLBACK(hybrid_service_enabled), self); + g_signal_connect(priv->mock, "service-disabled", G_CALLBACK(hybrid_service_disabled), self); + /* g_signal_connect(priv->mock, "status-changed", G_CALLBACK(hybrid_status_changed), self); */ + g_signal_connect(priv->mock, "service-updated", G_CALLBACK(hybrid_service_updated), self); + g_signal_connect(priv->mock, "location-updated", G_CALLBACK(hybrid_location_updated), self); + } hybrid_set_current_method(priv, LOCATION_TYPE_HYBRID); priv->enabled = FALSE; @@ -1233,11 +1435,23 @@ location_hybrid_class_init(LocationHybridClass *klass) G_TYPE_NONE, 1, G_TYPE_UINT); +#if 0 /* TODO: STATUS_CHANGED will aggregate SERVICE_ENABLED and SERVICE_DISABLED */ + signals[STATUS_CHANGED] = g_signal_new("status-changed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationHybridClass, status_changed), + NULL, NULL, + location_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); +#endif + signals[SERVICE_UPDATED] = g_signal_new("service-updated", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET(LocationHybridClass, updated), + G_STRUCT_OFFSET(LocationHybridClass, service_updated), NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER, G_TYPE_NONE, 4, @@ -1354,6 +1568,15 @@ location_hybrid_class_init(LocationHybridClass *klass) LOCATION_TYPE_BOUNDARY, G_PARAM_READWRITE); + /* Tizen 3.0 */ + properties[PROP_SERVICE_STATUS] = g_param_spec_int("service-status", + "location service status prop", + "location service status data", + LOCATION_STATUS_NO_FIX, + LOCATION_STATUS_3D_FIX, + LOCATION_STATUS_NO_FIX, + G_PARAM_READABLE); + g_object_class_install_properties(gobject_class, PROP_MAX, properties); diff --git a/location/manager/location-hybrid.h b/location/manager/location-hybrid.h index 5b49905..2fd530b 100644 --- a/location/manager/location-hybrid.h +++ b/location/manager/location-hybrid.h @@ -50,10 +50,11 @@ struct _LocationHybridClass { void (* enabled)(guint type); void (* disabled)(guint type); - void (* updated)(gint type, gpointer data, gpointer velocity, gpointer accuracy); + void (* service_updated)(gint type, gpointer data, gpointer velocity, gpointer accuracy); void (* location_updated)(gint error, gpointer position, gpointer velocity, gpointer accuracy); void (* zone_in)(gpointer boundary, gpointer position, gpointer accuracy); void (* zone_out)(gpointer boundary, gpointer position, gpointer accuracy); + void (* status_changed)(guint type); }; GType location_hybrid_get_type(void); diff --git a/location/manager/location-ielement.c b/location/manager/location-ielement.c old mode 100644 new mode 100755 index 8623613..21e8c2f --- a/location/manager/location-ielement.c +++ b/location/manager/location-ielement.c @@ -242,3 +242,37 @@ location_ielement_get_nmea(LocationIElement *self, return LOCATION_IELEMENT_GET_INTERFACE(self)->get_nmea(self, nmea); } + + +/* Tizen 3.0 */ + +int location_ielement_get_status(LocationIElement *self, int *state) +{ + g_return_val_if_fail(LOCATION_IS_IELEMENT(self), LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(LOCATION_IELEMENT_GET_INTERFACE(self), LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(LOCATION_IELEMENT_GET_INTERFACE(self)->get_status, LOCATION_ERROR_NOT_AVAILABLE); + + return LOCATION_IELEMENT_GET_INTERFACE(self)->get_status(self, state); +} + +int location_ielement_set_mock_location(LocationIElement *self, const LocationPosition *position, const LocationVelocity *velocity, const LocationAccuracy *accuracy) +{ + g_return_val_if_fail(LOCATION_IS_IELEMENT(self), LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(LOCATION_IELEMENT_GET_INTERFACE(self), LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(LOCATION_IELEMENT_GET_INTERFACE(self)->set_mock_location, LOCATION_ERROR_NOT_AVAILABLE); + + return LOCATION_IELEMENT_GET_INTERFACE(self)->set_mock_location(self, position, velocity, accuracy); +} + +int location_ielement_clear_mock_location(LocationIElement *self) +{ + g_return_val_if_fail(LOCATION_IS_IELEMENT(self), LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(LOCATION_IELEMENT_GET_INTERFACE(self), LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(LOCATION_IELEMENT_GET_INTERFACE(self)->clear_mock_location, LOCATION_ERROR_NOT_AVAILABLE); + + return LOCATION_IELEMENT_GET_INTERFACE(self)->clear_mock_location(self); +} + diff --git a/location/manager/location-ielement.h b/location/manager/location-ielement.h index 3be425a..7c96bc0 100644 --- a/location/manager/location-ielement.h +++ b/location/manager/location-ielement.h @@ -54,6 +54,9 @@ enum { ZONE_OUT, LOCATION_UPDATED, BATCH_UPDATED, + MOCK_LOCATION_SET, + MOCK_LOCATION_FAIL, + STATUS_CHANGED, LAST_SIGNAL, }; @@ -70,6 +73,10 @@ typedef int (*TYPE_START_BATCH)(LocationIElement *self); typedef int (*TYPE_STOP_BATCH)(LocationIElement *self); typedef int (*TYPE_GET_NMEA)(LocationIElement *self, char **nmea); +/* Tizen 3.0 */ +typedef int (*TYPE_GET_STATUS)(LocationIElement *self, int *status); +typedef int (*TYPE_SET_MOCK_LOCATION)(LocationIElement *self, const LocationPosition *position, const LocationVelocity *velocity, const LocationAccuracy *accuracy); +typedef int (*TYPE_CLEAR_MOCK_LOCATION)(LocationIElement *self); struct _LocationIElementInterface { GTypeInterface parent_iface; @@ -90,6 +97,11 @@ struct _LocationIElementInterface { TYPE_START_BATCH start_batch; TYPE_STOP_BATCH stop_batch; TYPE_GET_NMEA get_nmea; + + /* Tizen 3.0 */ + TYPE_GET_STATUS get_status; + TYPE_SET_MOCK_LOCATION set_mock_location; + TYPE_CLEAR_MOCK_LOCATION clear_mock_location; }; GType location_ielement_get_type(void); @@ -111,6 +123,10 @@ int location_ielement_start_batch(LocationIElement *self); int location_ielement_stop_batch(LocationIElement *self); int location_ielement_get_nmea(LocationIElement *self, char **nmea); +/* Tizen 3.0 */ +int location_ielement_get_status(LocationIElement *self, int *state); +int location_ielement_set_mock_location(LocationIElement *self, const LocationPosition *position, const LocationVelocity *velocity, const LocationAccuracy *accuracy); +int location_ielement_clear_mock_location(LocationIElement *self); G_END_DECLS diff --git a/location/manager/location-mock.c b/location/manager/location-mock.c new file mode 100755 index 0000000..82fd017 --- /dev/null +++ b/location/manager/location-mock.c @@ -0,0 +1,1091 @@ +/* + * libslp-location + * + * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "location-setting.h" +#include "location-log.h" + +#include "module-internal.h" + +#include "location-mock.h" +#include "location-marshal.h" +#include "location-ielement.h" +#include "location-signaling-util.h" +#include "location-common-util.h" +#include "location-privacy.h" + +#include + +/* + * forward definitions + */ + +typedef struct _LocationMockPrivate { + LocationMockMod *mod; + GMutex mutex; + gboolean is_started; + guint app_type; + gboolean set_noti; + gboolean enabled; + guint pos_updated_timestamp; + guint pos_interval; + guint vel_updated_timestamp; + guint vel_interval; + guint loc_updated_timestamp; + guint loc_interval; + guint loc_timeout; + guint dist_updated_timestamp; + guint min_interval; + gdouble min_distance; + LocationPosition *pos; + LocationVelocity *vel; + LocationAccuracy *acc; + GList *boundary_list; +} LocationMockPrivate; + +enum { + PROP_0, + PROP_METHOD_TYPE, + PROP_IS_STARTED, + PROP_LAST_POSITION, + PROP_POS_INTERVAL, + PROP_VEL_INTERVAL, + PROP_LOC_INTERVAL, + PROP_BOUNDARY, + PROP_REMOVAL_BOUNDARY, + PROP_MIN_INTERVAL, + PROP_MIN_DISTANCE, + PROP_SERVICE_STATUS, + PROP_MAX +}; + +static guint32 signals[LAST_SIGNAL] = {0, }; +static GParamSpec *properties[PROP_MAX] = {NULL, }; + +#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), LOCATION_TYPE_MOCK, LocationMockPrivate)) + +static void location_ielement_interface_init(LocationIElementInterface *iface); + +G_DEFINE_TYPE_WITH_CODE(LocationMock, location_mock, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(LOCATION_TYPE_IELEMENT, + location_ielement_interface_init)); + +static void +__reset_pos_data_from_priv(LocationMockPrivate *priv) +{ + LOCATION_LOGD("__reset_pos_data_from_priv"); + g_return_if_fail(priv); + + if (priv->pos) { + location_position_free(priv->pos); + priv->pos = NULL; + } + if (priv->vel) { + location_velocity_free(priv->vel); + priv->vel = NULL; + } + if (priv->acc) { + location_accuracy_free(priv->acc); + priv->acc = NULL; + } + priv->pos_updated_timestamp = 0; + priv->vel_updated_timestamp = 0; +} + +static gboolean +__get_started(gpointer self) +{ + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, FALSE); + + return priv->is_started; +} + +static int +__set_started(gpointer self, gboolean started) +{ + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, -1); + + if (priv->is_started != started) { + g_mutex_lock(&priv->mutex); + priv->is_started = started; + g_mutex_unlock(&priv->mutex); + } + + return 0; +} + +static void +mock_status_cb(gboolean enabled, + LocationStatus status, + gpointer self) +{ + LOCATION_LOGD("mock_status_cb"); + g_return_if_fail(self); + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_if_fail(priv); + if (priv->enabled == TRUE && enabled == FALSE) { + __set_started(self, FALSE); + enable_signaling(self, signals, &(priv->enabled), enabled, status); + } +} + +static void +mock_location_cb(gboolean enabled, + LocationPosition *pos, + LocationVelocity *vel, + LocationAccuracy *acc, + gpointer self) +{ + g_return_if_fail(self); + g_return_if_fail(pos); + g_return_if_fail(vel); + g_return_if_fail(acc); + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_if_fail(priv); + + if (priv->min_interval != LOCATION_UPDATE_INTERVAL_NONE) { + distance_based_position_signaling(self, + signals, + enabled, + pos, + vel, + acc, + priv->min_interval, + priv->min_distance, + &(priv->enabled), + &(priv->dist_updated_timestamp), + &(priv->pos), + &(priv->vel), + &(priv->acc)); + } + + LOCATION_LOGD("Calling location_signaling, status =%d", pos->status); + + location_signaling(self, + signals, + enabled, + priv->boundary_list, + pos, + vel, + acc, + priv->pos_interval, + priv->vel_interval, + priv->loc_interval, + &(priv->enabled), + &(priv->pos_updated_timestamp), + &(priv->vel_updated_timestamp), + &(priv->loc_updated_timestamp), + &(priv->pos), + &(priv->vel), + &(priv->acc)); +} + +static void +location_setting_mock_cb(keynode_t *key, + gpointer self) +{ + LOCATION_LOGD("location_setting_mock_cb"); + g_return_if_fail(key); + g_return_if_fail(self); + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_if_fail(priv); + g_return_if_fail(priv->mod); + g_return_if_fail(priv->mod->handler); + + int ret = LOCATION_ERROR_NONE; + + if (location_setting_get_key_val(key) == 0) { + if (priv->mod->ops.stop && __get_started(self)) { + __set_started(self, FALSE); + ret = priv->mod->ops.stop(priv->mod->handler); + if (ret == LOCATION_ERROR_NONE) { + __reset_pos_data_from_priv(priv); + } + } + } else { + if (location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED) == 1 && priv->mod->ops.start && !__get_started(self)) { + LOCATION_LOGD("location resumed by setting"); + __set_started(self, TRUE); + ret = priv->mod->ops.start(priv->mod->handler, mock_status_cb, mock_location_cb, self); + if (ret != LOCATION_ERROR_NONE) { + __set_started(self, FALSE); + LOCATION_LOGD("Fail to start. Error[%d]", ret); + } + } + } + +} + +static int +location_mock_start(LocationMock *self) +{ + LOCATION_LOGD("ENTER >>>"); + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE); + + if (__get_started(self) == TRUE) return LOCATION_ERROR_NONE; + + int ret = LOCATION_ERROR_NONE; + + if (!location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED)) { + ret = LOCATION_ERROR_SETTING_OFF; + } else { + __set_started(self, TRUE); + ret = priv->mod->ops.start(priv->mod->handler, mock_status_cb, mock_location_cb, self); + if (ret != LOCATION_ERROR_NONE) { + __set_started(self, FALSE); + LOCATION_LOGE("Failed to start mock. Error[%d]", ret); + return ret; + } + } + + if (priv->app_type != CPPAPP && priv->set_noti == FALSE) { + location_setting_add_notify(VCONFKEY_LOCATION_MOCK_ENABLED, location_setting_mock_cb, self); + priv->set_noti = TRUE; + } + LOCATION_LOGD("EXIT <<<, ret = %d", ret); + + return ret; +} + +static int +location_mock_stop(LocationMock *self) +{ + LOCATION_LOGD("location_mock_stop"); + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->ops.stop, LOCATION_ERROR_NOT_AVAILABLE); + + int ret = LOCATION_ERROR_NONE; + + if (__get_started(self) == TRUE) { + __set_started(self, FALSE); + ret = priv->mod->ops.stop(priv->mod->handler); + if (ret != LOCATION_ERROR_NONE) { + LOCATION_LOGD("Failed to stop. Error[%d]", ret); + } + } + + if (priv->app_type != CPPAPP && priv->set_noti == TRUE) { + location_setting_ignore_notify(VCONFKEY_LOCATION_MOCK_ENABLED, location_setting_mock_cb); + priv->set_noti = FALSE; + } + + __reset_pos_data_from_priv(priv); + + return ret; +} + +static void +location_mock_dispose(GObject *gobject) +{ + LOCATION_LOGD("location_mock_dispose"); + + LocationMockPrivate *priv = GET_PRIVATE(gobject); + g_return_if_fail(priv); + + g_mutex_clear(&priv->mutex); + if (priv->app_type != CPPAPP && priv->set_noti == TRUE) { + location_setting_ignore_notify(VCONFKEY_LOCATION_MOCK_ENABLED, location_setting_mock_cb); + priv->set_noti = FALSE; + + } + + G_OBJECT_CLASS(location_mock_parent_class)->dispose(gobject); +} + +static void +location_mock_finalize(GObject *gobject) +{ + LOCATION_LOGD("location_mock_finalize"); + LocationMockPrivate *priv = GET_PRIVATE(gobject); + g_return_if_fail(priv); + module_free(priv->mod, "mock"); + + if (priv->boundary_list) { + g_list_free_full(priv->boundary_list, free_boundary_list); + priv->boundary_list = NULL; + } + + if (priv->pos) { + location_position_free(priv->pos); + priv->pos = NULL; + } + + if (priv->vel) { + location_velocity_free(priv->vel); + priv->vel = NULL; + } + + if (priv->acc) { + location_accuracy_free(priv->acc); + priv->acc = NULL; + } + + G_OBJECT_CLASS(location_mock_parent_class)->finalize(gobject); +} + +static void +location_mock_set_property(GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + LocationMockPrivate *priv = GET_PRIVATE(object); + g_return_if_fail(priv); + int ret = 0; + + switch (property_id) { + case PROP_BOUNDARY: { + GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value)); + ret = set_prop_boundary(&priv->boundary_list, boundary_list); + if (ret != LOCATION_ERROR_NONE) LOCATION_LOGE("Set boundary. Error[%d]", ret); + if (boundary_list) g_list_free(boundary_list); + break; + } + case PROP_REMOVAL_BOUNDARY: { + LocationBoundary *req_boundary = (LocationBoundary *) g_value_dup_boxed(value); + ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary); + if (ret != 0) LOCATION_LOGD("Set removal boundary. Error[%d]", ret); + break; + } + case PROP_POS_INTERVAL: { + guint interval = g_value_get_uint(value); + if (interval > 0) { + if (interval < LOCATION_UPDATE_INTERVAL_MAX) + priv->pos_interval = interval; + else + priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX; + } else + priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT; + + break; + } + case PROP_VEL_INTERVAL: { + guint interval = g_value_get_uint(value); + if (interval > 0) { + if (interval < LOCATION_UPDATE_INTERVAL_MAX) + priv->vel_interval = interval; + else + priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX; + } else { + priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT; + } + break; + } + case PROP_LOC_INTERVAL: { + guint interval = g_value_get_uint(value); + LOCATION_LOGD("Set prop>> PROP_LOC_INTERVAL: %u", interval); + if (interval > 0) { + if (interval < LOCATION_UPDATE_INTERVAL_MAX) + priv->loc_interval = interval; + else + priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX; + } else + priv->loc_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT; + + break; + } + case PROP_MIN_INTERVAL: { + guint interval = g_value_get_uint(value); + LOCATION_LOGD("Set prop>> update-min-interval: %u", interval); + if (interval > 0) { + if (interval < LOCATION_MIN_INTERVAL_MAX) + priv->min_interval = interval; + else + priv->min_interval = (guint)LOCATION_MIN_INTERVAL_MAX; + } else + priv->min_interval = (guint)LOCATION_MIN_INTERVAL_DEFAULT; + + break; + } + case PROP_MIN_DISTANCE: { + gdouble distance = g_value_get_double(value); + LOCATION_LOGD("Set prop>> update-min-distance: %u", distance); + if (distance > 0) { + if (distance < LOCATION_MIN_DISTANCE_MAX) + priv->min_distance = distance; + else + priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_MAX; + } else + priv->min_distance = (gdouble)LOCATION_MIN_DISTANCE_DEFAULT; + + break; + } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void +location_mock_get_property(GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + LocationMockPrivate *priv = GET_PRIVATE(object); + g_return_if_fail(priv); + + switch (property_id) { + case PROP_METHOD_TYPE: + g_value_set_int(value, LOCATION_METHOD_MOCK); + break; + case PROP_IS_STARTED: + g_value_set_boolean(value, __get_started(object)); + break; + case PROP_LAST_POSITION: + g_value_set_boxed(value, priv->pos); + break; + case PROP_BOUNDARY: + g_value_set_pointer(value, g_list_first(priv->boundary_list)); + break; + case PROP_POS_INTERVAL: + g_value_set_uint(value, priv->pos_interval); + break; + case PROP_VEL_INTERVAL: + g_value_set_uint(value, priv->vel_interval); + break; + case PROP_LOC_INTERVAL: + g_value_set_uint(value, priv->loc_interval); + break; + case PROP_MIN_INTERVAL: + g_value_set_uint(value, priv->min_interval); + break; + case PROP_MIN_DISTANCE: + g_value_set_double(value, priv->min_distance); + break; + case PROP_SERVICE_STATUS: + g_value_set_int(value, priv->enabled); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static int +location_mock_get_position(LocationMock *self, + LocationPosition **position, + LocationAccuracy **accuracy) +{ + int ret = LOCATION_ERROR_NOT_AVAILABLE; + + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + setting_retval_if_fail(VCONFKEY_LOCATION_MOCK_ENABLED); + + if (__get_started(self) != TRUE) { + LOCATION_LOGE("location is not started"); + return LOCATION_ERROR_NOT_AVAILABLE; + } + + if (priv->pos) { + *position = location_position_copy(priv->pos); + if (priv->acc) *accuracy = location_accuracy_copy(priv->acc); + else *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0); + ret = LOCATION_ERROR_NONE; + } + + return ret; +} + +static int +location_mock_get_position_ext(LocationMock *self, + LocationPosition **position, + LocationVelocity **velocity, + LocationAccuracy **accuracy) +{ + int ret = LOCATION_ERROR_NOT_AVAILABLE; + + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + setting_retval_if_fail(VCONFKEY_LOCATION_MOCK_ENABLED); + + if (__get_started(self) != TRUE) { + LOCATION_LOGE("location is not started"); + return LOCATION_ERROR_NOT_AVAILABLE; + } + + if (priv->pos && priv->vel) { + *position = location_position_copy(priv->pos); + *velocity = location_velocity_copy(priv->vel); + if (priv->acc) *accuracy = location_accuracy_copy(priv->acc); + else *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0); + ret = LOCATION_ERROR_NONE; + } + + return ret; +} + + +static int +location_mock_get_last_position(LocationMock *self, + LocationPosition **position, + LocationAccuracy **accuracy) +{ + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + setting_retval_if_fail(VCONFKEY_LOCATION_MOCK_ENABLED); + + int ret = LOCATION_ERROR_NONE; + LocationVelocity *_velocity = NULL; + + LocModMockOps ops = priv->mod->ops; + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE); + + ret = ops.get_last_position(priv->mod->handler, position, &_velocity, accuracy); + if (_velocity) location_velocity_free(_velocity); + + return ret; +} + +static int +location_mock_get_last_position_ext(LocationMock *self, + LocationPosition **position, + LocationVelocity **velocity, + LocationAccuracy **accuracy) +{ + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + setting_retval_if_fail(VCONFKEY_LOCATION_MOCK_ENABLED); + + LocModMockOps ops = priv->mod->ops; + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE); + + return ops.get_last_position(priv->mod->handler, position, velocity, accuracy); +} + + +static int +location_mock_get_velocity(LocationMock *self, + LocationVelocity **velocity, + LocationAccuracy **accuracy) +{ + int ret = LOCATION_ERROR_NOT_AVAILABLE; + + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + setting_retval_if_fail(VCONFKEY_LOCATION_MOCK_ENABLED); + + if (__get_started(self) != TRUE) { + LOCATION_LOGE("location is not started"); + return LOCATION_ERROR_NOT_AVAILABLE; + } + + if (priv->vel) { + *velocity = location_velocity_copy(priv->vel); + if (priv->acc) *accuracy = location_accuracy_copy(priv->acc); + else *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0); + ret = LOCATION_ERROR_NONE; + } + + return ret; +} + +static int +location_mock_get_last_velocity(LocationMock *self, + LocationVelocity **velocity, + LocationAccuracy **accuracy) +{ + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + setting_retval_if_fail(VCONFKEY_LOCATION_MOCK_ENABLED); + + int ret = LOCATION_ERROR_NONE; + LocationPosition *_position = NULL; + + LocModMockOps ops = priv->mod->ops; + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + ret = ops.get_last_position(priv->mod->handler, &_position, velocity, accuracy); + if (!_position) location_position_free(_position); + + return ret; +} + +static gboolean __single_location_timeout_cb(void *data) +{ + LOCATION_LOGD("__single_location_timeout_cb"); + LocationMock *self = (LocationMock *)data; + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, FALSE); + + LocationPosition *pos = location_position_new(0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX); + LocationVelocity *vel = location_velocity_new(0, 0.0, 0.0, 0.0); + LocationAccuracy *acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0); + + if (priv->loc_timeout) g_source_remove(priv->loc_timeout); + priv->loc_timeout = 0; + + g_signal_emit(self, signals[LOCATION_UPDATED], 0, LOCATION_ERROR_NOT_AVAILABLE, pos, vel, acc); + location_mock_stop(self); + + return FALSE; +} + + +static void +mock_single_location_cb(gboolean enabled, + LocationPosition *pos, + LocationVelocity *vel, + LocationAccuracy *acc, + gpointer self) +{ + LOCATION_LOGD("mock_single_location_cb"); + g_return_if_fail(self); + g_return_if_fail(pos); + g_return_if_fail(vel); + g_return_if_fail(acc); + + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_if_fail(priv); + + g_signal_emit(self, signals[LOCATION_UPDATED], 0, LOCATION_ERROR_NONE, pos, vel, acc); + if (priv->loc_timeout) { + g_source_remove(priv->loc_timeout); + priv->loc_timeout = 0; + } + location_mock_stop(self); +} + +static int +location_mock_request_single_location(LocationMock *self, int timeout) +{ + LOCATION_LOGD("location_mock_request_single_location"); + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE); + + if (__get_started(self) == TRUE) return LOCATION_ERROR_NONE; + + int ret = LOCATION_ERROR_NONE; + + __set_started(self, TRUE); + ret = priv->mod->ops.start(priv->mod->handler, mock_status_cb, mock_single_location_cb, self); + if (ret != LOCATION_ERROR_NONE) { + LOCATION_LOGE("Fail to start request single. Error[%d]", ret); + __set_started(self, FALSE); + return ret; + } else { + if (priv->loc_timeout != 0) { + g_source_remove(priv->loc_timeout); + } + priv->loc_timeout = g_timeout_add_seconds(timeout, __single_location_timeout_cb, self); + } + + return ret; +} + +static int +location_mock_get_satellite(LocationMock *self, + LocationSatellite **satellite) +{ + return LOCATION_ERROR_NOT_SUPPORTED; +} + +static int +location_mock_get_last_satellite(LocationMock *self, + LocationSatellite **satellite) +{ + return LOCATION_ERROR_NOT_SUPPORTED; +} + +static int +location_mock_set_option(LocationMock *self, const char *option) +{ + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE); + + int ret = LOCATION_ERROR_NONE; + + ret = priv->mod->ops.set_option(priv->mod->handler, option); + if (ret != LOCATION_ERROR_NONE) { + LOCATION_LOGE("Failed to set_option. Error[%d]", ret); + } + + return ret; +} + +static int +location_mock_get_nmea(LocationMock *self, + char **nmea_data) +{ + return LOCATION_ERROR_NOT_SUPPORTED; +} + + +/* Tizen 3.0 */ + +static int +location_mock_get_status(LocationMock *self, int *status) +{ + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + + if (__get_started(self) == TRUE) + *status = 1; + else + *status = 0; + + return LOCATION_ERROR_NONE; +} + + +static void +__set_mock_location_cb(gboolean enabled, + LocationStatus status, + gpointer self) +{ + g_return_if_fail(self); + LocationObject *obj = (LocationObject *) self; + LocationMockPrivate *priv = GET_PRIVATE(obj); + g_return_if_fail(priv); + + LOCATION_LOGD("ENTER >>>"); + LOCATION_LOGD("status = %d"); + if (status == LOCATION_STATUS_MOCK_FAIL) { + /* g_signal_emit(obj, signals[SERVICE_DISABLED], 0, LOCATION_STATUS_NO_FIX); */ + g_signal_emit(obj, signals[STATUS_CHANGED], 0, LOCATION_STATUS_MOCK_FAIL); + } + + LOCATION_LOGD("EXIT <<<"); +} + +static int +location_mock_set_mock_location(LocationMock *self, + LocationPosition *position, + LocationVelocity *velocity, + LocationAccuracy *accuracy) +{ + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->ops.set_mock_location, LOCATION_ERROR_NOT_AVAILABLE); + + LOCATION_LOGD("ENTER >>>"); + + int ret = LOCATION_ERROR_NONE; + + if (!location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED)) { + ret = LOCATION_ERROR_SETTING_OFF; + } else { + ret = priv->mod->ops.set_mock_location(priv->mod->handler, position, velocity, accuracy, __set_mock_location_cb, self); + if (ret != LOCATION_ERROR_NONE) { + LOCATION_LOGE("Failed to set_mock_location. Error[%d]", ret); + } + } + + LOCATION_LOGD("EXIT <<<"); + return ret; +} + +static int +location_mock_clear_mock_location(LocationMock *self) +{ + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(priv->mod->ops.set_mock_location, LOCATION_ERROR_NOT_AVAILABLE); + + LOCATION_LOGD("ENTER >>>"); + + int ret = LOCATION_ERROR_NONE; + + if (!location_setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED)) { + ret = LOCATION_ERROR_SETTING_OFF; + } else { + ret = priv->mod->ops.clear_mock_location(priv->mod->handler, __set_mock_location_cb, self); + if (ret != LOCATION_ERROR_NONE) { + LOCATION_LOGE("Failed to set_mock_location. Error[%d]", ret); + } + } + + LOCATION_LOGD("EXIT <<<"); + return ret; +} + +static void _glib_log(const gchar *log_domain, GLogLevelFlags log_level, + const gchar *msg, gpointer user_data) +{ + LOCATION_LOGD("GLIB[%d]: %s", log_level, msg); +} + + +static void +location_ielement_interface_init(LocationIElementInterface *iface) +{ + iface->start = (TYPE_START_FUNC)location_mock_start; + iface->stop = (TYPE_STOP_FUNC)location_mock_stop; + iface->get_position = (TYPE_GET_POSITION)location_mock_get_position; + iface->get_position_ext = (TYPE_GET_POSITION_EXT)location_mock_get_position_ext; + iface->get_last_position = (TYPE_GET_POSITION)location_mock_get_last_position; + iface->get_last_position_ext = (TYPE_GET_POSITION_EXT)location_mock_get_last_position_ext; + iface->get_velocity = (TYPE_GET_VELOCITY)location_mock_get_velocity; + iface->get_last_velocity = (TYPE_GET_VELOCITY)location_mock_get_last_velocity; + iface->get_satellite = (TYPE_GET_SATELLITE)location_mock_get_satellite; + iface->get_last_satellite = (TYPE_GET_SATELLITE)location_mock_get_last_satellite; + iface->set_option = (TYPE_SET_OPTION)location_mock_set_option; + iface->request_single_location = (TYPE_REQUEST_SINGLE_LOCATION)location_mock_request_single_location; + iface->get_nmea = (TYPE_GET_NMEA)location_mock_get_nmea; + + iface->get_status = (TYPE_GET_STATUS) location_mock_get_status; + iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_mock_set_mock_location; + iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_mock_clear_mock_location; +} + +static void +location_mock_init(LocationMock *self) +{ + LOCATION_LOGD("location_mock_init"); + LocationMockPrivate *priv = GET_PRIVATE(self); + g_return_if_fail(priv); + + priv->mod = (LocationMockMod *)module_new("mock"); + if (!priv->mod) LOCATION_LOGW("module loading failed"); + + g_mutex_init(&priv->mutex); + priv->is_started = FALSE; + priv->set_noti = FALSE; + priv->enabled = FALSE; + + priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT; + priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT; + priv->loc_interval = LOCATION_UPDATE_INTERVAL_DEFAULT; + priv->min_interval = LOCATION_UPDATE_INTERVAL_NONE; + + priv->pos_updated_timestamp = 0; + priv->vel_updated_timestamp = 0; + priv->loc_updated_timestamp = 0; + + priv->pos = NULL; + priv->vel = NULL; + priv->acc = NULL; + priv->boundary_list = NULL; + + priv->loc_timeout = 0; + + priv->app_type = location_get_app_type(NULL); + if (priv->app_type == 0) { + LOCATION_LOGW("Fail to get app_type"); + } +} + +static void +location_mock_class_init(LocationMockClass *klass) +{ + LOCATION_LOGD("location_mock_class_init"); + + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + + g_log_set_default_handler(_glib_log, NULL); + + + gobject_class->set_property = location_mock_set_property; + gobject_class->get_property = location_mock_get_property; + + gobject_class->dispose = location_mock_dispose; + gobject_class->finalize = location_mock_finalize; + + g_type_class_add_private(klass, sizeof(LocationMockPrivate)); + + + + signals[SERVICE_ENABLED] = g_signal_new("service-enabled", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationMockClass, enabled), + NULL, NULL, + location_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + + + signals[SERVICE_DISABLED] = g_signal_new("service-disabled", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationMockClass, disabled), + NULL, NULL, + location_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); + +#if 0 /* TODO: STATUS_CHANGED will aggregate SERVICE_ENABLED and SERVICE_DISABLED */ + signals[STATUS_CHANGED] = g_signal_new("status-changed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationMockClass, status_changed), + NULL, NULL, + location_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); +#endif + + signals[SERVICE_UPDATED] = g_signal_new("service-updated", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationMockClass, service_updated), + NULL, NULL, + location_VOID__INT_POINTER_POINTER_POINTER, + G_TYPE_NONE, 4, + G_TYPE_INT, + G_TYPE_POINTER, + G_TYPE_POINTER, + G_TYPE_POINTER); + + signals[LOCATION_UPDATED] = g_signal_new("location-updated", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationMockClass, location_updated), + NULL, NULL, + location_VOID__INT_POINTER_POINTER_POINTER, + G_TYPE_NONE, 4, + G_TYPE_INT, + G_TYPE_POINTER, + G_TYPE_POINTER, + G_TYPE_POINTER); + + signals[ZONE_IN] = g_signal_new("zone-in", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationMockClass, zone_in), + NULL, NULL, + location_VOID__POINTER_POINTER_POINTER, + G_TYPE_NONE, 3, + G_TYPE_POINTER, + G_TYPE_POINTER, + G_TYPE_POINTER); + + signals[ZONE_OUT] = g_signal_new("zone-out", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationMockClass, zone_out), + NULL, NULL, + location_VOID__POINTER_POINTER_POINTER, + G_TYPE_NONE, 3, + G_TYPE_POINTER, + G_TYPE_POINTER, + G_TYPE_POINTER); + + properties[PROP_METHOD_TYPE] = g_param_spec_int("method", + "method type", + "location method type name", + LOCATION_METHOD_MOCK, + LOCATION_METHOD_MOCK, + LOCATION_METHOD_MOCK, + G_PARAM_READABLE); + + properties[PROP_IS_STARTED] = g_param_spec_boolean("is_started", + "mock is started prop", + "mock is started status", + FALSE, + G_PARAM_READWRITE); + + properties[PROP_LAST_POSITION] = g_param_spec_boxed("last-position", + "mock last position prop", + "mock last position data", + LOCATION_TYPE_POSITION, + G_PARAM_READABLE); + + properties[PROP_POS_INTERVAL] = g_param_spec_uint("pos-interval", + "mock position interval prop", + "mock position interval data", + LOCATION_UPDATE_INTERVAL_MIN, + LOCATION_UPDATE_INTERVAL_MAX, + LOCATION_UPDATE_INTERVAL_DEFAULT, + G_PARAM_READWRITE); + + properties[PROP_VEL_INTERVAL] = g_param_spec_uint("vel-interval", + "mock velocity interval prop", + "mock velocity interval data", + LOCATION_UPDATE_INTERVAL_MIN, + LOCATION_UPDATE_INTERVAL_MAX, + LOCATION_UPDATE_INTERVAL_DEFAULT, + G_PARAM_READWRITE); + + properties[PROP_LOC_INTERVAL] = g_param_spec_uint("loc-interval", + "gps location interval prop", + "gps location interval data", + LOCATION_UPDATE_INTERVAL_MIN, + LOCATION_UPDATE_INTERVAL_MAX, + LOCATION_UPDATE_INTERVAL_DEFAULT, + G_PARAM_READWRITE); + + properties[PROP_MIN_INTERVAL] = g_param_spec_uint("min-interval", + "mock distance-based interval prop", + "mock distance-based interval data", + LOCATION_MIN_INTERVAL_MIN, + LOCATION_MIN_INTERVAL_MAX, + LOCATION_MIN_INTERVAL_DEFAULT, + G_PARAM_READWRITE); + + properties[PROP_MIN_DISTANCE] = g_param_spec_double("min-distance", + "mock distance-based distance prop", + "mock distance-based distance data", + LOCATION_MIN_DISTANCE_MIN, + LOCATION_MIN_DISTANCE_MAX, + LOCATION_MIN_DISTANCE_DEFAULT, + G_PARAM_READWRITE); + + properties[PROP_BOUNDARY] = g_param_spec_pointer("boundary", + "mock boundary prop", + "mock boundary data", + G_PARAM_READWRITE); + + properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary", + "mock removal boundary prop", + "mock removal boundary data", + LOCATION_TYPE_BOUNDARY, + G_PARAM_READWRITE); + + g_object_class_install_properties(gobject_class, + PROP_MAX, + properties); +} + diff --git a/location/manager/location-mock.h b/location/manager/location-mock.h new file mode 100755 index 0000000..2e8d7ba --- /dev/null +++ b/location/manager/location-mock.h @@ -0,0 +1,64 @@ +/* + * libslp-location + * + * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LOCATION_MOCK_H__ +#define __LOCATION_MOCK_H__ + +#include + +/** + * @file location-mock.h + * @brief This file contains the internal definitions and structures related to MOCK. + */ + +G_BEGIN_DECLS + +#define LOCATION_TYPE_MOCK (location_mock_get_type ()) +#define LOCATION_MOCK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LOCATION_TYPE_MOCK, LocationMock)) +#define LOCATION_IS_MOCK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LOCATION_TYPE_MOCK)) +#define LOCATION_MOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LOCATION_TYPE_MOCK, LocationMockClass)) +#define LOCATION_IS_MOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LOCATION_TYPE_MOCK)) +#define LOCATION_MOCK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LOCATION_TYPE_MOCK, LocationMockClass)) + +typedef struct _LocationMock LocationMock; +typedef struct _LocationMockClass LocationMockClass; + +struct _LocationMock { + GObject parent_instance; +}; + +struct _LocationMockClass { + GObjectClass parent_class; + + void (* enabled)(guint type); + void (* disabled)(guint type); + void (* service_updated)(gint type, gpointer data, gpointer velocity, gpointer accuracy); + void (* location_updated)(gint error, gpointer position, gpointer velocity, gpointer accuracy); + void (* zone_in)(gpointer boundary, gpointer position, gpointer accuracy); + void (* zone_out)(gpointer boundary, gpointer position, gpointer accuracy); + void (* status_changed)(guint type); +}; + +GType location_mock_get_type(void); + +G_END_DECLS + +#endif diff --git a/location/manager/location-position.h b/location/manager/location-position.h index 8250d3b..9fb8383 100644 --- a/location/manager/location-position.h +++ b/location/manager/location-position.h @@ -52,7 +52,9 @@ GType location_position_get_type(void); typedef enum { LOCATION_STATUS_NO_FIX = 0, /*/< No fix status. */ LOCATION_STATUS_2D_FIX, /*/< 2D fix status (latitude/longitude/speed/direction). */ - LOCATION_STATUS_3D_FIX /*/< 3D fix status (altitude/climb as well). */ + LOCATION_STATUS_3D_FIX, /*/< 3D fix status (altitude/climb as well). */ + LOCATION_STATUS_MOCK_SET, /**< MOCK Location set*/ + LOCATION_STATUS_MOCK_FAIL, /**< MOACK Location failed */ } LocationStatus; /** diff --git a/location/manager/location-satellite.c b/location/manager/location-satellite.c old mode 100644 new mode 100755 diff --git a/location/manager/location-setting.c b/location/manager/location-setting.c index 191ef10..79ab1cd 100644 --- a/location/manager/location-setting.c +++ b/location/manager/location-setting.c @@ -88,57 +88,6 @@ static char *__convert_event_from_vconf(const char *vconf) return event; } -static char *__convert_key_from_event(const char *event) -{ - char *key = NULL; - if (g_strcmp0(event, SYS_EVENT_LOCATION_ENABLE_STATE) == 0) { - key = g_strdup(EVT_KEY_LOCATION_ENABLE_STATE); - } else if (g_strcmp0(event, SYS_EVENT_GPS_ENABLE_STATE) == 0) { - key = g_strdup(EVT_KEY_GPS_ENABLE_STATE); - } else if (g_strcmp0(event, SYS_EVENT_NPS_ENABLE_STATE) == 0) { - key = g_strdup(EVT_KEY_NPS_ENABLE_STATE); - } - return key; -} - -static char *__convert_event_value(const int val) -{ - char *value = NULL; - if (val == 1) { - value = g_strdup(EVT_VAL_GPS_ENABLED); - } else { - value = g_strdup(EVT_VAL_GPS_DISABLED); - } - return value; -} - -gint location_setting_send_system_event(const char *path, const int val) -{ - g_return_val_if_fail(path, -1); - - int ret = 0; - char *event = NULL; - char *key = NULL; - char *value = NULL; - bundle *b = NULL; - - event = __convert_event_from_vconf(path); - key = __convert_key_from_event(event); - value = __convert_event_value(val); - - b = bundle_create(); - bundle_add_str(b, key, value); - ret = eventsystem_request_sending_system_event(event, b); - bundle_free(b); - - LOCATION_SECLOG("[%s: %s]", key, value); - - g_free(event); - g_free(key); - g_free(value); - return ret; -} - static void __event_handler(const char *event_name, bundle *data, void *self) { const char *value = NULL; diff --git a/location/manager/location-setting.h b/location/manager/location-setting.h index 20f29fb..ffced76 100644 --- a/location/manager/location-setting.h +++ b/location/manager/location-setting.h @@ -48,7 +48,6 @@ typedef void (*SettingCB)(keynode_t *key, gpointer data); -gint location_setting_send_system_event(const char *path, const int val); gint location_setting_get_key_val(keynode_t *key); gint location_setting_get_int(const gchar *path); gboolean location_setting_get_bool(const gchar *path); @@ -68,4 +67,9 @@ gint location_state_ignore_notify(const gchar *path, SettingCB setting_cb); }\ } -#endif +/* For test +#define VCONFKEY_LOCATION_MOCK_ENABLED "db/location/setting/MockEnabled" +#define VCONFKEY_LOCATION_MOCK_STATE "memory/location/mock/state" +*/ + +#endif /* __LOCATION_SETTING_H__ */ diff --git a/location/manager/location-signaling-util.c b/location/manager/location-signaling-util.c old mode 100644 new mode 100755 index 968fa54..516fbf5 --- a/location/manager/location-signaling-util.c +++ b/location/manager/location-signaling-util.c @@ -42,13 +42,21 @@ enable_signaling(LocationObject *obj, if (*prev_enabled == TRUE && enabled == FALSE) { *prev_enabled = FALSE; - LOCATION_LOGD("Signal emit: SERVICE_DISABLED"); + LOCATION_LOGD("Signal emit: SERVICE_DISABLED, status = %d", status); g_signal_emit(obj, signals[SERVICE_DISABLED], 0, LOCATION_STATUS_NO_FIX); + /* g_signal_emit(obj, signals[STATUS_CHANGED], 0, LOCATION_STATUS_NO_FIX); */ } else if (*prev_enabled == FALSE && enabled == TRUE) { *prev_enabled = TRUE; - LOCATION_LOGD("Signal emit: SERVICE_ENABLED"); + LOCATION_LOGD("Signal emit: SERVICE_ENABLED, status = %d", status); g_signal_emit(obj, signals[SERVICE_ENABLED], 0, status); + /* g_signal_emit(obj, signals[STATUS_CHANGED], 0, status); */ } +#if 0 + } else if (*prev_enabled != enabled) { + LOCATION_LOGD("Signal emit: prev_enabled = %d, enabled = %d, status = %d", *prev_enabled, enabled, status); + /* g_signal_emit(obj, signals[STATUS_CHANGED], 0, status); */ + } +#endif } void @@ -75,7 +83,10 @@ position_velocity_signaling(LocationObject *obj, GList *boundary_list = prev_bound; LocationBoundaryPrivate *priv = NULL; - if (!pos->timestamp) return; + if (pos && !pos->timestamp) { + LOCATION_LOGW("Invalid location with timestamp, 0"); + return; + } if (pos_interval > 0) { if (pos->timestamp - *pos_updated_timestamp >= pos_interval) { @@ -85,7 +96,7 @@ position_velocity_signaling(LocationObject *obj, } if (vel_interval > 0) { - if (vel->timestamp - *vel_updated_timestamp >= vel_interval) { + if (vel && (vel->timestamp - *vel_updated_timestamp >= vel_interval)) { signal_type |= VELOCITY_UPDATED; *vel_updated_timestamp = vel->timestamp; } @@ -220,6 +231,7 @@ location_signaling(LocationObject *obj, *prev_vel = location_velocity_copy(cur_vel); *prev_acc = location_accuracy_copy(cur_acc); + LOCATION_LOGD("status = %d", cur_pos->status); enable_signaling(obj, signals, prev_enabled, enabled, cur_pos->status); position_velocity_signaling(obj, signals, pos_interval, vel_interval, loc_interval, prev_pos_timestamp, prev_vel_timestamp, prev_loc_timestamp, boundary_list, cur_pos, cur_vel, cur_acc); } diff --git a/location/manager/location-wps.c b/location/manager/location-wps.c old mode 100644 new mode 100755 index 4690d37..795cbf4 --- a/location/manager/location-wps.c +++ b/location/manager/location-wps.c @@ -76,13 +76,14 @@ enum { PROP_REMOVAL_BOUNDARY, PROP_MIN_INTERVAL, PROP_MIN_DISTANCE, + PROP_SERVICE_STATUS, PROP_MAX }; static guint32 signals[LAST_SIGNAL] = {0, }; static GParamSpec *properties[PROP_MAX] = {NULL, }; -#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_WPS, LocationWpsPrivate)) +#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), LOCATION_TYPE_WPS, LocationWpsPrivate)) static void location_ielement_interface_init(LocationIElementInterface *iface); @@ -141,7 +142,7 @@ wps_status_cb(gboolean enabled, LocationStatus status, gpointer self) { - LOCATION_LOGD("wps_status_cb"); + LOCATION_LOGD("status = %d, status"); g_return_if_fail(self); LocationWpsPrivate *priv = GET_PRIVATE(self); g_return_if_fail(priv); @@ -225,7 +226,7 @@ location_setting_wps_cb(keynode_t *key, if (1 == location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED) && priv->mod->ops.start && !__get_started(self)) { LOCATION_LOGD("location resumed by setting"); __set_started(self, TRUE); - ret = priv->mod->ops.start(priv->mod->handler, wps_status_cb, wps_location_cb, NULL, self); + ret = priv->mod->ops.start(priv->mod->handler, wps_status_cb, wps_location_cb, self); if (ret != LOCATION_ERROR_NONE) { __set_started(self, FALSE); LOCATION_LOGD("Fail to start. Error[%d]", ret); @@ -253,7 +254,7 @@ location_wps_start(LocationWps *self) ret = LOCATION_ERROR_SETTING_OFF; } else { __set_started(self, TRUE); - ret = priv->mod->ops.start(priv->mod->handler, wps_status_cb, wps_location_cb, NULL, self); + ret = priv->mod->ops.start(priv->mod->handler, wps_status_cb, wps_location_cb, self); if (ret != LOCATION_ERROR_NONE) { __set_started(self, FALSE); LOCATION_LOGE("Fail to start wps. Error[%d]", ret); @@ -434,6 +435,12 @@ location_wps_set_property(GObject *object, break; } + case PROP_SERVICE_STATUS: { + gint enabled = g_value_get_int(value); + LOCATION_LOGD("Set prop>> PROP_SERVICE_STATUS: %u", enabled); + priv->enabled = enabled; + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -477,6 +484,9 @@ location_wps_get_property(GObject *object, case PROP_MIN_DISTANCE: g_value_set_double(value, priv->min_distance); break; + case PROP_SERVICE_STATUS: + g_value_set_int(value, priv->enabled); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -690,7 +700,7 @@ location_wps_request_single_location(LocationWps *self, int timeout) int ret = LOCATION_ERROR_NONE; __set_started(self, TRUE); - ret = priv->mod->ops.start(priv->mod->handler, wps_status_cb, wps_single_location_cb, NULL, self); + ret = priv->mod->ops.start(priv->mod->handler, wps_status_cb, wps_single_location_cb, self); if (ret != LOCATION_ERROR_NONE) { LOCATION_LOGE("Fail to start request single. Error[%d]", ret); __set_started(self, FALSE); @@ -726,6 +736,7 @@ location_wps_set_option(LocationWps *self, const char *option) g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE); g_return_val_if_fail(priv->mod, LOCATION_ERROR_NOT_AVAILABLE); g_return_val_if_fail(priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE); + return LOCATION_ERROR_NONE; } @@ -825,11 +836,23 @@ location_wps_class_init(LocationWpsClass *klass) G_TYPE_NONE, 1, G_TYPE_UINT); +#if 0 /* TODO: STATUS_CHANGED will aggregate SERVICE_ENABLED and SERVICE_DISABLED */ + signals[STATUS_CHANGED] = g_signal_new("status-changed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET(LocationWpsClass, status_changed), + NULL, NULL, + location_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); +#endif + signals[SERVICE_UPDATED] = g_signal_new("service-updated", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, - G_STRUCT_OFFSET(LocationWpsClass, updated), + G_STRUCT_OFFSET(LocationWpsClass, service_updated), NULL, NULL, location_VOID__INT_POINTER_POINTER_POINTER, G_TYPE_NONE, 4, @@ -946,6 +969,15 @@ location_wps_class_init(LocationWpsClass *klass) LOCATION_TYPE_BOUNDARY, G_PARAM_READWRITE); + /* Tizen 3.0 */ + properties[PROP_SERVICE_STATUS] = g_param_spec_int("service-status", + "location service status prop", + "location service status data", + LOCATION_STATUS_NO_FIX, + LOCATION_STATUS_3D_FIX, + LOCATION_STATUS_NO_FIX, + G_PARAM_READABLE); + g_object_class_install_properties(gobject_class, PROP_MAX, properties); diff --git a/location/manager/location-wps.h b/location/manager/location-wps.h index 8f9b494..2c21e35 100644 --- a/location/manager/location-wps.h +++ b/location/manager/location-wps.h @@ -50,10 +50,11 @@ struct _LocationWpsClass { void (* enabled)(guint type); void (* disabled)(guint type); - void (* updated)(gint type, gpointer data, gpointer velocity, gpointer accuracy); + void (* service_updated)(gint type, gpointer data, gpointer velocity, gpointer accuracy); void (* location_updated)(gint error, gpointer position, gpointer velocity, gpointer accuracy); void (* zone_in)(gpointer boundary, gpointer position, gpointer accuracy); void (* zone_out)(gpointer boundary, gpointer position, gpointer accuracy); + void (* status_changed)(guint type); }; GType location_wps_get_type(void); diff --git a/location/manager/location.c b/location/manager/location.c old mode 100644 new mode 100755 index 402dc32..851f7e7 --- a/location/manager/location.c +++ b/location/manager/location.c @@ -35,6 +35,7 @@ #include "location-hybrid.h" #include "location-gps.h" #include "location-wps.h" +#include "location-mock.h" #include "location-position.h" #include "module-internal.h" #include "location-common-util.h" @@ -65,6 +66,9 @@ static char *__convert_setting_key(LocationMethod method) case LOCATION_METHOD_WPS: key = g_strdup(VCONFKEY_LOCATION_NETWORK_ENABLED); break; + case LOCATION_METHOD_MOCK: + key = g_strdup(VCONFKEY_LOCATION_MOCK_ENABLED); + break; default: break; } @@ -81,6 +85,8 @@ static LocationMethod __convert_method_from_key(const char *key) _method = LOCATION_METHOD_GPS; } else if (g_strcmp0(key, VCONFKEY_LOCATION_NETWORK_ENABLED) == 0) { _method = LOCATION_METHOD_WPS; + } else if (g_strcmp0(key, VCONFKEY_LOCATION_MOCK_ENABLED) == 0) { + _method = LOCATION_METHOD_MOCK; } return _method; @@ -103,11 +109,11 @@ static void __location_setting_cb(keynode_t *key, gpointer data) EXPORT_API int location_init(void) { -#if !GLIB_CHECK_VERSION (2, 35, 0) +#if !GLIB_CHECK_VERSION(2, 35, 0) g_type_init(); #endif -#if !GLIB_CHECK_VERSION (2, 31, 0) +#if !GLIB_CHECK_VERSION(2, 31, 0) if (!g_thread_supported()) g_thread_init(NULL); #endif if (FALSE == module_init()) @@ -136,6 +142,8 @@ location_new(LocationMethod method) case LOCATION_METHOD_WPS: self = g_object_new(LOCATION_TYPE_WPS, NULL); break; + case LOCATION_METHOD_MOCK: + self = g_object_new(LOCATION_TYPE_MOCK, NULL); default: break; } @@ -265,7 +273,7 @@ location_is_supported_method(LocationMethod method) switch (method) { case LOCATION_METHOD_HYBRID: - if (module_is_supported("gps") || module_is_supported("wps")) + if (module_is_supported("gps") || module_is_supported("wps") || module_is_supported("mock")) is_supported = TRUE; break; case LOCATION_METHOD_GPS: @@ -274,6 +282,9 @@ location_is_supported_method(LocationMethod method) case LOCATION_METHOD_WPS: is_supported = module_is_supported("wps"); break; + case LOCATION_METHOD_MOCK: + is_supported = module_is_supported("mock"); + break; default: break; } @@ -334,13 +345,6 @@ location_enable_method(const LocationMethod method, const int enable) LOCATION_SECLOG("vconf_set_int failed [%s], ret=[%d]", _key, ret); g_free(_key); return LOCATION_ERROR_NOT_ALLOWED; - } else { - ret = location_setting_send_system_event(_key, enable); - if (ret != LOCATION_ERROR_NONE) { - LOCATION_SECLOG("Fail to send system event [%s], ret=[%d]", _key, ret); - g_free(_key); - return LOCATION_ERROR_NOT_ALLOWED; - } } g_free(_key); @@ -357,16 +361,8 @@ location_enable_method(const LocationMethod method, const int enable) LOCATION_SECLOG("vconf_set_int failed [%s], ret=[%d]", _key, ret); g_free(_key); return LOCATION_ERROR_NOT_ALLOWED; - } else { - ret = location_setting_send_system_event(_key, enable); - if (ret != LOCATION_ERROR_NONE) { - LOCATION_SECLOG("Fail to send system event [%s], ret=[%d]", _key, ret); - g_free(_key); - return LOCATION_ERROR_NOT_ALLOWED; - } } - } - else { + } else { int i = 0; int enabled_state = 0; @@ -384,12 +380,6 @@ location_enable_method(const LocationMethod method, const int enable) return LOCATION_ERROR_NOT_ALLOWED; } else { LOCATION_SECLOG("[%s]:[%d]", _key, ret); - ret = location_setting_send_system_event(_key, enable); - if (ret != LOCATION_ERROR_NONE) { - LOCATION_SECLOG("Fail to send system event [%s], error [%d]", _key, ret); - g_free(_key); - return LOCATION_ERROR_NOT_ALLOWED; - } } g_free(_key); } @@ -751,3 +741,178 @@ location_set_option(LocationObject *obj, const char *option) LOCATION_LOGE("Fail to get_velocity. Error [%d]", ret); return ret; } + + +/* + * Tizen 3.0 + */ + +EXPORT_API int +location_get_service_state(LocationObject *obj, int *state) +{ + g_return_val_if_fail(obj, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(state, LOCATION_ERROR_PARAMETER); + + int ret = LOCATION_ERROR_NONE; + +#ifndef TIZEN_PROFILE_TV + ret = location_get_privacy(LOCATION_PRIVILEGE); + if (ret != LOCATION_ERROR_NONE) { + LOCATION_LOGE("Cannot use location service for privacy[%d]", ret); + return LOCATION_ERROR_NOT_ALLOWED; + } +#endif + + ret = location_ielement_get_status(LOCATION_IELEMENT(obj), state); + if (ret != LOCATION_ERROR_NONE) LOCATION_LOGE("Fail to get_position. Error [%d]", ret); + + return ret; +} + + +EXPORT_API int +location_enable_mock(const LocationMethod method, const int enable) +{ + int ret = 0; + char *_key = NULL; + + if (method != LOCATION_METHOD_MOCK) { + return LOCATION_ERROR_PARAMETER; + } + +#ifndef TIZEN_PROFILE_TV + ret = location_check_privilege(LOCATION_PRIVILEGE); + if (ret != LOCATION_ERROR_NONE) { + LOCATION_LOGE("Cannot use location service for privacy[%d]", ret); + return LOCATION_ERROR_NOT_ALLOWED; + } +#endif + +#if 0 /* Tizen platform didn't turn developer option on */ + gboolean developer_option = FALSE; + + ret = vconf_get_bool(VCONFKEY_SETAPPL_DEVELOPER_OPTION_STATE, &developer_option); + if (!developer_option) { + LOCATION_LOGE("Cannot enable mock location because developer option is not turned on", ret); + return LOCATION_ERROR_NOT_ALLOWED; + } +#endif + + _key = __convert_setting_key(method); + if (!_key) { + LOCATION_LOGE("Invalid method[%d]", method); + return LOCATION_ERROR_NOT_SUPPORTED; + } + ret = vconf_set_int(_key, enable); + if (ret != VCONF_OK) { + LOCATION_SECLOG("vconf_set_int failed [%s], ret=[%d]", _key, ret); + g_free(_key); + return LOCATION_ERROR_NOT_ALLOWED; + } + + g_free(_key); + + return ret; +} + +#if 0 +static char *__convert_mock_setting_key(LocationMethod method) +{ + char *key = NULL; + switch (method) { + case LOCATION_METHOD_MOCK_GPS: + key = g_strdup(VCONFKEY_LOCATION_MOCK_GPS_ENABLED); + break; + case LOCATION_METHOD_MOCK_WPS: + key = g_strdup(VCONFKEY_LOCATION_MOCK_NETWORK_ENABLED); + break; + default: + break; + } + return key; +} + +EXPORT_API int +location_set_mock_method_enabled(const LocationMethod method, const int enable) +{ + int ret = 0; + char *_key = NULL; + int vconf_val = 0; + + _key = __convert_setting_key(method); + if (!_key) { + LOCATION_LOGE("Invalid method[%d]", method); + return LOCATION_ERROR_NOT_SUPPORTED; + } + + ret = vconf_get_int(_key, &vconf_val); + if (ret != VCONF_OK) { + LOCATION_SECLOG("failed [%s], error [%d]", _key, ret); + g_free(_key); + return LOCATION_ERROR_NOT_ALLOWED; + } + + if (vconf_val) { + _key = __convert_mock_setting_key(method); + if (!_key) { + LOCATION_LOGE("Invalid method[%d]", method); + return LOCATION_ERROR_NOT_SUPPORTED; + } + ret = vconf_set_int(_key, enable); + if (ret != VCONF_OK) { + LOCATION_SECLOG("vconf_set_int failed [%s], ret=[%d]", _key, ret); + g_free(_key); + return LOCATION_ERROR_NOT_ALLOWED; + } + g_free(_key); + } + + return ret; +} +#endif + + +EXPORT_API int +location_set_mock_location(LocationObject *obj, const LocationPosition *position, const LocationVelocity *velocity, const LocationAccuracy *accuracy) +{ + g_return_val_if_fail(obj, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER); + + int ret = LOCATION_ERROR_NONE; + +#ifndef TIZEN_PROFILE_TV + ret = location_get_privacy(LOCATION_PRIVILEGE); + if (ret != LOCATION_ERROR_NONE) { + LOCATION_LOGE("Cannot use location service for privacy[%d]", ret); + return LOCATION_ERROR_NOT_ALLOWED; + } +#endif + + ret = location_ielement_set_mock_location(LOCATION_IELEMENT(obj), position, velocity, accuracy); + if (ret != LOCATION_ERROR_NONE) LOCATION_LOGE("Fail to location_ielement_set_mock_location. Error [%d]", ret); + + return ret; +} + +EXPORT_API int +location_clear_mock_location(LocationObject *obj) +{ + g_return_val_if_fail(obj, LOCATION_ERROR_PARAMETER); + + int ret = LOCATION_ERROR_NONE; + +#ifndef TIZEN_PROFILE_TV + ret = location_get_privacy(LOCATION_PRIVILEGE); + if (ret != LOCATION_ERROR_NONE) { + LOCATION_LOGE("Cannot use location service for privacy[%d]", ret); + return LOCATION_ERROR_NOT_ALLOWED; + } +#endif + + ret = location_ielement_clear_mock_location(LOCATION_IELEMENT(obj)); + if (ret != LOCATION_ERROR_NONE) LOCATION_LOGE("Fail to location_ielement_set_mock_location. Error [%d]", ret); + + return ret; +} \ No newline at end of file diff --git a/location/manager/location.h b/location/manager/location.h old mode 100644 new mode 100755 index f118f0d..ebb1527 --- a/location/manager/location.h +++ b/location/manager/location.h @@ -148,31 +148,25 @@ static void cb_service_enabled (GObject *self, guint status, gpointer userdata) g_object_get(loc, "method", &method, NULL); g_debug("Get property>> method:%d", method); - if (LOCATION_ERROR_NONE == location_get_position (loc, &pos, &acc)) { - g_debug ("SYNC>> Current position> time: %d, lat: %f, long: %f, alt: %f, status: %d", - pos->timestamp, pos->latitude, pos->longitude, pos->altitude, pos->status); - g_debug ("\tAccuracy level %d (%.0f meters %.0f meters)", - acc->level, acc->horizontal_accuracy, acc->vertical_accuracy); - location_position_free(pos); - location_accuracy_free(acc); - } else g_warning ("SYNC>> Current position> failed"); - - if (LOCATION_ERROR_NONE == location_get_velocity (loc, &vel, &acc)) { - g_debug ("SYNC>> Current velocity> time: %d, speed: %f, direction:%f, climb:%f", - vel->timestamp, vel->speed, vel->direction, vel->climb); - g_debug ("\tAccuracy level %d (%.0f meters %.0f meters)", + if (status == LOCATION_STATUS_2D_FIX || status == LOCATION_STATUS_3D_FIX) { + if (LOCATION_ERROR_NONE == location_get_position (loc, &pos, &acc)) { + g_debug ("SYNC>> Current position> time: %d, lat: %f, long: %f, alt: %f, status: %d", + pos->timestamp, pos->latitude, pos->longitude, pos->altitude, pos->status); + g_debug ("\tAccuracy level %d (%.0f meters %.0f meters)", acc->level, acc->horizontal_accuracy, acc->vertical_accuracy); - location_velocity_free(vel); - location_accuracy_free(acc); - } else g_warning ("SYNC>> Current velocity> failed"); + location_position_free(pos); + location_accuracy_free(acc); + } else g_warning ("SYNC>> Current position> failed"); - if (LOCATION_ERROR_NONE == location_get_address(loc, &addr, &acc)) { - g_debug ("SYNC>> Current address> %s %s %s %s %s %s %s", - addr->building_number, addr->street, addr->district, addr->city, addr->state, addr->postal_code, addr->country_code); - g_debug ("\tAccuracy level %d (%.0f meters %.0f meters)", acc->level, acc->horizontal_accuracy, acc->vertical_accuracy); - location_address_free(addr); - location_accuracy_free(acc); - } else g_warning ("SYNC>> Current address> failed"); + if (LOCATION_ERROR_NONE == location_get_velocity (loc, &vel, &acc)) { + g_debug ("SYNC>> Current velocity> time: %d, speed: %f, direction:%f, climb:%f", + vel->timestamp, vel->speed, vel->direction, vel->climb); + g_debug ("\tAccuracy level %d (%.0f meters %.0f meters)", + acc->level, acc->horizontal_accuracy, acc->vertical_accuracy); + location_velocity_free(vel); + location_accuracy_free(acc); + } else g_warning ("SYNC>> Current velocity> failed"); + } } static void @@ -875,6 +869,14 @@ int location_ignore_setting_notify(LocationMethod method, LocationSettingCb call int location_get_nmea(LocationObject *obj, char **nmea_data); +/* Tizen 3.0 */ + +int location_get_service_state(LocationObject *obj, int *state); +int location_enable_mock(const LocationMethod method, const int enable); +int location_set_mock_method_enabled(const LocationMethod method, const int enable); +int location_set_mock_location(LocationObject *obj, const LocationPosition *position, const LocationVelocity *velocity, const LocationAccuracy *accuracy); +int location_clear_mock_location(LocationObject *obj); + /** * @} @} */ diff --git a/location/module/location-module.h b/location/module/location-module.h index 9dd06cf..c1cc12f 100644 --- a/location/module/location-module.h +++ b/location/module/location-module.h @@ -88,13 +88,28 @@ typedef struct { * @brief This represents APIs declared in a WPS plug-in for location WPS modules. */ typedef struct { - int (*start)(gpointer handle, LocModStatusCB status_cb, LocModPositionExtCB pos_ext_cb, LocModSatelliteCB sat_cb, gpointer userdata); /*/< This is used for starting a WPS service from a plug-in. #LocModStatusCB, #LocModPositionExtCB and #LocModSatelliteCB(Not used) are given from a location framework to a plug-in for asynchronous signaling. */ + int (*start)(gpointer handle, LocModStatusCB status_cb, LocModPositionExtCB pos_ext_cb, gpointer userdata); /*/< This is used for starting a WPS service from a plug-in. #LocModStatusCB, #LocModPositionExtCB and #LocModSatelliteCB(Not used) are given from a location framework to a plug-in for asynchronous signaling. */ int (*stop)(gpointer handle); /*/< This is used for stopping a WPS service from a plug-in. */ int (*get_position)(gpointer handle, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy); /*/< This is used for getting a position from a plug-in. */ int (*get_last_position)(gpointer handle, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy); /*/< This is used for getting a last position from a plug-in. */ int (*set_option)(gpointer handle, const char *option); } LocModWpsOps; +typedef struct { + int (*start)(gpointer handle, LocModStatusCB status_cb, LocModPositionExtCB pos_ext_cb, gpointer userdata); /*/< This is used for starting a GPS device from a plug-in. #LocModStatusCB, #LocModPositionExtCB are given from a location framework to a plug-in for asynchronous signaling. */ + int (*stop)(gpointer handle); /*/< This is used for stopping a GPS device name from a plug-in. */ +#if 0 /* Mock doesn't support batch */ + int (*start_batch)(gpointer handle, LocModBatchExtCB batch_ext_cb, guint batch_interval, guint batch_period, gpointer userdata); /*/< This is used for starting a GPS batch mode from a plug-in. #LocModBatchExtCB are given from a location framework to a plug-in for asynchronous signaling. */ + int (*stop_batch)(gpointer handle); /*/< This is used for stopping a GPS batch mode from a plug-in. */ +#endif + int (*get_position)(gpointer handle, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy); /*/< This is used for getting a position from a plug-in. */ + int (*get_last_position)(gpointer handle, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy); /*/< This is used for getting a last position from a plug-in. */ + int (*set_option)(gpointer handle, const char *option); + //int (*set_position_update_interval)(gpointer handle, guint interval); + int (*set_mock_location)(gpointer handle, LocationPosition *position, LocationVelocity *velocity, LocationAccuracy *accuracy, LocModStatusCB status_cb, gpointer userdata); /*/< This is used for getting a position from a plug-in. */ + int (*clear_mock_location)(gpointer handle, LocModStatusCB status_cb, gpointer userdata); /*/< This is used for getting a position from a plug-in. */ +} LocModMockOps; + /** * @brief This is used for exported APIs in a plug-in for a location framework. */ diff --git a/location/module/module-internal.c b/location/module/module-internal.c old mode 100644 new mode 100755 index 7e4a292..ad5a0c5 --- a/location/module/module-internal.c +++ b/location/module/module-internal.c @@ -50,7 +50,7 @@ static GMod *gmod_new(const char *module_name, gboolean is_resident) char *module_path = g_strndup(MODULE_PATH_PREFIX, strlen(MODULE_PATH_PREFIX)+1); /* gmod->path = g_module_build_path(MODULE_PATH_PREFIX, gmod->name); */ - gmod->path = g_module_build_path(module_path, gmod->name); + gmod->path = g_module_build_path(module_path, gmod->name); if (!gmod->path) { g_free(gmod->name); g_free(gmod); @@ -147,6 +147,18 @@ static gpointer mod_new(const char *module_name) ret_mod = NULL; } else ret_mod = (gpointer) _mod; + } else if (g_str_has_prefix(module_name, "mock")) { + LocationMockMod *_mod = g_new0(LocationMockMod, 1); + _mod->gmod = gmod; + _mod->init = init; + _mod->shutdown = shutdown; + _mod->handler = _mod->init(&(_mod->ops)); + if (!_mod->handler) { + LOCATION_LOGW("module init failed"); + gmod_free(_mod->gmod); + ret_mod = NULL; + } else + ret_mod = (gpointer) _mod; } else { LOCATION_LOGW("module name (%s) is wrong", module_name); ret_mod = NULL; @@ -179,8 +191,19 @@ static void mod_free(gpointer mod, const char *module_name) _mod->shutdown = NULL; gmod_free(_mod->gmod); _mod->gmod = NULL; - } else + } else if (0 == g_strcmp0(module_name, "mock")) { + LocationMockMod *_mod = (LocationMockMod *) mod; + if (_mod->shutdown && _mod->handler) { + _mod->shutdown(_mod->handler); + } + _mod->handler = NULL; + _mod->init = NULL; + _mod->shutdown = NULL; + gmod_free(_mod->gmod); + _mod->gmod = NULL; + } else { LOCATION_LOGW("module name (%s) is wrong", module_name); + } g_free(mod); } @@ -217,10 +240,12 @@ gpointer module_new(const char *module_name) { if (!module_name) return NULL; - int index = 0; char name[256]; gpointer mod = NULL; +#if 0 + int index = 0; + for (index = -1; index < MAX_MODULE_INDEX; index++) { if (index >= 0) { if (0 >= g_snprintf(name, 256, "%s%d", module_name, index)) { @@ -240,6 +265,16 @@ gpointer module_new(const char *module_name) } LOCATION_LOGW("module (%s) open failed", name); } +#endif + if (0 >= g_snprintf(name, 256, "%s", module_name)) { + LOCATION_LOGW("module name(%s) is wrong", name); + } else { + mod = mod_new(name); + if (mod) + LOCATION_LOGW("module (%s) open success", name); + else + LOCATION_LOGW("module (%s) open failed", name); + } return mod; } diff --git a/location/module/module-internal.h b/location/module/module-internal.h index fff11d6..6d2998d 100644 --- a/location/module/module-internal.h +++ b/location/module/module-internal.h @@ -54,6 +54,13 @@ typedef struct { LocModWpsOps ops; } LocationWpsMod; +typedef struct { + GMod *gmod; + gpointer handler; + gpointer(*init)(LocModMockOps *ops); + void (*shutdown)(gpointer handle); + LocModMockOps ops; +} LocationMockMod; gboolean module_init(void); gpointer module_new(const char *module_name); diff --git a/packaging/liblbs-location.changes b/packaging/liblbs-location.changes index 0c4d5a0..71a87f7 100644 --- a/packaging/liblbs-location.changes +++ b/packaging/liblbs-location.changes @@ -1,3 +1,10 @@ +[Version] libslp-location_1.0.0 +[Date] 19 January 2016 +[Changes] Supported mock location +[Developer] Young-Ae Kang + +================================================================================ + [Version] libslp-location_0.12.0 [Date] 10 Jun 2015 [Changes] Code synchronization with tizen_2.4 @@ -6,7 +13,6 @@ ================================================================================ - [Version] libslp-location_0.11.0 [Date] 29 May 2015 [Changes] [ACR-225][2.4][location-manager][Add] Turn Location setting on or off diff --git a/packaging/liblbs-location.spec b/packaging/liblbs-location.spec index 8a739f7..266eb46 100755 --- a/packaging/liblbs-location.spec +++ b/packaging/liblbs-location.spec @@ -1,6 +1,6 @@ Name: liblbs-location Summary: Location Based Service Library -Version: 0.12.0 +Version: 1.0.0 Release: 1 Group: Location/Libraries License: Apache-2.0 -- 2.7.4