Fused Location 25/111425/20 submit/tizen/20170713.072054
authorMarcin Masternak <m.masternak@samsung.com>
Fri, 12 May 2017 16:46:48 +0000 (18:46 +0200)
committerkj7.sung <kj7.sung@samsung.com>
Mon, 10 Jul 2017 08:11:24 +0000 (17:11 +0900)
Change-Id: If4a6e7eac54eff8c16d9f74e26a5c08416973380
Signed-off-by: kj7.sung <kj7.sung@samsung.com>
Signed-off-by: Marcin Masternak <m.masternak@samsung.com>
19 files changed:
location/CMakeLists.txt
location/include/location-types.h
location/manager/location-batch.c [changed mode: 0755->0644]
location/manager/location-fused.c [new file with mode: 0644]
location/manager/location-fused.h [new file with mode: 0644]
location/manager/location-gps.c [changed mode: 0755->0644]
location/manager/location-hybrid-mobile.c [changed mode: 0755->0644]
location/manager/location-ielement.c [changed mode: 0755->0644]
location/manager/location-ielement.h
location/manager/location-passive.c [changed mode: 0755->0644]
location/manager/location-satellite.c [changed mode: 0755->0644]
location/manager/location-signaling-util.c [changed mode: 0755->0644]
location/manager/location-wps.c [changed mode: 0755->0644]
location/manager/location.c [changed mode: 0755->0644]
location/manager/location.h [changed mode: 0755->0644]
location/module/location-module.h
location/module/module-internal.c
location/module/module-internal.h
packaging/liblbs-location.spec

