Fix a crash after changes that velocity is updated before position
[platform/core/location/lbs-location.git] / location / manager / location-common-util.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <stdio.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 #include <location-appman.h>
30
31 #include "location.h"
32 #include "location-common-util.h"
33 #include "location-setting.h"
34 #include "location-log.h"
35
36
37 int location_application_enabled (void)
38 {
39         pid_t pid = getpid();
40         location_appman_s *appman;
41         int enabled;
42         int found;
43         time_t timestamp;
44
45         if (TRUE == location_appman_check_developer_mode()) {
46                 LOCATION_LOGE("Location is Enabled");
47                 return TRUE;
48         }
49
50         if (location_appman_get_package_by_pid(pid, &appman) != LOCATION_APPMAN_ERROR_NONE) {
51                 LOCATION_LOGE("Fail to location_appman_get_package_by_pid");
52                 return FALSE;
53         }
54
55         if (location_appman_find_package(appman->package, &found) != LOCATION_APPMAN_ERROR_NONE) {
56                 LOCATION_LOGE("Cannot find package [%s]", appman->package);
57                 return FALSE;
58         }
59
60         if (found == LOCATION_APPMAN_PACKAGE_NOTFOUND) {
61                 LOCATION_LOGD("First time to use location [%s]", appman->package);
62                 if (location_appman_register_package(appman) != LOCATION_APPMAN_ERROR_NONE) {
63                         LOCATION_LOGE("Fail to register [%s]", appman->package);
64                         return FALSE;
65                 }
66         } else {
67                 LOCATION_LOGD("[%s] is already registered. Update recently used time", appman->package);
68                 time(&timestamp);
69                 if (location_appman_set_recently_used(appman->package, timestamp) != LOCATION_APPMAN_ERROR_NONE) {
70                         LOCATION_LOGD("Cannot update recently used time");
71                 }
72         }
73
74         if (location_appman_is_enabled(appman->package, &enabled) != LOCATION_APPMAN_ERROR_NONE) {
75                 LOCATION_LOGE("Fail to location_appman_is_enabled");
76                 return FALSE;
77         }
78         return enabled;
79 }
80
81 static gint compare_position (gconstpointer a, gconstpointer b)
82 {
83         g_return_val_if_fail(a, 1);
84         g_return_val_if_fail(b, -1);
85
86         if(location_position_equal((LocationPosition*) a, (LocationPosition *)b) == TRUE) {
87                 return 0;
88         }
89
90         return -1;
91 }
92
93 static int
94 boundary_compare (gconstpointer comp1, gconstpointer comp2)
95 {
96         g_return_val_if_fail(comp1, 1);
97         g_return_val_if_fail(comp2, -1);
98
99         int ret = -1;
100
101         LocationBoundary *boundary1 = (LocationBoundary *)comp1;
102         LocationBoundary *boundary2 = (LocationBoundary *)comp2;
103
104         if (boundary1->type == boundary2->type) {
105                 switch (boundary1->type) {
106                         case LOCATION_BOUNDARY_CIRCLE: {
107                                 if (location_position_equal(boundary1->circle.center, boundary2->circle.center)
108                                         && boundary1->circle.radius == boundary2->circle.radius) {
109                                         ret = 0;
110                                 }
111                                 break;
112                         }
113                         case LOCATION_BOUNDARY_RECT: {
114                                 if (location_position_equal(boundary1->rect.left_top, boundary2->rect.left_top)
115                                         && location_position_equal(boundary1->rect.right_bottom, boundary2->rect.right_bottom)) {
116                                         ret = 0;
117                                 }
118                                 break;
119                         }
120                         case LOCATION_BOUNDARY_POLYGON: {
121
122                                 GList *boundary1_next = NULL;
123                                 GList *boundary2_start = NULL, *boundary2_prev = NULL, *boundary2_next = NULL;
124                                 if (g_list_length(boundary1->polygon.position_list) != g_list_length(boundary2->polygon.position_list)) {
125                                         return -1;
126                                 }
127
128                                 // Find a matching index of Boundary2 with Boundary1's 1st postion.
129                                 boundary2_start = g_list_find_custom(boundary2->polygon.position_list, g_list_nth_data(boundary1->polygon.position_list, 0), (GCompareFunc) compare_position);
130                                 if (boundary2_start == NULL) return -1;
131
132                                 boundary2_prev = g_list_previous(boundary2_start);
133                                 boundary2_next = g_list_next(boundary2_start);
134                                 if (boundary2_prev == NULL) boundary2_prev = g_list_last(boundary2->polygon.position_list);
135                                 if (boundary2_next == NULL) boundary2_next = g_list_first(boundary2->polygon.position_list);
136
137                                 boundary1_next = g_list_next(boundary1->polygon.position_list);
138                                 if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*)boundary2_prev->data) == TRUE){
139                                         boundary1_next = g_list_next(boundary1_next);
140                                         while (boundary1_next) {
141                                                 boundary2_prev = g_list_previous(boundary2_prev);
142                                                 if (boundary2_prev == NULL) boundary2_prev = g_list_last(boundary2->polygon.position_list);
143                                                 if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*) boundary2_prev->data) == FALSE){
144                                                         return -1;
145                                                 }
146                                                 boundary1_next = g_list_next(boundary1_next);
147                                         }
148                                         ret = 0;
149                                 }
150                                 else if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*)boundary2_next->data) == TRUE) {
151                                         boundary1_next = g_list_next(boundary1_next);
152                                         while(boundary1_next) {
153                                                 boundary2_next = g_list_next(boundary2_next);
154                                                 if (boundary2_next == NULL) boundary2_next = g_list_first(boundary2->polygon.position_list);
155                                                 if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*) boundary2_next->data) == FALSE){
156                                                         return -1;
157                                                 }
158                                                 boundary1_next = g_list_next(boundary1_next);
159                                         }
160                                         ret = 0;
161                                 }
162                                 else {
163                                         return -1;
164                                 }
165                                 break;
166                         }
167                         default:{
168                                  ret = -1;
169                                  break;
170                         }
171
172                 }
173         }
174
175         return ret;
176 }
177
178 int set_prop_boundary(GList **prev_boundary_list, GList *new_boundary_list)
179 {
180         g_return_val_if_fail(new_boundary_list, LOCATION_ERROR_PARAMETER);
181
182         int index;
183         GList *check_list = NULL;
184
185         LocationBoundary *new_boundary = NULL;
186         LocationBoundary *copy_boundary = NULL;
187
188         index = 0;
189         while((new_boundary = (LocationBoundary*) g_list_nth_data(new_boundary_list, index)) != NULL) {
190
191                 check_list = g_list_find_custom(*prev_boundary_list, new_boundary, (GCompareFunc)boundary_compare);
192                 if (check_list == NULL) {
193                         LOCATION_LOGD("Set Prop >> boundary type: [%d]", new_boundary->type);
194                         copy_boundary = location_boundary_copy(new_boundary);
195                         *prev_boundary_list = g_list_append(*prev_boundary_list, copy_boundary);
196                 }
197                 index++;
198         }
199         *prev_boundary_list = g_list_first(*prev_boundary_list);
200
201         return LOCATION_ERROR_NONE;
202 }
203
204
205
206 int set_prop_removal_boundary(GList **prev_boundary_list, LocationBoundary* boundary)
207 {
208         g_return_val_if_fail(*prev_boundary_list, LOCATION_ERROR_PARAMETER);
209
210         GList *check_list = NULL;
211
212         check_list = g_list_find_custom (*prev_boundary_list, boundary, (GCompareFunc) boundary_compare);
213         if (check_list) {
214                 LOCATION_LOGD("Found");
215                 *prev_boundary_list = g_list_delete_link(*prev_boundary_list, check_list);
216         }
217
218         if (g_list_length(*prev_boundary_list) == 0 ) {
219                 LOCATION_LOGD("Boundary List is empty");
220                 g_list_free(*prev_boundary_list);
221                 *prev_boundary_list = NULL;
222         }
223
224         return LOCATION_ERROR_NONE;
225 }
226
227 void free_boundary_list (gpointer data)
228 {
229         LocationBoundary *boundary = (LocationBoundary *)data;
230
231         location_boundary_free(boundary);
232 }
233