merge with master
[platform/core/location/lbs-location.git] / location / manager / location-common-util.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
7  *          Genie Kim <daejins.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 int location_application_get_authority (void)
37 {
38         pid_t pid = getpid();
39         location_appman_s *appman;
40         int enabled;
41         int found;
42
43         if (location_appman_get_package_by_pid(pid, &appman) != LOCATION_APPMAN_ERROR_NONE) {
44                 LOCATION_LOGE("Fail to location_appman_get_package_by_pid");
45                 return LOCATION_APP_NOT_FOUND;
46         }
47
48         if (location_appman_find_package(appman->package, &found) != LOCATION_APPMAN_ERROR_NONE || found == LOCATION_APPMAN_PACKAGE_NOTFOUND) {
49                 LOCATION_LOGE("Cannot find package [%s]", appman->package);
50                 return LOCATION_APP_NOT_FOUND;
51         }
52
53         if (location_appman_is_enabled(appman->package, &enabled) != LOCATION_APPMAN_ERROR_NONE) {
54                 LOCATION_LOGE("Fail to location_appman_is_enabled");
55                 return LOCATION_APP_NOT_FOUND;
56         }
57
58         if (enabled) {
59                 return LOCATION_APP_ON;
60         }
61         else {
62                 return LOCATION_APP_OFF;
63
64         }
65
66         return LOCATION_APP_NOT_FOUND;
67 }
68
69 int location_application_set_authority (int auth)
70 {
71         pid_t pid = getpid();
72         location_appman_s *appman;
73         int enabled;
74         int found;
75
76         if (location_appman_get_package_by_pid(pid, &appman) != LOCATION_APPMAN_ERROR_NONE) {
77                 LOCATION_LOGE("Fail to location_appman_get_package_by_pid");
78                 return LOCATION_ERROR_UNKNOWN;
79         }
80
81         if (location_appman_find_package(appman->package, &found) != LOCATION_APPMAN_ERROR_NONE || found == LOCATION_APPMAN_PACKAGE_NOTFOUND) {
82                 LOCATION_LOGE("Cannot find package [%s]", appman->package);
83                 return LOCATION_ERROR_UNKNOWN;
84         }
85
86         if (location_appman_set_on(appman->package, auth) != LOCATION_APPMAN_ERROR_NONE) {
87                 LOCATION_LOGE("Fail to location_appman_is_enabled");
88                 return LOCATION_ERROR_UNKNOWN;
89         }
90
91         return LOCATION_ERROR_NONE;
92 }
93
94 int location_application_add_app_to_applist (void)
95 {
96         pid_t pid = getpid();
97         location_appman_s *appman;
98         int found;
99         time_t timestamp;
100
101         if (location_appman_get_package_by_pid(pid, &appman) != LOCATION_APPMAN_ERROR_NONE) {
102                 LOCATION_LOGE("Fail to location_appman_get_package_by_pid");
103                 return FALSE;
104         }
105
106         if (location_appman_find_package(appman->package, &found) != LOCATION_APPMAN_ERROR_NONE) {
107                 LOCATION_LOGE("Cannot find package [%s]", appman->package);
108                 if (appman) g_free(appman);
109                 return FALSE;
110         }
111
112         if (found == LOCATION_APPMAN_PACKAGE_NOTFOUND) {
113                 LOCATION_LOGD("First time to use location [%s]", appman->package);
114                 if (location_appman_register_package(appman) != LOCATION_APPMAN_ERROR_NONE) {
115                         LOCATION_LOGE("Fail to register [%s]", appman->package);
116                         if (appman) g_free(appman);
117                         return FALSE;
118                 }
119         } else {
120                 LOCATION_LOGD("[%s] is already registered. Update recently used time", appman->package);
121                 if (appman) g_free(appman);
122                 return FALSE;
123         }
124
125         if (appman) g_free(appman);
126         return TRUE;
127 }
128
129 int location_application_enabled (void)
130 {
131         pid_t pid = getpid();
132         location_appman_s *appman;
133         int enabled;
134         int found;
135         time_t timestamp;
136
137         if (TRUE == location_appman_check_developer_mode()) {
138                 LOCATION_LOGE("Location is Enabled");
139                 return TRUE;
140         }
141
142         if (location_appman_get_package_by_pid(pid, &appman) != LOCATION_APPMAN_ERROR_NONE) {
143                 LOCATION_LOGE("Fail to location_appman_get_package_by_pid");
144                 return FALSE;
145         }
146
147         if (location_appman_find_package(appman->package, &found) != LOCATION_APPMAN_ERROR_NONE) {
148                 LOCATION_LOGE("Cannot find package [%s]", appman->package);
149                 if (appman) g_free(appman);
150                 return FALSE;
151         }
152
153         if (found == LOCATION_APPMAN_PACKAGE_NOTFOUND) {
154                 LOCATION_LOGD("First time to use location [%s]", appman->package);
155                 if (location_appman_register_package(appman) != LOCATION_APPMAN_ERROR_NONE) {
156                         LOCATION_LOGE("Fail to register [%s]", appman->package);
157                         if (appman) g_free(appman);
158                         return FALSE;
159                 }
160         } else {
161                 LOCATION_LOGD("[%s] is already registered. Update recently used time", appman->package);
162                 time(&timestamp);
163                 if (location_appman_set_recently_used(appman->package, timestamp) != LOCATION_APPMAN_ERROR_NONE) {
164                         LOCATION_LOGD("Cannot update recently used time");
165                 }
166         }
167
168         if (location_appman_is_enabled(appman->package, &enabled) != LOCATION_APPMAN_ERROR_NONE) {
169                 LOCATION_LOGE("Fail to location_appman_is_enabled");
170                 if (appman) g_free(appman);
171                 return FALSE;
172         }
173
174         if (appman) g_free(appman);
175         return enabled;
176 }
177
178 static gint compare_position (gconstpointer a, gconstpointer b)
179 {
180         g_return_val_if_fail(a, 1);
181         g_return_val_if_fail(b, -1);
182
183         if(location_position_equal((LocationPosition*) a, (LocationPosition *)b) == TRUE) {
184                 return 0;
185         }
186
187         return -1;
188 }
189
190 static int
191 boundary_compare (gconstpointer comp1, gconstpointer comp2)
192 {
193         g_return_val_if_fail(comp1, 1);
194         g_return_val_if_fail(comp2, -1);
195
196         int ret = -1;
197
198         LocationBoundaryPrivate *priv1 = (LocationBoundaryPrivate *)comp1;
199         LocationBoundaryPrivate *priv2 = (LocationBoundaryPrivate *)comp2;
200
201         if (priv1->boundary->type == priv2->boundary->type) {
202                 switch (priv1->boundary->type) {
203                         case LOCATION_BOUNDARY_CIRCLE: {
204                                 if (location_position_equal(priv1->boundary->circle.center, priv2->boundary->circle.center)
205                                         && priv1->boundary->circle.radius == priv2->boundary->circle.radius) {
206                                         ret = 0;
207                                 }
208                                 break;
209                         }
210                         case LOCATION_BOUNDARY_RECT: {
211                                 if (location_position_equal(priv1->boundary->rect.left_top, priv2->boundary->rect.left_top)
212                                         && location_position_equal(priv1->boundary->rect.right_bottom, priv2->boundary->rect.right_bottom)) {
213                                         ret = 0;
214                                 }
215                                 break;
216                         }
217                         case LOCATION_BOUNDARY_POLYGON: {
218                                 GList *boundary1_next = NULL;
219                                 GList *boundary2_start = NULL, *boundary2_prev = NULL, *boundary2_next = NULL;
220                                 if (g_list_length(priv1->boundary->polygon.position_list) != g_list_length(priv2->boundary->polygon.position_list)) {
221                                         return -1;
222                                 }
223
224                                 // Find a matching index of Boundary2 with Boundary1's 1st postion.
225                                 boundary2_start = g_list_find_custom(priv2->boundary->polygon.position_list, g_list_nth_data(priv1->boundary->polygon.position_list, 0), (GCompareFunc) compare_position);
226                                 if (boundary2_start == NULL) return -1;
227
228                                 boundary2_prev = g_list_previous(boundary2_start);
229                                 boundary2_next = g_list_next(boundary2_start);
230                                 if (boundary2_prev == NULL) boundary2_prev = g_list_last(priv2->boundary->polygon.position_list);
231                                 if (boundary2_next == NULL) boundary2_next = g_list_first(priv2->boundary->polygon.position_list);
232
233                                 boundary1_next = g_list_next(priv1->boundary->polygon.position_list);
234                                 if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*)boundary2_prev->data) == TRUE){
235                                         boundary1_next = g_list_next(boundary1_next);
236                                         while (boundary1_next) {
237                                                 boundary2_prev = g_list_previous(boundary2_prev);
238                                                 if (boundary2_prev == NULL) boundary2_prev = g_list_last(priv2->boundary->polygon.position_list);
239                                                 if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*) boundary2_prev->data) == FALSE){
240                                                         return -1;
241                                                 }
242                                                 boundary1_next = g_list_next(boundary1_next);
243                                         }
244                                         ret = 0;
245                                 }
246                                 else if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*)boundary2_next->data) == TRUE) {
247                                         boundary1_next = g_list_next(boundary1_next);
248                                         while(boundary1_next) {
249                                                 boundary2_next = g_list_next(boundary2_next);
250                                                 if (boundary2_next == NULL) boundary2_next = g_list_first(priv2->boundary->polygon.position_list);
251                                                 if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*) boundary2_next->data) == FALSE){
252                                                         return -1;
253                                                 }
254                                                 boundary1_next = g_list_next(boundary1_next);
255                                         }
256                                         ret = 0;
257                                 }
258                                 else {
259                                         return -1;
260                                 }
261                                 break;
262                         }
263                         default:{
264                                  ret = -1;
265                                  break;
266                         }
267
268                 }
269         }
270
271         return ret;
272 }
273
274 int set_prop_boundary(GList **prev_boundary_priv_list, GList *new_boundary_priv_list)
275 {
276         g_return_val_if_fail(new_boundary_priv_list, LOCATION_ERROR_PARAMETER);
277
278         int index = 0;
279         GList *check_list = NULL;
280
281         LocationBoundaryPrivate *new_priv = NULL;
282         LocationBoundaryPrivate *copy_priv = g_slice_new0(LocationBoundaryPrivate);
283
284         while((new_priv = (LocationBoundaryPrivate *) g_list_nth_data(new_boundary_priv_list, index)) != NULL) {
285                 check_list = g_list_find_custom(*prev_boundary_priv_list, new_priv, (GCompareFunc)boundary_compare);
286                 if (check_list == NULL) {
287                         LOCATION_LOGD("Set Prop >> boundary type: [%d]", new_priv->boundary->type);
288                         copy_priv->boundary = location_boundary_copy(new_priv->boundary);
289                         copy_priv->zone_status = new_priv->zone_status;
290                         *prev_boundary_priv_list = g_list_append(*prev_boundary_priv_list, copy_priv);
291                 }
292                 index++;
293         }
294         *prev_boundary_priv_list = g_list_first(*prev_boundary_priv_list);
295
296         return LOCATION_ERROR_NONE;
297 }
298
299 int set_prop_removal_boundary(GList **prev_boundary_list, LocationBoundary* boundary)
300 {
301         g_return_val_if_fail(*prev_boundary_list, LOCATION_ERROR_PARAMETER);
302
303         GList *check_list = NULL;
304         LocationBoundaryPrivate *remove_priv = g_slice_new0(LocationBoundaryPrivate);
305
306         remove_priv->boundary = location_boundary_copy(boundary);
307
308         check_list = g_list_find_custom (*prev_boundary_list, remove_priv, (GCompareFunc) boundary_compare);
309         if (check_list) {
310                 LOCATION_LOGD("Found");
311                 *prev_boundary_list = g_list_delete_link(*prev_boundary_list, check_list);
312         }
313
314         if (g_list_length(*prev_boundary_list) == 0 ) {
315                 LOCATION_LOGD("Boundary List is empty");
316                 g_list_free(*prev_boundary_list);
317                 *prev_boundary_list = NULL;
318         }
319
320         g_slice_free(LocationBoundaryPrivate, remove_priv);
321         return LOCATION_ERROR_NONE;
322 }
323
324 void free_boundary_list (gpointer data)
325 {
326         LocationBoundaryPrivate *priv= (LocationBoundaryPrivate *)data;
327
328         location_boundary_free(priv->boundary);
329         g_slice_free(LocationBoundaryPrivate, priv);
330 }