index 7e0eb09..83b66a6 100644 (file)
@@ -37,6 +37,7 @@ SET(SRCS
        ${MANAGER_DIR}/location-gps.c
        ${MANAGER_DIR}/location-wps.c
        ${MANAGER_DIR}/location-passive.c
+       ${MANAGER_DIR}/location-fused.c
        ${PRIVACY_SRC}
 
        ${MODULE_DIR}/module-internal.c
@@ -56,6 +57,7 @@ SET (INSTALL_HEADERS
        ${MANAGER_DIR}/location-accuracy.h
        ${MANAGER_DIR}/location-boundary.h
        ${MANAGER_DIR}/location-satellite.h
+       ${MANAGER_DIR}/location-setting.h
 
        ${MODULE_DIR}/location-module.h
 )
index f82086e..47ebed4 100644 (file)
@@ -65,6 +65,7 @@ typedef enum {
        LOCATION_METHOD_GPS,                            /*/< This method uses Global Positioning System. */
        LOCATION_METHOD_WPS,                            /*/< This method uses Wifi Positioning System. */
        LOCATION_METHOD_PASSIVE,                        /* < This method is for passive method */
+       LOCATION_METHOD_FUSED,                          /* < This method uses fused location */
        INTERNAL_METHOD_MOCK,                           /*/< This method uses mock location. */
        LOCATION_METHOD_MAX,                            /*/< The numer of methods */
 } LocationMethod;
@@ -90,6 +91,15 @@ typedef enum {
 } LocationAccessState;
 
 /**
+ * @brief Supported methods of measurement in the FUSED mode.
+ */
+typedef enum {
+       LOCATION_FUSED_HIGH = 0,        /*/< High-accuracy */
+       LOCATION_FUSED_BALANCED,        /*/< Medium-accuracy, lower power consumption */
+       LOCATION_FUSED_NONE                     /*/< Mode is not decided for devel */
+} LocationFusedMode;
+
+/**
  * @brief This represents the setting type.
  */
 typedef enum {
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/location/manager/location-fused.c b/location/manager/location-fused.c
new file mode 100644 (file)
index 0000000..3b5e947
--- /dev/null
@@ -0,0 +1,743 @@
+/*
+ * libslp-location
+ *
+ * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <math.h>
+#include <stdlib.h>
+#include <vconf-internal-location-keys.h>
+#include "module-internal.h"
+
+#include "location-fused.h"
+#include "location-setting.h"
+#include "location-marshal.h"
+#include "location-ielement.h"
+#include "location-signaling-util.h"
+#include "location-common-util.h"
+
+#include "location-log.h"
+
+
+static void location_ielement_interface_init(LocationIElementInterface *iface);
+
+typedef struct _LocationFusedPrivate {
+       LocationFusedMod        *mod;
+       GMutex                          mutex;
+       gboolean                        is_started;
+       guint                           app_type;
+       gboolean                        set_noti;
+       gboolean                        enabled;
+       guint                           pos_updated_timestamp;
+       guint                           vel_updated_timestamp;
+       guint                           loc_updated_timestamp;
+       guint                           dist_updated_timestamp;
+       guint                           pos_interval;
+       guint                           vel_interval;
+       guint                           loc_interval;
+       guint                           optimized_interval;
+       guint                           min_interval;
+       gdouble                         min_distance;
+       LocationPosition        *pos;
+       LocationVelocity        *vel;
+       LocationAccuracy        *acc;
+       GList                           *boundary_list;
+       LocationFusedMode       fused_mode;
+} LocationFusedPrivate;
+
+enum {
+       PROP_0,
+       PROP_METHOD_TYPE,
+       PROP_IS_STARTED,
+       PROP_LAST_POSITION,
+       PROP_BOUNDARY,
+       PROP_REMOVAL_BOUNDARY,
+       PROP_POS_INTERVAL,
+       PROP_VEL_INTERVAL,
+       PROP_LOC_INTERVAL,
+       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_FUSED, LocationFusedPrivate))
+
+static void location_ielement_interface_init(LocationIElementInterface *iface);
+G_DEFINE_TYPE_WITH_CODE(LocationFused, location_fused, G_TYPE_OBJECT,
+                                               G_IMPLEMENT_INTERFACE(LOCATION_TYPE_IELEMENT, location_ielement_interface_init));
+
+static void fused_position_cb(gboolean enabled, LocationPosition *pos, LocationVelocity *vel, LocationAccuracy *acc, gpointer self);
+static void fused_status_cb(gboolean enabled, LocationStatus status, gpointer self);
+
+
+static void __reset_pos_data_from_priv(LocationFusedPrivate *priv)
+{
+       LOC_FUNC_LOG
+       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;
+       priv->loc_updated_timestamp = 0;
+}
+
+static gboolean __get_started(gpointer self)
+{
+       LOC_FUNC_LOG
+       g_return_val_if_fail(self, FALSE);
+
+       LocationFusedPrivate *priv = GET_PRIVATE(self);
+       g_return_val_if_fail(priv, FALSE);
+
+       return priv->is_started;
+}
+
+static int __set_started(gpointer self, gboolean started)
+{
+       LOC_FUNC_LOG
+       g_return_val_if_fail(self, -1);
+       LocationFusedPrivate *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 fused_status_cb(gboolean enabled, LocationStatus status, gpointer self)
+{
+       LOC_FUNC_LOG
+       g_return_if_fail(self);
+       LocationFusedPrivate *priv = GET_PRIVATE(self);
+       g_return_if_fail(priv);
+
+       enable_signaling((gpointer)self, signals, &(priv->enabled), status != LOCATION_STATUS_NO_FIX, status);
+}
+
+static void fused_position_cb(gboolean enabled, LocationPosition *pos, LocationVelocity *vel, LocationAccuracy *acc, gpointer self)
+{
+       LOC_FUNC_LOG
+       g_return_if_fail(self);
+       g_return_if_fail(pos);
+       g_return_if_fail(vel);
+       g_return_if_fail(acc);
+
+       LocationFusedPrivate *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_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_changed_cb(keynode_t *key, gpointer self)
+{
+       LOC_FUNC_LOG
+       g_return_if_fail(self);
+       g_return_if_fail(key);
+       LocationFusedPrivate *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 (0 == location_setting_get_key_val(key) && priv->mod->ops.stop && __get_started(self)) {
+               LOCATION_LOGD("location stopped by setting");
+               __set_started(self, FALSE);
+               ret = priv->mod->ops.stop(priv->mod->handler);
+               if (ret == LOCATION_ERROR_NONE)
+                       __reset_pos_data_from_priv(priv);
+               else
+                       LOCATION_LOGI("Fail to stop[%d]", ret);
+
+       } else if (1 == location_setting_get_key_val(key) && !__get_started(self)) {
+               LOCATION_LOGD("location resumed by setting");
+               __set_started(self, TRUE);
+
+               if (priv->fused_mode == LOCATION_FUSED_HIGH && priv->mod->ops.start_gps)
+                       ret = priv->mod->ops.start_gps(priv->mod->handler, priv->optimized_interval, fused_status_cb, fused_position_cb, NULL, self);
+               else if (priv->fused_mode == LOCATION_FUSED_BALANCED && priv->mod->ops.start_wps)
+                       ret = priv->mod->ops.start_wps(priv->mod->handler, priv->optimized_interval, fused_status_cb, fused_position_cb, NULL, self);
+
+               if (ret != LOCATION_ERROR_NONE) {
+                       __set_started(self, FALSE);
+                       LOCATION_LOGI("Fail to start[%d]", ret);
+               }
+       }
+}
+
+int location_fused_start(LocationFused *self)
+{
+       LOC_FUNC_LOG
+       LocationFusedPrivate *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_gps, LOCATION_ERROR_NOT_AVAILABLE);
+       g_return_val_if_fail(priv->mod->ops.start_wps, LOCATION_ERROR_NOT_AVAILABLE);
+
+       LOC_COND_RET(__get_started(self) == TRUE, LOCATION_ERROR_NONE, _E, "Fused already started. Error[%s]", err_msg(LOCATION_ERROR_NONE));
+
+       int ret = LOCATION_ERROR_NONE;
+
+       if (priv->fused_mode == LOCATION_FUSED_HIGH) {
+               if (location_setting_get_int(VCONFKEY_LOCATION_ENABLED)) {
+                       __set_started(self, TRUE);
+                       ret = priv->mod->ops.start_gps(priv->mod->handler, priv->optimized_interval, fused_status_cb, fused_position_cb, NULL, self);
+
+                       if (ret != LOCATION_ERROR_NONE) {
+                               LOCATION_LOGE("Fail to start fused high. Error[%d]", ret);
+                               __set_started(self, FALSE);
+                               return ret;
+                       }
+               } else {
+                       LOCATION_LOGE("GPS Setting off");
+                       ret = LOCATION_ERROR_SETTING_OFF;
+               }
+
+       } else if (priv->fused_mode == LOCATION_FUSED_BALANCED) {
+               if (location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED)) {
+                       __set_started(self, TRUE);
+                       ret = priv->mod->ops.start_wps(priv->mod->handler, priv->optimized_interval, fused_status_cb, fused_position_cb, NULL, self);
+
+                       if (ret != LOCATION_ERROR_NONE) {
+                               LOCATION_LOGE("Fail to start fused balanced. Error[%d]", ret);
+                               __set_started(self, FALSE);
+                               return ret;
+                       }
+               } else {
+                       LOCATION_LOGE("WPS Setting off");
+                       ret = LOCATION_ERROR_SETTING_OFF;
+               }
+       }
+
+       if (priv->app_type != CPPAPP && priv->set_noti == FALSE) {
+               if (priv->fused_mode == LOCATION_FUSED_HIGH)
+                       location_setting_add_notify(VCONFKEY_LOCATION_ENABLED, location_setting_changed_cb, self);
+               else if (priv->fused_mode == LOCATION_FUSED_BALANCED)
+                       location_setting_add_notify(VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_changed_cb, self);
+
+               priv->set_noti = TRUE;
+       }
+
+       LOCATION_LOGD("EXIT <<<");
+       return ret;
+}
+
+int location_fused_stop(LocationFused *self)
+{
+       LOC_FUNC_LOG
+       LocationFusedPrivate *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);
+               LOC_IF_FAIL_LOG(ret, _E, "Failed to stop [%s]", err_msg(ret));
+
+               g_signal_emit(self, signals[SERVICE_DISABLED], 0, LOCATION_STATUS_NO_FIX);
+       } else {
+               return LOCATION_ERROR_NONE;
+       }
+
+       if (priv->app_type != CPPAPP && priv->set_noti == TRUE) {
+               if (priv->fused_mode == LOCATION_FUSED_HIGH)
+                       location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_setting_changed_cb);
+               else if (priv->fused_mode == LOCATION_FUSED_BALANCED)
+                       location_setting_ignore_notify(VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_changed_cb);
+
+               priv->set_noti = FALSE;
+       }
+
+       __reset_pos_data_from_priv(priv);
+
+       return ret;
+}
+
+void location_fused_dispose(GObject *gobject)
+{
+       LOC_FUNC_LOG
+       LocationFusedPrivate *priv = GET_PRIVATE(gobject);
+       g_return_if_fail(priv);
+       g_return_if_fail(priv->mod);
+       g_mutex_clear(&priv->mutex);
+
+       if (priv->app_type != CPPAPP && priv->set_noti == TRUE) {
+               if (priv->fused_mode == LOCATION_FUSED_HIGH)
+                       location_setting_ignore_notify(VCONFKEY_LOCATION_ENABLED, location_setting_changed_cb);
+               else if (priv->fused_mode == LOCATION_FUSED_BALANCED)
+                       location_setting_ignore_notify(VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_changed_cb);
+
+               priv->set_noti = FALSE;
+       }
+
+       G_OBJECT_CLASS(location_fused_parent_class)->dispose(gobject);
+}
+
+void location_fused_finalize(GObject *gobject)
+{
+       LOC_FUNC_LOG
+       LocationFusedPrivate *priv = GET_PRIVATE(gobject);
+       g_return_if_fail(priv);
+
+       module_free(priv->mod, "fused");
+       priv->mod = NULL;
+
+       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_fused_parent_class)->finalize(gobject);
+}
+
+static guint get_valid_interval(guint interval, int max_interval, int min_interval)
+{
+       if (interval > max_interval)
+               return (guint)max_interval;
+       else if (interval < min_interval)
+               return (guint)min_interval;
+       else
+               return interval;
+}
+
+void location_fused_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+       LOC_FUNC_LOG
+       LocationFusedPrivate *priv = GET_PRIVATE(object);
+       g_return_if_fail(priv);
+       g_return_if_fail(priv->mod);
+       g_return_if_fail(priv->mod->handler);
+
+       int ret = LOCATION_ERROR_NONE;
+
+       switch (property_id) {
+       case PROP_BOUNDARY: {
+               GList *source_list = (GList *)(g_value_get_pointer(value));
+               if (source_list) {
+                       GList *boundary_list = (GList *)g_list_copy(source_list);
+                       ret = set_prop_boundary(&priv->boundary_list, boundary_list);
+                       LOC_IF_FAIL_LOG(ret, _E, "Set boundary. Error[%s]", err_msg(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);
+               LOC_IF_FAIL_LOG(ret, _E, "Removal boundary. Error[%s]", err_msg(ret));
+               break;
+       }
+       case PROP_POS_INTERVAL: {
+               guint interval = g_value_get_uint(value);
+               LOCATION_LOGD("Set prop>> PROP_POS_INTERVAL: %u", interval);
+               if (interval == priv->pos_interval) break;
+
+               priv->pos_interval = get_valid_interval(interval, LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_MIN);
+               priv->optimized_interval = priv->pos_interval;
+
+               if (__get_started(object) == TRUE) {
+                       LOCATION_LOGD("[update_pos_interval]: update pos-interval while pos-tracking");
+                       g_return_if_fail(priv->mod->ops.set_position_update_interval);
+                       priv->mod->ops.set_position_update_interval(priv->mod->handler, priv->pos_interval);
+               }
+               break;
+       }
+       case PROP_VEL_INTERVAL: {
+               guint interval = g_value_get_uint(value);
+               LOCATION_LOGD("Set prop>> PROP_VEL_INTERVAL: %u", interval);
+               if (interval == priv->vel_interval) break;
+               priv->vel_interval = get_valid_interval(interval, LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_MIN);
+               break;
+       }
+       case PROP_LOC_INTERVAL: {
+               guint interval = g_value_get_uint(value);
+               LOCATION_LOGD("Set prop>> PROP_LOC_INTERVAL: %u", interval);
+               if (interval == priv->loc_interval) break;
+
+               priv->loc_interval = get_valid_interval(interval, LOCATION_UPDATE_INTERVAL_MAX, LOCATION_UPDATE_INTERVAL_MIN);
+               priv->optimized_interval = priv->loc_interval;
+
+               if (__get_started(object) == TRUE) {
+                       LOCATION_LOGD("[update_pos_interval]: update loc-interval while loc-tracking");
+                       g_return_if_fail(priv->mod->ops.set_position_update_interval);
+                       priv->mod->ops.set_position_update_interval(priv->mod->handler, priv->loc_interval);
+               }
+
+               break;
+       }
+       case PROP_MIN_INTERVAL: {
+               guint interval = g_value_get_uint(value);
+               LOCATION_LOGD("Set prop>> PROP_MIN_INTERVAL: %u", interval);
+               priv->min_interval = interval;
+               break;
+       }
+       case PROP_MIN_DISTANCE: {
+               gdouble distance = g_value_get_double(value);
+               LOCATION_LOGD("Set prop>> PROP_MIN_DISTANCE: %f", distance);
+               priv->min_distance = distance;
+               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;
+       }
+}
+
+void location_fused_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+       LOC_FUNC_LOG
+       LocationFusedPrivate *priv = GET_PRIVATE(object);
+       g_return_if_fail(priv);
+
+       switch (property_id) {
+       case PROP_METHOD_TYPE:
+               g_value_set_int(value, LOCATION_METHOD_FUSED);
+               break;
+       case PROP_IS_STARTED:
+               g_value_set_boolean(value, __get_started(object));
+               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;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+               break;
+       }
+
+}
+
+static int location_fused_get_position_ext(LocationFused *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
+{
+       LOC_FUNC_LOG
+       LocationFusedPrivate *priv = GET_PRIVATE(self);
+       g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
+       setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
+
+       LOC_COND_RET(__get_started(self) != TRUE, LOCATION_ERROR_NOT_AVAILABLE, _E, "Fused not started. Error[%s]", err_msg(LOCATION_ERROR_NOT_AVAILABLE));
+       int ret = LOCATION_ERROR_NONE;
+
+       if (position && priv->pos)
+               *position = location_position_copy(priv->pos);
+
+       if (velocity && priv->vel)
+               *velocity = location_velocity_copy(priv->vel);
+
+       if (accuracy) {
+               if (priv->acc)
+                       *accuracy = location_accuracy_copy(priv->acc);
+               else
+                       *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+       }
+
+       if (position && (priv->pos == NULL))
+               ret = LOCATION_ERROR_NOT_AVAILABLE;
+
+       if (velocity && (priv->vel == NULL))
+               ret = LOCATION_ERROR_NOT_AVAILABLE;
+
+       return ret;
+}
+
+static int location_fused_get_position(LocationFused *self, LocationPosition **position, LocationAccuracy **accuracy)
+{
+       LOC_FUNC_LOG
+       return location_fused_get_position_ext(self, position, NULL, accuracy);
+}
+
+static int location_fused_get_velocity(LocationFused *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
+{
+       LOC_FUNC_LOG
+       return location_fused_get_position_ext(self, NULL, velocity, accuracy);
+}
+
+static int location_fused_get_last_position_ext(LocationFused *self, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
+{
+       LOC_FUNC_LOG
+       LocationFusedPrivate *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);
+       setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
+
+       if (__get_started(self) == TRUE) {
+               return location_fused_get_position_ext(self, position, velocity, accuracy);
+       } else {
+
+               int ret = LOCATION_ERROR_NONE;
+
+               LocModFusedOps ops = priv->mod->ops;
+               g_return_val_if_fail(ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
+               ret = ops.get_last_position(priv->mod->handler, position, velocity, accuracy);
+               return ret;
+       }
+}
+
+static int location_fused_get_last_position(LocationFused *self, LocationPosition **position, LocationAccuracy **accuracy)
+{
+       LOC_FUNC_LOG
+       return location_fused_get_last_position_ext(self, position, NULL, accuracy);
+}
+
+static int location_fused_get_last_velocity(LocationFused *self, LocationVelocity **velocity, LocationAccuracy **accuracy)
+{
+       LOC_FUNC_LOG
+       return location_fused_get_last_position_ext(self, NULL, velocity, accuracy);
+}
+
+static int location_fused_get_satellite(LocationFused *self, LocationSatellite **satellite)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_get_last_satellite(LocationFused *self, LocationSatellite **satellite)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_get_batch(LocationFused *self, LocationBatch **batch)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_start_batch(LocationFused *self)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_stop_batch(LocationFused *self)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_request_single_location(LocationFused *self, int timeout)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_cancel_single_location(LocationFused *self)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_get_nmea(LocationFused *self, char **nmea_data)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int
+location_fused_set_mock_location(LocationFused *self, LocationPosition *position, LocationVelocity *velocity, LocationAccuracy *accuracy)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_clear_mock_location(LocationFused *self)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_set_option(LocationFused *self, const char *option)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
+static int location_fused_set_fused_mode(LocationFused *self, LocationFusedMode mode)
+{
+       LOC_FUNC_LOG
+       g_return_val_if_fail(self, LOCATION_ERROR_PARAMETER);
+       LocationFusedPrivate *priv = GET_PRIVATE(self);
+       g_return_val_if_fail(priv, LOCATION_ERROR_NOT_AVAILABLE);
+
+       if (priv->fused_mode != mode) {
+               priv->fused_mode = mode;
+       }
+       return LOCATION_ERROR_NONE;
+}
+
+static void location_ielement_interface_init(LocationIElementInterface *iface)
+{
+       LOC_FUNC_LOG
+       g_return_if_fail(iface);
+       iface->start = (TYPE_START_FUNC) location_fused_start;
+       iface->stop = (TYPE_STOP_FUNC) location_fused_stop;
+       iface->get_position = (TYPE_GET_POSITION) location_fused_get_position;
+       iface->get_position_ext = (TYPE_GET_POSITION_EXT) location_fused_get_position_ext;
+       iface->get_last_position = (TYPE_GET_POSITION) location_fused_get_last_position;
+       iface->get_last_position_ext = (TYPE_GET_POSITION_EXT) location_fused_get_last_position_ext;
+       iface->get_velocity = (TYPE_GET_VELOCITY) location_fused_get_velocity;
+       iface->get_last_velocity = (TYPE_GET_VELOCITY) location_fused_get_last_velocity;
+       iface->set_option = (TYPE_SET_OPTION) location_fused_set_option;
+       iface->set_fused_mode = (TYPE_SET_FUSED_MODE) location_fused_set_fused_mode;
+       iface->get_satellite = (TYPE_GET_SATELLITE) location_fused_get_satellite;
+       iface->get_last_satellite = (TYPE_GET_SATELLITE) location_fused_get_last_satellite;
+       iface->get_batch = (TYPE_GET_BATCH) location_fused_get_batch;
+       iface->start_batch = (TYPE_START_BATCH) location_fused_start_batch;
+       iface->stop_batch = (TYPE_STOP_BATCH) location_fused_stop_batch;
+       iface->request_single_location = (TYPE_REQUEST_SINGLE_LOCATION) location_fused_request_single_location;
+       iface->cancel_single_location = (TYPE_CANCEL_SINGLE_LOCATION) location_fused_cancel_single_location;
+       iface->get_nmea = (TYPE_GET_NMEA) location_fused_get_nmea;
+       iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_fused_set_mock_location;
+       iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_fused_clear_mock_location;
+}
+
+static void location_fused_init(LocationFused *self)
+{
+       LOC_FUNC_LOG
+       g_return_if_fail(self);
+       LocationFusedPrivate *priv = GET_PRIVATE(self);
+       g_return_if_fail(priv);
+
+       priv->mod = (LocationFusedMod *)module_new("fused");
+       LOC_COND_LOG(!priv->mod, _E, "Module loading failed");
+
+       __set_started(self, 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->optimized_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
+       priv->min_interval = LOCATION_UPDATE_INTERVAL_NONE;
+       priv->min_distance = LOCATION_MIN_DISTANCE_DEFAULT;
+
+       priv->pos_updated_timestamp = 0;
+       priv->vel_updated_timestamp = 0;
+       priv->loc_updated_timestamp = 0;
+
+       priv->boundary_list = NULL;
+       priv->fused_mode = LOCATION_FUSED_HIGH;
+       priv->app_type = location_get_app_type(NULL);
+       LOC_COND_LOG(priv->app_type == 0, _W, "Fail to get app_type");
+}
+
+static void location_fused_class_init(LocationFusedClass *klass)
+{
+       LOC_FUNC_LOG
+       g_return_if_fail(klass);
+       GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+       gobject_class->set_property = location_fused_set_property;
+       gobject_class->get_property = location_fused_get_property;
+       gobject_class->dispose      = location_fused_dispose;
+       gobject_class->finalize     = location_fused_finalize;
+
+       g_type_class_add_private(klass, sizeof(LocationFusedPrivate));
+
+       signals[SERVICE_ENABLED]  = g_signal_new("service-enabled",  G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, G_STRUCT_OFFSET(LocationFusedClass, 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(LocationFusedClass, disabled),         NULL, NULL, location_VOID__UINT,                        G_TYPE_NONE, 1, G_TYPE_UINT);
+       signals[SERVICE_UPDATED]  = g_signal_new("service-updated",  G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, G_STRUCT_OFFSET(LocationFusedClass, 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(LocationFusedClass, 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(LocationFusedClass, 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(LocationFusedClass, 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 (fused)", LOCATION_METHOD_FUSED, LOCATION_METHOD_FUSED, LOCATION_METHOD_FUSED, G_PARAM_READABLE);
+       properties[PROP_IS_STARTED]       = g_param_spec_boolean("is_started",     "fused is started prop",        "status of the fused location", FALSE, G_PARAM_READWRITE);
+       properties[PROP_LAST_POSITION]    = g_param_spec_boxed("last-position",    "fused last position prop",     "last fused position", LOCATION_TYPE_POSITION, G_PARAM_READABLE);
+       properties[PROP_POS_INTERVAL]     = g_param_spec_uint("pos-interval",      "pos-int prop",                 "desired signaling interval of position", 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",      "vel-int prop",                 "desired signaling interval of velocity", 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",      "loc-int prop",                 "desired signaling interval of entire location", 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",      "min-int prop",                 "minimal signaling interval", 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",    "min-dist prop",                "minimal signaling distance", LOCATION_MIN_DISTANCE_MIN, LOCATION_MIN_DISTANCE_MAX, LOCATION_MIN_DISTANCE_DEFAULT, G_PARAM_READWRITE);
+       properties[PROP_BOUNDARY]         = g_param_spec_pointer("boundary",       "fused boundary prop",          "fused boundary data", G_PARAM_READWRITE);
+       properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary", "fused removal boundary prop",  "fused removal boundary data", LOCATION_TYPE_BOUNDARY, G_PARAM_READWRITE);
+       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-fused.h b/location/manager/location-fused.h
new file mode 100644 (file)
index 0000000..8ab4fb2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * libslp-location
+ *
+ * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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.
+ */
+
+/**
+ * @file location-fused.h
+ * @brief This file contains the internal definitions and structures related to FUSED.
+ */
+
+#ifndef __LOCATION_FUSED_H__
+#define __LOCATION_FUSED_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define FEATURE_PRIVATE_LOCATION_COPY   0
+
+#define LOCATION_TYPE_FUSED             (location_fused_get_type())
+#define LOCATION_FUSED(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), LOCATION_TYPE_FUSED, LocationFused))
+#define LOCATION_IS_FUSED(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), LOCATION_TYPE_FUSED))
+#define LOCATION_FUSED_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),  LOCATION_TYPE_FUSED, LocationFusedClass))
+#define LOCATION_IS_FUSED_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),  LOCATION_TYPE_FUSED))
+#define LOCATION_FUSED_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj),  LOCATION_TYPE_FUSED, LocationFusedClass))
+
+typedef struct _LocationFused          LocationFused;
+typedef struct _LocationFusedClass     LocationFusedClass;
+
+struct _LocationFused {
+       GObject parent_instance;
+};
+
+struct _LocationFusedClass {
+       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_fused_get_type(void);
+
+
+G_END_DECLS
+
+#endif
old mode 100755 (executable)
new mode 100644 (file)
index 60d746a..611d7ce
@@ -46,7 +46,6 @@ typedef struct _LocationGpsPrivate {
        gboolean                        is_mock;
        gboolean                        set_noti;
        gboolean                        enabled;
-       gint                            signal_type;
        guint                           app_type;
        guint                           pos_updated_timestamp;
        guint                           vel_updated_timestamp;
@@ -140,8 +139,6 @@ static void __reset_pos_data_from_priv(LocationGpsPrivate *priv)
        priv->vel_updated_timestamp = 0;
        priv->sat_updated_timestamp = 0;
        priv->loc_updated_timestamp = 0;
-
-       priv->signal_type = 0;
 }
 
 static gboolean __get_started(gpointer self)
@@ -1104,6 +1101,13 @@ location_gps_clear_mock_location(LocationGps *self)
        return ret;
 }
 
+static int
+location_gps_set_fused_mode(LocationGps *self, LocationFusedMode mode)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
 static void location_ielement_interface_init(LocationIElementInterface *iface)
 {
        iface->start = (TYPE_START_FUNC)location_gps_start;
@@ -1125,6 +1129,7 @@ static void location_ielement_interface_init(LocationIElementInterface *iface)
        iface->get_nmea = (TYPE_GET_NMEA)location_gps_get_nmea;
        iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_gps_set_mock_location;
        iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_gps_clear_mock_location;
+       iface->set_fused_mode = (TYPE_SET_FUSED_MODE) location_gps_set_fused_mode;
 }
 
 static void location_gps_init(LocationGps *self)
@@ -1142,7 +1147,6 @@ static void location_gps_init(LocationGps *self)
        priv->is_mock = FALSE;
        priv->set_noti = FALSE;
        priv->enabled = FALSE;
-       priv->signal_type = 0;
 
        priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
        priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
old mode 100755 (executable)
new mode 100644 (file)
index da74da2..3ad0150
@@ -1119,6 +1119,13 @@ location_hybrid_clear_mock_location(LocationHybrid *self)
        return ret;
 }
 
+static int
+location_hybrid_set_fused_mode(LocationHybrid *self, LocationFusedMode mode)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
 static void
 location_ielement_interface_init(LocationIElementInterface *iface)
 {
@@ -1139,6 +1146,7 @@ location_ielement_interface_init(LocationIElementInterface *iface)
 
        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;
+       iface->set_fused_mode = (TYPE_SET_FUSED_MODE) location_hybrid_set_fused_mode;
 }
 
 static void
old mode 100755 (executable)
new mode 100644 (file)
index a6d6617..acc0339
@@ -260,3 +260,11 @@ int location_ielement_clear_mock_location(LocationIElement *self)
        return LOCATION_IELEMENT_GET_INTERFACE(self)->clear_mock_location(self);
 }
 
