Add option to execute unittest in building package
[platform/core/uifw/capi-ui-sticker.git] / client / sticker_provider.c
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <dlog.h>
21 #include <app_common.h>
22 #include <package_manager.h>
23
24 #include "sticker_provider.h"
25 #include "sticker_provider_main.h"
26 #include "sticker_dbus.h"
27
28 #ifdef LOG_TAG
29 #undef LOG_TAG
30 #endif
31 #define LOG_TAG "STICKER_PROVIDER"
32
33 EXPORT_API int sticker_provider_create(sticker_provider_h *provider_handle)
34 {
35     CHECK_STICKER_FEATURE();
36
37     int ret;
38     if (!provider_handle)
39         return STICKER_ERROR_INVALID_PARAMETER;
40
41     struct sticker_provider_s *provider_struct = (sticker_provider_h)calloc(1, sizeof(struct sticker_provider_s));
42
43     if (!provider_struct)
44         return STICKER_ERROR_OUT_OF_MEMORY;
45
46     ret = sticker_dbus_init(&provider_struct->gdbus_connection, &provider_struct->server_watcher_id,
47         &provider_struct->monitor_id, &provider_struct->server_monitor_id, STICKER_CLIENT_LIB_PROVIDER, (void *)provider_struct);
48     if (ret != STICKER_ERROR_NONE) {
49         //LCOV_EXCL_START
50         LOGE("Failed to initialize dbus : %d", ret);
51         free(provider_struct);
52         return STICKER_ERROR_OPERATION_FAILED;
53         //LCOV_EXCL_STOP
54     }
55
56     *provider_handle = provider_struct;
57
58     return STICKER_ERROR_NONE;
59 }
60
61 EXPORT_API int sticker_provider_destroy(sticker_provider_h provider_handle)
62 {
63     CHECK_STICKER_FEATURE();
64
65     int ret;
66     if (!provider_handle)
67         return STICKER_ERROR_INVALID_PARAMETER;
68
69     LOGD("provider_handle : %p", provider_handle);
70     ret = sticker_dbus_shutdown(provider_handle->gdbus_connection, &provider_handle->server_watcher_id,
71                                 &provider_handle->server_monitor_id, &provider_handle->monitor_id, STICKER_CLIENT_LIB_PROVIDER);
72     if (ret != STICKER_ERROR_NONE) {
73         //LCOV_EXCL_START
74         LOGE("Failed to finalize dbus : %d", ret);
75         free(provider_handle);
76         return STICKER_ERROR_OPERATION_FAILED;
77         //LCOV_EXCL_STOP
78     }
79
80     if (provider_handle->gdbus_connection)
81         g_object_unref(provider_handle->gdbus_connection);
82
83     free(provider_handle);
84
85     return STICKER_ERROR_NONE;
86 }
87
88 EXPORT_API int sticker_provider_insert_data(sticker_provider_h provider_handle, sticker_data_h data_handle)
89 {
90     CHECK_STICKER_FEATURE();
91
92     int ret;
93     int is_exist = 0;
94
95     if (!provider_handle || !data_handle || (data_handle->sticker_info_id > 0) || !data_handle->uri)
96         return STICKER_ERROR_INVALID_PARAMETER;
97
98     int len = strlen(STICKER_DIRECTORY) + strlen(data_handle->app_id) + strlen(data_handle->uri) + 3;
99     char *new_path = (char *)calloc(len, sizeof(char));
100     if (!new_path) {
101         return STICKER_ERROR_OUT_OF_MEMORY;
102     }
103
104     if (data_handle->uri[0] == '/')
105         snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, data_handle->app_id, data_handle->uri);
106     else
107         snprintf(new_path, len, "%s/%s/%s",STICKER_DIRECTORY, data_handle->app_id, data_handle->uri);
108
109     ret = sticker_dbus_check_file_exists(provider_handle->gdbus_connection, new_path, &is_exist);
110     if (ret != STICKER_ERROR_NONE) {
111         LOGE("Failed to check file exists : %d", ret);
112         ret = STICKER_ERROR_OPERATION_FAILED;
113         goto cleanup;
114     }
115
116     if (is_exist) {
117         LOGE("Sticker already exists");
118         ret = STICKER_ERROR_FILE_EXISTS;
119         goto cleanup;
120     }
121
122     ret = sticker_dbus_insert_sticker_info(provider_handle->gdbus_connection, data_handle);
123     if (ret != STICKER_ERROR_NONE) {
124         LOGE("Failed to insert sticker information : %d", ret);
125         if (ret == STICKER_CLIENT_ERROR_NO_SUCH_FILE)
126             ret = STICKER_ERROR_NO_SUCH_FILE;
127         else
128             ret = STICKER_ERROR_OPERATION_FAILED;
129     }
130
131 cleanup:
132     if (new_path) {
133         free(new_path);
134         new_path = NULL;
135     }
136
137     return ret;
138 }
139
140 EXPORT_API int sticker_provider_insert_data_by_json_file(sticker_provider_h provider_handle, const char *json_path, sticker_provider_insert_finished_cb callback, void *user_data)
141 {
142     CHECK_STICKER_FEATURE();
143
144     int ret;
145     char *app_id = NULL;
146     package_info_h package_info = NULL;
147     char *app_path = NULL;
148     char *file_path = NULL;
149
150     if (!provider_handle || !json_path || !callback)
151         return STICKER_ERROR_INVALID_PARAMETER;
152
153     ret = app_get_id(&app_id);
154     if (ret != APP_ERROR_NONE) {
155         LOGE("Failed to get app_id : %d", ret); //LCOV_EXCL_LINE
156         ret = STICKER_ERROR_OPERATION_FAILED;
157         goto cleanup;
158     }
159
160     if (access(json_path, F_OK) != 0) {
161         ret = package_info_create(app_id, &package_info);
162         if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
163             LOGE("failed to create package_info. ret: %d", ret); //LCOV_EXCL_LINE
164             ret = STICKER_ERROR_OPERATION_FAILED;
165             goto cleanup;
166         }
167
168         ret = package_info_get_root_path(package_info, &app_path);
169         if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
170             LOGE("failed to create package_info. ret: %d", ret); //LCOV_EXCL_LINE
171             ret = STICKER_ERROR_OPERATION_FAILED;
172             goto cleanup;
173         }
174
175         int path_len = strlen(app_path) + strlen(json_path) + 2;
176         file_path = (char *)calloc(path_len, sizeof(char));
177         if (!file_path) {
178             LOGE("failed to alloc memory"); //LCOV_EXCL_LINE
179             ret = STICKER_ERROR_OPERATION_FAILED;
180             goto cleanup;
181         }
182
183         if (json_path[0] == '/')
184             snprintf(file_path, path_len, "%s%s",app_path, json_path);
185         else
186             snprintf(file_path, path_len, "%s%s%s",app_path, "/", json_path);
187
188         if (access(file_path, F_OK) != 0) {
189             LOGE("%s does not exist", file_path);
190             ret = STICKER_ERROR_INVALID_PARAMETER;
191             goto cleanup;
192         }
193     } else
194         file_path = strdup(json_path);
195
196     SECURE_LOGD("json path : %s", file_path);
197     ret = sticker_dbus_insert_sticker_info_by_json(provider_handle->gdbus_connection, app_id, file_path);
198     if (ret != STICKER_ERROR_NONE) {
199         LOGE("Failed to load json file : %d", ret);
200         ret = STICKER_ERROR_OPERATION_FAILED;
201         goto cleanup;
202     }
203
204     provider_handle->insert_finished_cb = callback;
205     provider_handle->insert_finished_cb_user_data = user_data;
206
207 cleanup:
208     if (app_id)
209         free(app_id);
210
211     if (package_info)
212         package_info_destroy(package_info);
213
214     if (app_path)
215         free(app_path);
216
217     if (file_path)
218         free(file_path);
219
220     return ret;
221 }
222
223 EXPORT_API int sticker_provider_update_data(sticker_provider_h provider_handle, sticker_data_h data_handle)
224 {
225     CHECK_STICKER_FEATURE();
226
227     int ret;
228     if (!provider_handle || !data_handle || (data_handle->sticker_info_id <= 0))
229         return STICKER_ERROR_INVALID_PARAMETER;
230
231     ret = sticker_dbus_update_sticker_info(provider_handle->gdbus_connection, data_handle);
232     if (ret != STICKER_ERROR_NONE) {
233         //LCOV_EXCL_START
234         LOGE("Failed to update sticker information : %d", ret);
235         if (ret == STICKER_CLIENT_ERROR_FILE_EXISTS)
236             return STICKER_ERROR_FILE_EXISTS;
237         else if (ret == STICKER_CLIENT_ERROR_NO_SUCH_FILE)
238             return STICKER_ERROR_NO_SUCH_FILE;
239         else
240             return STICKER_ERROR_OPERATION_FAILED;
241         //LCOV_EXCL_STOP
242     }
243
244     return STICKER_ERROR_NONE;
245 }
246
247 EXPORT_API int sticker_provider_delete_data(sticker_provider_h provider_handle, sticker_data_h data_handle)
248 {
249     CHECK_STICKER_FEATURE();
250
251     int ret;
252     if (!provider_handle || !data_handle || (data_handle->sticker_info_id <= 0))
253         return STICKER_ERROR_INVALID_PARAMETER;
254
255     ret = sticker_dbus_delete_sticker_info(provider_handle->gdbus_connection, data_handle->sticker_info_id);
256     if (ret != STICKER_ERROR_NONE) {
257         LOGE("Failed to delete sticker information : %d", ret);
258         return STICKER_ERROR_OPERATION_FAILED;
259     }
260
261     return STICKER_ERROR_NONE;
262 }
263
264 EXPORT_API int sticker_provider_get_sticker_count(sticker_provider_h provider_handle, int *count)
265 {
266     CHECK_STICKER_FEATURE();
267
268     int ret;
269     char *app_id = NULL;
270
271     if (!provider_handle || !count)
272         return STICKER_ERROR_INVALID_PARAMETER;
273
274     ret = app_get_id(&app_id);
275     if (ret != APP_ERROR_NONE) {
276         LOGE("Failed to get app_id : %d", ret); //LCOV_EXCL_LINE
277         ret = STICKER_ERROR_OPERATION_FAILED;
278         goto cleanup;
279     }
280
281     ret = sticker_dbus_get_sticker_count(provider_handle->gdbus_connection, app_id, count);
282     if (ret != STICKER_ERROR_NONE) {
283         LOGE("Failed to get sticker count : %d", ret);
284         ret = STICKER_ERROR_OPERATION_FAILED;
285     }
286
287 cleanup:
288     if (app_id)
289         free(app_id);
290
291     return ret;
292 }
293
294 EXPORT_API int sticker_provider_data_foreach_all(sticker_provider_h provider_handle, int offset, int count, int *result, sticker_provider_data_foreach_cb callback, void *user_data)
295 {
296     CHECK_STICKER_FEATURE();
297
298     int ret;
299     int info_id;
300     int sticker_count = 0;
301     char *app_id = NULL;
302     GVariantIter *id_iter = NULL;
303
304     if (!provider_handle || (offset < 0) || (count <= 0) || !result || !callback)
305         return STICKER_ERROR_INVALID_PARAMETER;
306
307     ret = app_get_id(&app_id);
308     if (ret != APP_ERROR_NONE) {
309         LOGE("Failed to get app_id : %d", ret); //LCOV_EXCL_LINE
310         ret = STICKER_ERROR_OPERATION_FAILED;
311         goto cleanup;
312     }
313
314     ret = sticker_dbus_get_sticker_info_by_appid(provider_handle->gdbus_connection, app_id, offset, count, &id_iter);
315     if (ret != STICKER_ERROR_NONE) {
316         LOGE("Failed to get sticker information : %d", ret);
317         ret = STICKER_ERROR_OPERATION_FAILED;
318         goto cleanup;
319     }
320
321     if (id_iter) {
322         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
323             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
324             if (!sticker_data) {
325                 ret = STICKER_ERROR_OUT_OF_MEMORY;
326                 goto cleanup;
327             }
328
329             ret = sticker_dbus_get_sticker_info_by_record_id(provider_handle->gdbus_connection, sticker_data, info_id);
330             if (ret == STICKER_ERROR_NONE) {
331                 sticker_count++;
332                 callback(sticker_data, user_data);
333                 sticker_data_destroy(sticker_data);
334             } else {
335                 sticker_data_destroy(sticker_data);
336                 goto cleanup;
337             }
338         }
339     }
340
341     *result = sticker_count;
342
343 cleanup:
344     if (app_id)
345         free(app_id);
346
347     if (id_iter)
348         g_variant_iter_free(id_iter);
349
350     return ret;
351 }
352
353 EXPORT_API int sticker_provider_delete_data_by_uri(sticker_provider_h provider_handle, const char *uri)
354 {
355     CHECK_STICKER_FEATURE();
356
357     int ret;
358     int is_exist = 0;
359
360     if (!provider_handle || !uri)
361         return STICKER_ERROR_INVALID_PARAMETER;
362
363     ret = sticker_dbus_check_file_exists(provider_handle->gdbus_connection, uri, &is_exist);
364     if (ret != STICKER_ERROR_NONE) {
365         LOGE("Failed to check file exists : %d", ret);
366         return STICKER_ERROR_OPERATION_FAILED;
367     }
368
369     if (!is_exist) {
370         LOGE("Sticker does not exist");
371         return STICKER_ERROR_NO_SUCH_FILE;
372     }
373
374     ret = sticker_dbus_delete_sticker_info_by_uri(provider_handle->gdbus_connection, uri);
375     if (ret != STICKER_ERROR_NONE) {
376         LOGE("Failed to delete sticker information : %d", ret);
377         return STICKER_ERROR_OPERATION_FAILED;
378     }
379
380     return STICKER_ERROR_NONE;
381 }
382
383 EXPORT_API int sticker_provider_set_group_image(sticker_provider_h provider_handle, const char *group, sticker_data_uri_type_e type, const char *uri)
384 {
385     CHECK_STICKER_FEATURE();
386
387     int ret;
388     int is_exist = 0;
389     char *app_id = NULL;
390     package_info_h package_info = NULL;
391     char *app_path = NULL;
392     char *file_path = NULL;
393
394     if (!provider_handle || !group || !uri)
395         return STICKER_ERROR_INVALID_PARAMETER;
396
397     ret = app_get_id(&app_id);
398     if (ret != APP_ERROR_NONE) {
399         LOGE("Failed to get app_id : %d", ret); //LCOV_EXCL_LINE
400         ret = STICKER_ERROR_OPERATION_FAILED;
401         goto cleanup;
402     }
403
404     ret = sticker_dbus_check_group_exists(provider_handle->gdbus_connection, app_id, group, &is_exist);
405     if (ret != STICKER_ERROR_NONE) {
406         LOGE("Failed to check group exists : %d", ret);
407         ret = STICKER_ERROR_OPERATION_FAILED;
408         goto cleanup;
409     }
410
411     if (!is_exist) {
412         LOGE("Group name does not exist");
413         ret = STICKER_ERROR_INVALID_PARAMETER;
414         goto cleanup;
415     }
416
417     if (type == STICKER_DATA_URI_LOCAL_PATH) {
418         ret = package_info_create(app_id, &package_info);
419         if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
420             LOGE("failed to create package_info. ret: %d", ret); //LCOV_EXCL_LINE
421             ret = STICKER_ERROR_OPERATION_FAILED;
422             goto cleanup;
423         }
424
425         ret = package_info_get_root_path(package_info, &app_path);
426         if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
427             LOGE("failed to create package_info. ret: %d", ret); //LCOV_EXCL_LINE
428             ret = STICKER_ERROR_OPERATION_FAILED;
429             goto cleanup;
430         }
431
432         int path_len = strlen(app_path) + strlen(uri) + 2;
433         file_path = (char *)calloc(path_len, sizeof(char));
434         if (!file_path) {
435             LOGE("failed to alloc memory"); //LCOV_EXCL_LINE
436             ret = STICKER_ERROR_OPERATION_FAILED;
437             goto cleanup;
438         }
439
440         if (uri[0] == '/')
441             snprintf(file_path, path_len, "%s%s",app_path, uri);
442         else
443             snprintf(file_path, path_len, "%s%s%s",app_path, "/", uri); //LCOV_EXCL_LINE
444
445         if (access(file_path, F_OK) != 0) {
446             LOGE("%s does not exist", file_path);
447             ret = STICKER_ERROR_NO_SUCH_FILE;
448             goto cleanup;
449         }
450     }
451
452     ret = sticker_dbus_set_group_image(provider_handle->gdbus_connection, app_id, group, type, file_path ? file_path : uri);
453     if (ret != STICKER_ERROR_NONE) {
454         LOGE("Failed to set group image : %d", ret);
455         if (ret == STICKER_CLIENT_ERROR_NO_SUCH_FILE)
456             ret = STICKER_ERROR_NO_SUCH_FILE;
457         else
458             ret = STICKER_ERROR_OPERATION_FAILED;
459     }
460
461 cleanup:
462     if (app_id) {
463         free(app_id);
464         app_id = NULL;
465     }
466
467     if (package_info)
468         package_info_destroy(package_info);
469
470     if (app_path) {
471         free(app_path);
472         app_path = NULL;
473     }
474
475     if (file_path) {
476         free(file_path);
477         file_path = NULL;
478     }
479
480     return ret;
481 }