Support the event callback to send sticker DB changes
[platform/core/uifw/capi-ui-sticker.git] / provider / 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 static void _free_sticker_data(sticker_data_h sticker_data)
34 {
35     if (sticker_data->app_id) {
36         free(sticker_data->app_id);
37         sticker_data->app_id = NULL;
38     }
39
40     if (sticker_data->uri) {
41         free(sticker_data->uri);
42         sticker_data->uri = NULL;
43     }
44
45     if (sticker_data->thumbnail) {
46         free(sticker_data->thumbnail);
47         sticker_data->thumbnail = NULL;
48     }
49
50     if (sticker_data->keyword) {
51         g_list_free_full(sticker_data->keyword, free);
52         sticker_data->keyword = NULL;
53     }
54
55     if (sticker_data->group) {
56         free(sticker_data->group);
57         sticker_data->group = NULL;
58     }
59
60     if (sticker_data->description) {
61         free(sticker_data->description);
62         sticker_data->description = NULL;
63     }
64
65     if (sticker_data->date) {
66         free(sticker_data->date);
67         sticker_data->date = NULL;
68     }
69
70     free(sticker_data);
71     sticker_data = NULL;
72 }
73
74 EXPORT_API int sticker_provider_create(sticker_provider_h *provider_handle)
75 {
76     CHECK_STICKER_FEATURE();
77
78     int ret;
79     if (!provider_handle)
80         return STICKER_ERROR_INVALID_PARAMETER;
81
82     struct sticker_provider_s *provider_struct = (sticker_provider_h)calloc(1, sizeof(struct sticker_provider_s));
83
84     if (!provider_struct)
85         return STICKER_ERROR_OUT_OF_MEMORY;
86
87     ret = sticker_dbus_init(&provider_struct->gdbus_connection, &provider_struct->server_watcher_id,
88         &provider_struct->monitor_id, &provider_struct->server_monitor_id, STICKER_CLIENT_LIB_PROVIDER, (void *)provider_struct);
89     if (ret != STICKER_ERROR_NONE) {
90         LOGE("Failed to initialize dbus : %d", ret);
91         free(provider_struct);
92         return STICKER_ERROR_OPERATION_FAILED;
93     }
94
95     *provider_handle = provider_struct;
96
97     return STICKER_ERROR_NONE;
98 }
99
100 EXPORT_API int sticker_provider_destroy(sticker_provider_h provider_handle)
101 {
102     CHECK_STICKER_FEATURE();
103
104     int ret;
105     if (!provider_handle)
106         return STICKER_ERROR_INVALID_PARAMETER;
107
108     LOGD("provider_handle : %p", provider_handle);
109     ret = sticker_dbus_shutdown(provider_handle->gdbus_connection, &provider_handle->server_watcher_id,
110                                 &provider_handle->server_monitor_id, &provider_handle->monitor_id, STICKER_CLIENT_LIB_PROVIDER);
111     if (ret != STICKER_ERROR_NONE) {
112         LOGE("Failed to finalize dbus : %d", ret);
113         free(provider_handle);
114         return STICKER_ERROR_OPERATION_FAILED;
115     }
116
117     if (provider_handle->gdbus_connection)
118         g_object_unref(provider_handle->gdbus_connection);
119
120     free(provider_handle);
121
122     return STICKER_ERROR_NONE;
123 }
124
125 EXPORT_API int sticker_provider_insert_data(sticker_provider_h provider_handle, sticker_data_h data_handle)
126 {
127     CHECK_STICKER_FEATURE();
128
129     int ret;
130     int is_exist = 0;
131
132     if (!provider_handle || !data_handle || (data_handle->sticker_info_id > 0) || !data_handle->uri)
133         return STICKER_ERROR_INVALID_PARAMETER;
134
135     ret = sticker_dbus_check_file_exists(provider_handle->gdbus_connection, data_handle->uri, &is_exist);
136     if (ret != STICKER_ERROR_NONE) {
137         LOGE("Failed to check file exists : %d", ret);
138         return STICKER_ERROR_OPERATION_FAILED;
139     }
140
141     if (is_exist) {
142         LOGE("Sticker already exists");
143         return STICKER_ERROR_FILE_EXISTS;
144     }
145
146     ret = sticker_dbus_insert_sticker_info(provider_handle->gdbus_connection, data_handle);
147     if (ret != STICKER_ERROR_NONE) {
148         LOGE("Failed to insert sticker information : %d", ret);
149         if (ret == STICKER_CLIENT_ERROR_NO_SUCH_FILE)
150             return STICKER_ERROR_NO_SUCH_FILE;
151         else
152             return STICKER_ERROR_OPERATION_FAILED;
153     }
154     return STICKER_ERROR_NONE;
155 }
156
157 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)
158 {
159     CHECK_STICKER_FEATURE();
160
161     int ret;
162     char *app_id = NULL;
163     package_info_h package_info = NULL;
164     char *app_path = NULL;
165     char *file_path = NULL;
166
167     if (!provider_handle || !json_path || !callback)
168         return STICKER_ERROR_INVALID_PARAMETER;
169
170     ret = app_get_id(&app_id);
171     if (ret != APP_ERROR_NONE) {
172         LOGE("Failed to get app_id : %d", ret);
173         ret = STICKER_ERROR_OPERATION_FAILED;
174         goto cleanup;
175     }
176
177     if (access(json_path, F_OK) != 0) {
178         ret = package_info_create(app_id, &package_info);
179         if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
180             LOGE("failed to create package_info. ret: %d", ret);
181             ret = STICKER_ERROR_OPERATION_FAILED;
182             goto cleanup;
183         }
184
185         ret = package_info_get_root_path(package_info, &app_path);
186         if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
187             LOGE("failed to create package_info. ret: %d", ret);
188             ret = STICKER_ERROR_OPERATION_FAILED;
189             goto cleanup;
190         }
191
192         int path_len = strlen(app_path) + strlen(json_path) + 2;
193         file_path = (char *)calloc(path_len, sizeof(char));
194         if (!file_path) {
195             LOGE("failed to alloc memory");
196             ret = STICKER_ERROR_OPERATION_FAILED;
197             goto cleanup;
198         }
199
200         if(json_path[0] == '/')
201             snprintf(file_path, path_len, "%s%s",app_path, json_path);
202         else
203             snprintf(file_path, path_len, "%s%s%s",app_path, "/", json_path);
204
205         if (access(file_path, F_OK) != 0) {
206             LOGE("%s does not exist", file_path);
207             ret = STICKER_ERROR_INVALID_PARAMETER;
208             goto cleanup;
209         }
210     } else
211         file_path = strdup(json_path);
212
213     SECURE_LOGD("json path : %s", file_path);
214     ret = sticker_dbus_insert_sticker_info_by_json(provider_handle->gdbus_connection, app_id, file_path);
215     if (ret != STICKER_ERROR_NONE) {
216         LOGE("Failed to load json file : %d", ret);
217         ret = STICKER_ERROR_OPERATION_FAILED;
218         goto cleanup;
219     }
220
221     provider_handle->insert_finished_cb = callback;
222     provider_handle->insert_finished_cb_user_data = user_data;
223
224 cleanup:
225     if (app_id)
226         free(app_id);
227
228     if (package_info)
229         package_info_destroy(package_info);
230
231     if (app_path)
232         free(app_path);
233
234     if (file_path)
235         free(file_path);
236
237     return ret;
238 }
239
240 EXPORT_API int sticker_provider_update_data(sticker_provider_h provider_handle, sticker_data_h data_handle)
241 {
242     CHECK_STICKER_FEATURE();
243
244     int ret;
245     if (!provider_handle || !data_handle || (data_handle->sticker_info_id <= 0))
246         return STICKER_ERROR_INVALID_PARAMETER;
247
248     ret = sticker_dbus_update_sticker_info(provider_handle->gdbus_connection, data_handle);
249     if (ret != STICKER_ERROR_NONE) {
250         LOGE("Failed to update sticker information : %d", ret);
251         if (ret == STICKER_CLIENT_ERROR_FILE_EXISTS)
252             return STICKER_ERROR_FILE_EXISTS;
253         else if (ret == STICKER_CLIENT_ERROR_NO_SUCH_FILE)
254             return STICKER_ERROR_NO_SUCH_FILE;
255         else
256             return STICKER_ERROR_OPERATION_FAILED;
257     }
258
259     return STICKER_ERROR_NONE;
260 }
261
262 EXPORT_API int sticker_provider_delete_data(sticker_provider_h provider_handle, sticker_data_h data_handle)
263 {
264     CHECK_STICKER_FEATURE();
265
266     int ret;
267     if (!provider_handle || !data_handle || (data_handle->sticker_info_id <= 0))
268         return STICKER_ERROR_INVALID_PARAMETER;
269
270     ret = sticker_dbus_delete_sticker_info(provider_handle->gdbus_connection, data_handle->sticker_info_id);
271     if (ret != STICKER_ERROR_NONE) {
272         LOGE("Failed to delete sticker information : %d", ret);
273         return STICKER_ERROR_OPERATION_FAILED;
274     }
275
276     return STICKER_ERROR_NONE;
277 }
278
279 EXPORT_API int sticker_provider_get_sticker_count(sticker_provider_h provider_handle, int *count)
280 {
281     CHECK_STICKER_FEATURE();
282
283     int ret;
284     char *app_id = NULL;
285
286     if (!provider_handle || !count)
287         return STICKER_ERROR_INVALID_PARAMETER;
288
289     ret = app_get_id(&app_id);
290     if (ret != APP_ERROR_NONE) {
291         LOGE("Failed to get app_id : %d", ret);
292         ret = STICKER_ERROR_OPERATION_FAILED;
293         goto cleanup;
294     }
295
296     ret = sticker_dbus_get_sticker_count(provider_handle->gdbus_connection, app_id, count);
297     if (ret != STICKER_ERROR_NONE) {
298         LOGE("Failed to get sticker count : %d", ret);
299         ret = STICKER_ERROR_OPERATION_FAILED;
300     }
301
302 cleanup:
303     if (app_id)
304         free(app_id);
305
306     return ret;
307 }
308
309 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)
310 {
311     CHECK_STICKER_FEATURE();
312
313     int ret;
314     int info_id;
315     int sticker_count = 0;
316     char *app_id = NULL;
317     GVariantIter *id_iter = NULL;
318
319     if (!provider_handle || (offset < 0) || (count <= 0) || !result || !callback)
320         return STICKER_ERROR_INVALID_PARAMETER;
321
322     ret = app_get_id(&app_id);
323     if (ret != APP_ERROR_NONE) {
324         LOGE("Failed to get app_id : %d", ret);
325         ret = STICKER_ERROR_OPERATION_FAILED;
326         goto cleanup;
327     }
328
329     ret = sticker_dbus_get_sticker_info_by_appid(provider_handle->gdbus_connection, app_id, offset, count, &id_iter);
330     if (ret != STICKER_ERROR_NONE) {
331         LOGE("Failed to get sticker information : %d", ret);
332         ret = STICKER_ERROR_OPERATION_FAILED;
333         goto cleanup;
334     }
335
336     if (id_iter) {
337         while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
338             sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
339             if (!sticker_data) {
340                 ret = STICKER_ERROR_OUT_OF_MEMORY;
341                 goto cleanup;
342             }
343
344             ret = sticker_dbus_get_sticker_info_by_record_id(provider_handle->gdbus_connection, sticker_data, info_id);
345             if (ret == STICKER_ERROR_NONE) {
346                 sticker_count++;
347                 callback(sticker_data, user_data);
348                 _free_sticker_data(sticker_data);
349             } else {
350                 _free_sticker_data(sticker_data);
351                 goto cleanup;
352             }
353         }
354     }
355
356     *result = sticker_count;
357
358 cleanup:
359     if (app_id)
360         free(app_id);
361
362     if (id_iter)
363         g_variant_iter_free(id_iter);
364
365     return ret;
366 }
367
368 EXPORT_API int sticker_provider_delete_data_by_uri(sticker_provider_h provider_handle, const char *uri)
369 {
370     CHECK_STICKER_FEATURE();
371
372     int ret;
373     int is_exist = 0;
374
375     if (!provider_handle || !uri)
376         return STICKER_ERROR_INVALID_PARAMETER;
377
378     ret = sticker_dbus_check_file_exists(provider_handle->gdbus_connection, uri, &is_exist);
379     if (ret != STICKER_ERROR_NONE) {
380         LOGE("Failed to check file exists : %d", ret);
381         return STICKER_ERROR_OPERATION_FAILED;
382     }
383
384     if (!is_exist) {
385         LOGE("Sticker does not exist");
386         return STICKER_ERROR_NO_SUCH_FILE;
387     }
388
389     ret = sticker_dbus_delete_sticker_info_by_uri(provider_handle->gdbus_connection, uri);
390     if (ret != STICKER_ERROR_NONE) {
391         LOGE("Failed to delete sticker information : %d", ret);
392         return STICKER_ERROR_OPERATION_FAILED;
393     }
394
395     return STICKER_ERROR_NONE;
396 }