+int location_ielement_set_fused_mode(LocationIElement *self, LocationFusedMode mode)
+{
+       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)->set_fused_mode, LOCATION_ERROR_NOT_AVAILABLE);
+
+       return LOCATION_IELEMENT_GET_INTERFACE(self)->set_fused_mode(self, mode);
+}
index 07a3be7..f9891a1 100644 (file)
@@ -75,6 +75,7 @@ typedef int (*TYPE_GET_NMEA)(LocationIElement *self, char **nmea);
 /* Tizen 3.0 */
 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);
+typedef int (*TYPE_SET_FUSED_MODE)(LocationIElement *self, LocationFusedMode mode);
 
 struct _LocationIElementInterface {
        GTypeInterface parent_iface;
@@ -100,6 +101,7 @@ struct _LocationIElementInterface {
        /* Tizen 3.0 */
        TYPE_SET_MOCK_LOCATION set_mock_location;
        TYPE_CLEAR_MOCK_LOCATION clear_mock_location;
+       TYPE_SET_FUSED_MODE set_fused_mode;
 };
 
 GType location_ielement_get_type(void);
@@ -125,6 +127,7 @@ int location_ielement_get_nmea(LocationIElement *self, char **nmea);
 /* Tizen 3.0 */
 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);
+int location_ielement_set_fused_mode(LocationIElement *self, LocationFusedMode mode);
 
 G_END_DECLS
 
old mode 100755 (executable)
new mode 100644 (file)
index b58d087..6c3cb80
@@ -637,6 +637,12 @@ static int location_passive_clear_mock_location(LocationPassive *self)
        return LOCATION_ERROR_NOT_SUPPORTED;
 }
 
+static int location_passive_set_fused_mode(LocationPassive *self, LocationFusedMode mode)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
 static void location_ielement_interface_init(LocationIElementInterface *iface)
 {
        iface->start = (TYPE_START_FUNC)location_passive_start;
@@ -655,6 +661,7 @@ static void location_ielement_interface_init(LocationIElementInterface *iface)
        iface->get_nmea = (TYPE_GET_NMEA)location_passive_get_nmea;
        iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_passive_set_mock_location;
        iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_passive_clear_mock_location;
+       iface->set_fused_mode = (TYPE_SET_FUSED_MODE) location_passive_set_fused_mode;
 }
 
 static void location_passive_init(LocationPassive *self)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 2c4d7ed..7881851
@@ -783,6 +783,13 @@ location_wps_clear_mock_location(LocationWps *self)
        return ret;
 }
 
+static int
+location_wps_set_fused_mode(LocationWps *self, LocationFusedMode mode)
+{
+       LOC_FUNC_LOG
+       return LOCATION_ERROR_NOT_SUPPORTED;
+}
+
 static void
 location_ielement_interface_init(LocationIElementInterface *iface)
 {
@@ -802,6 +809,7 @@ location_ielement_interface_init(LocationIElementInterface *iface)
        iface->get_nmea = (TYPE_GET_NMEA)location_wps_get_nmea;
        iface->set_mock_location = (TYPE_SET_MOCK_LOCATION) location_wps_set_mock_location;
        iface->clear_mock_location = (TYPE_CLEAR_MOCK_LOCATION) location_wps_clear_mock_location;
+       iface->set_fused_mode = (TYPE_SET_FUSED_MODE) location_wps_set_fused_mode;
 }
 
 static void
old mode 100755 (executable)
new mode 100644 (file)
index 9b09046..3417abd
@@ -35,6 +35,7 @@
 #include "location-gps.h"
 #include "location-wps.h"
 #include "location-passive.h"
+#include "location-fused.h"
 #include "location-position.h"
 #include "module-internal.h"
 #include "location-common-util.h"
@@ -135,6 +136,9 @@ location_new(LocationMethod method, gboolean multi_handle)
        case LOCATION_METHOD_PASSIVE:
                self = g_object_new(LOCATION_TYPE_PASSIVE, NULL);
                break;
+       case LOCATION_METHOD_FUSED:
+               self = g_object_new(LOCATION_TYPE_FUSED, NULL);
+               break;
        default:
                break;
        }
@@ -261,8 +265,11 @@ location_is_supported_method(LocationMethod method)
        case LOCATION_METHOD_PASSIVE:
                is_supported = module_is_supported("passive");
                break;
+       case LOCATION_METHOD_FUSED:
+               is_supported = module_is_supported("fused");
+               break;
        default:
-                       break;
+               break;
        }
 
        return is_supported;
@@ -717,6 +724,18 @@ location_clear_mock_location(LocationObject *obj)
 }
 
 EXPORT_API int
+location_set_fused_mode(LocationObject *obj, LocationFusedMode mode)
+{
+       g_return_val_if_fail(obj, LOCATION_ERROR_PARAMETER);
+
+       int ret = LOCATION_ERROR_NONE;
+       ret = location_ielement_set_fused_mode(LOCATION_IELEMENT(obj), mode);
+       LOC_IF_FAIL(ret, _E, "Fail to set_fused_mode [%s]", err_msg(ret));
+
+       return ret;
+}
+
+EXPORT_API int
 location_enable_restriction(const int enable)
 {
        int ret = LOCATION_ERROR_NONE;
old mode 100755 (executable)
new mode 100644 (file)
index bfc595e..e3ca65a
@@ -308,6 +308,18 @@ int location_clear_mock_location(LocationObject *obj);
 int location_enable_restriction(const int enable);
 
 /**
+ * @brief
+ * Set the measurement method in FUSED mode.
+ *
+ * @param [in] obj  - an #LocationObject created by #location_new()
+ * @param [in] mode - one of the three options {HIGH, BALANCED, NOPOWER}
+ *                    listed in #LocationFusedMode enumeration.
+ *
+ * @return Zero upon success; one of the #LocationError codes otherwise.
+ */
+int location_set_fused_mode(LocationObject *obj, LocationFusedMode mode);
+
+/**
  * @} @}
  */
 
index d6e377e..d577d84 100644 (file)
@@ -107,6 +107,14 @@ typedef struct {
        int (*get_satellite)(gpointer handle, LocationSatellite **satellite);
 } LocModPassiveOps;
 
+typedef struct {
+       int (*start_gps)(gpointer handle, guint pos_update_interval, LocModStatusCB status_cb, LocModPositionExtCB pos_ext_cb, LocModSatelliteCB sat_cb, gpointer userdata);
+       int (*start_wps)(gpointer handle, guint pos_update_interval, LocModStatusCB status_cb, LocModPositionExtCB pos_ext_cb, LocModSatelliteCB sat_cb, gpointer userdata);
+       int (*stop)(gpointer handle);
+       int (*get_last_position)(gpointer handle, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy);
+       int (*set_position_update_interval)(gpointer handle, guint interval);
+} LocModFusedOps;
+
 /**
  * @brief This is used for exported APIs in a plug-in for a location framework.
  */
index e97d738..1f6c107 100755 (executable)
@@ -130,7 +130,7 @@ static gpointer mod_new(const char *module_name)
                _mod->shutdown = shutdown;
                _mod->handler = _mod->init(&(_mod->ops));
                if (!_mod->handler) {
-                       LOCATION_LOGW("module init failed");
+                       LOCATION_LOGW("module init failed : gps");
                        gmod_free(_mod->gmod);
                        ret_mod = NULL;
                } else
@@ -142,7 +142,7 @@ static gpointer mod_new(const char *module_name)
                _mod->shutdown = shutdown;
                _mod->handler = _mod->init(&(_mod->ops));
                if (!_mod->handler) {
-                       LOCATION_LOGW("module init failed");
+                       LOCATION_LOGW("module init failed : wps");
                        gmod_free(_mod->gmod);
                        ret_mod = NULL;
                } else
@@ -154,7 +154,19 @@ static gpointer mod_new(const char *module_name)
                _mod->shutdown = shutdown;
                _mod->handler = _mod->init(&(_mod->ops));
                if (!_mod->handler) {
-                       LOCATION_LOGW("module init failed");
+                       LOCATION_LOGW("module init failed : passive");
+                       gmod_free(_mod->gmod);
+                       ret_mod = NULL;
+               } else
+                       ret_mod = (gpointer) _mod;
+       } else if (g_str_has_prefix(module_name, "fused")) {
+               LocationFusedMod *_mod = g_new0(LocationFusedMod, 1);
+               _mod->gmod = gmod;
+               _mod->init = init;
+               _mod->shutdown = shutdown;
+               _mod->handler = _mod->init(&(_mod->ops));
+               if (!_mod->handler) {
+                       LOCATION_LOGW("module init failed : fused");
                        gmod_free(_mod->gmod);
                        ret_mod = NULL;
                } else
@@ -201,6 +213,16 @@ static void mod_free(gpointer mod, const char *module_name)
                _mod->shutdown = NULL;
                gmod_free(_mod->gmod);
                _mod->gmod = NULL;
+       } else if (0 == g_strcmp0(module_name, "fused")) {
+               LocationFusedMod *_mod = (LocationFusedMod *) 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);
        }
index 25e4a8f..0fbc623 100644 (file)
@@ -62,6 +62,14 @@ typedef struct {
        LocModPassiveOps ops;
 } LocationPassiveMod;
 
+typedef struct {
+       GMod *gmod;
+       gpointer handler;
+       gpointer(*init)(LocModFusedOps *ops);
+       void (*shutdown)(gpointer handle);
+       LocModFusedOps ops;
+} LocationFusedMod;
+
 gboolean module_init(void);
 gpointer module_new(const char *module_name);
 void module_free(gpointer mod, const char *module_name);
index 3b3b949..2c8b8c9 100755 (executable)
@@ -1,6 +1,6 @@
 Name: liblbs-location
 Summary: Location Based Service Library
-Version: 1.3.13
+Version: 1.4.0
 Release: 1
 Group: Location/Libraries
 License: Apache-2.0