Support display_type
[platform/core/uifw/capi-ui-sticker.git] / sticker-parser / sticker-parser.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 <unistd.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <dlog.h>
22 #include <glib.h>
23 #include <json-glib/json-glib.h>
24 #include <pkgmgr-info.h>
25 #include <sqlite3.h>
26 #include <tzplatform_config.h>
27 #include <package_manager.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <errno.h>
31 #include <dirent.h>
32 #include <fcntl.h>
33
34 #ifndef EXPORT_API
35 #define EXPORT_API __attribute__((visibility("default")))
36 #endif
37
38 #ifdef LOG_TAG
39 #undef LOG_TAG
40 #endif
41 #define LOG_TAG "STICKER_PARSER"
42
43 #define STICKER_DIRECTORY tzplatform_mkpath(TZ_SYS_SHARE, "sticker-data")
44 #define STICKER_INFO_CREATE_TABLE "CREATE TABLE IF NOT EXISTS sticker_info(sticker_info_id INTEGER PRIMARY KEY AUTOINCREMENT, app_id TEXT NOT NULL, type INTEGER NOT NULL, uri TEXT NOT NULL, thumbnail TEXT, description TEXT, group_name TEXT NOT NULL, date TEXT NOT NULL, display_type INTEGER)"
45 #define STICKER_KEYWORD_INFO_CREATE_TABLE "CREATE TABLE IF NOT EXISTS sticker_keyword_info(keyword_id INTEGER PRIMARY KEY AUTOINCREMENT, sticker_info_id INTEGER, keyword TEXT NOT NULL, FOREIGN KEY (sticker_info_id) REFERENCES sticker_info(sticker_info_id) ON DELETE CASCADE)"
46 #define STICKER_WHITELIST_INFO_CREATE_TABLE "CREATE TABLE IF NOT EXISTS sticker_whitelist_info(whitelist_id INTEGER PRIMARY KEY AUTOINCREMENT, provider_id TEXT NOT NULL, consumer_id TEXT NOT NULL)"
47 #define UIFW_ID           502
48 #define APPFW_ID          301
49 #define MAX_ERROR_BUFFER  256
50
51 static char error_buffer[MAX_ERROR_BUFFER];
52 static gboolean is_corrupted = FALSE;
53
54 typedef struct metadata {
55     const char *key;
56     const char *value;
57 } metadata;
58
59 static char* __get_string_from_object(JsonObject *object, const char *key)
60 {
61     if (json_object_has_member(object, key) == false)
62         return NULL;
63
64     const char *str = json_object_get_string_member(object, key);
65     if (str != NULL)
66         return strdup(str);
67     else
68         return NULL;
69 }
70
71 static int __get_int_from_object(JsonObject *object, const char *key)
72 {
73     if (json_object_has_member(object, key) == false)
74         return -1;
75
76     int type = json_object_get_int_member(object, key);
77
78     return type;
79 }
80
81 static int __change_ownership(const char *path, int user, int group)
82 {
83     int ret;
84     uid_t uid = (uid_t)user;
85     gid_t gid = (gid_t)group;
86
87     ret = chown(path, uid, gid);
88     if (ret != 0) {
89         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
90         LOGE("chown() failed : %s", error_buffer);
91     }
92
93     return ret;
94 }
95
96 static void __recover_db()
97 {
98     int ret;
99     sqlite3 *db = NULL;
100     char *err = NULL;
101     const char *db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
102
103     LOGD("Start to recover sticker db");
104     if (unlink(db_path) == -1)
105         LOGE("Failed to remove db file");
106
107     ret = sqlite3_open_v2(db_path, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
108     if (ret != SQLITE_OK) {
109         LOGE("Failed to open db : %s", sqlite3_errmsg(db));
110         if (unlink(db_path) == -1)
111             LOGE("Failed to remove db file");
112         goto cleanup;
113     }
114
115     ret = sqlite3_exec(db, STICKER_INFO_CREATE_TABLE, NULL, NULL, &err);
116     if (ret != SQLITE_OK) {
117         LOGE("Failed to create sticker_info table : %s" , err);
118         goto cleanup;
119     }
120
121     ret = sqlite3_exec(db, STICKER_KEYWORD_INFO_CREATE_TABLE, NULL, NULL, &err);
122     if (ret != SQLITE_OK) {
123         LOGE("Failed to create sticker_keyword_info table : %s", err);
124         goto cleanup;
125     }
126
127     ret = sqlite3_exec(db, STICKER_WHITELIST_INFO_CREATE_TABLE, NULL, NULL, &err);
128     if (ret != SQLITE_OK) {
129         LOGE("Failed to create sticker_whitelist_info table : %s", err);
130         goto cleanup;
131     }
132
133     is_corrupted = FALSE;
134
135 cleanup:
136     if (err)
137         sqlite3_free(err);
138
139     if (db)
140         sqlite3_close(db);
141 }
142
143 static int __integrity_check_cb(void *pid, int argc, char **argv, char **notUsed)
144 {
145     if (strcmp(argv[0], "ok") != 0) {
146         LOGE("DB integrity check failed : %s", argv[0]);
147         is_corrupted = TRUE;
148         return -1;
149     }
150
151     LOGD("Result integrity : %s", argv[0]);
152     return 0;
153 }
154
155 static void __db_init()
156 {
157     int ret;
158     sqlite3 *db = NULL;
159     char *err = NULL;
160     const char *db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
161
162     ret = sqlite3_open_v2(db_path, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
163     if (ret != SQLITE_OK) {
164         LOGE("Failed to open db : %s", sqlite3_errmsg(db));
165         goto cleanup;
166     }
167
168     if (__change_ownership(db_path, UIFW_ID, UIFW_ID) != 0)
169         LOGE("failed to change ownership");
170
171     ret = sqlite3_exec(db, STICKER_INFO_CREATE_TABLE, NULL, NULL, &err);
172     if (ret != SQLITE_OK) {
173         LOGE("Failed to create sticker_info table : %s" , err);
174         goto cleanup;
175     }
176
177     ret = sqlite3_exec(db, STICKER_KEYWORD_INFO_CREATE_TABLE, NULL, NULL, &err);
178     if (ret != SQLITE_OK) {
179         LOGE("Failed to create sticker_keyword_info table : %s", err);
180         goto cleanup;
181     }
182
183     ret = sqlite3_exec(db, STICKER_WHITELIST_INFO_CREATE_TABLE, NULL, NULL, &err);
184     if (ret != SQLITE_OK) {
185         LOGE("Failed to create sticker_whitelist_info table : %s", err);
186         goto cleanup;
187     }
188
189     ret = sqlite3_exec(db, "PRAGMA journal_mode = WAL", NULL, NULL, &err);
190     if (ret != SQLITE_OK) {
191         LOGE("Failed to set journal_mode : %s", err);
192         goto cleanup;
193     }
194
195     ret = sqlite3_exec(db, "PRAGMA integrity_check", __integrity_check_cb, NULL, &err);
196     if (ret != SQLITE_OK)
197         LOGE("Failed to check integrity : %s", err);
198
199 cleanup:
200     if (err)
201         sqlite3_free(err);
202
203     if (db)
204         sqlite3_close(db);
205
206     if (ret == SQLITE_CORRUPT || ret == SQLITE_NOTADB || is_corrupted)
207         __recover_db();
208 }
209
210 static sqlite3 *__db_open(const char *path)
211 {
212     int ret;
213     sqlite3 *db = NULL;
214     char *err = NULL;
215
216     ret = sqlite3_open(path, &db);
217     if (ret != SQLITE_OK) {
218         LOGE("Failed to open db : %s", sqlite3_errmsg(db));
219         return NULL;
220     }
221
222     ret = sqlite3_exec(db, "PRAGMA foreign_keys = ON", NULL, NULL, &err);
223     if (ret != SQLITE_OK) {
224         LOGE("Failed to turn on foreign keys : %s", err);
225     }
226
227     if (err)
228         sqlite3_free(err);
229
230     return db;
231 }
232
233 static int __remove_app_path(char *uri, const char *app_path)
234 {
235     int n = 0;
236     int k = 0;
237     for (int i = 0; uri[i] != '\0'; i++) {
238         if (uri[i] == app_path[n]) {
239             k = i;
240             while (uri[i] == app_path[n]) {
241                 if (app_path[++n] == '\0') {
242                     for(; uri[k + n] != '\0'; k++) {
243                         uri[k] = uri[k + n];
244                     }
245                     uri[k] = '\0';
246                     return 1;
247                 }
248                 i++;
249             }
250             n = 0;
251             i--;
252         }
253     }
254     return 0;
255 }
256
257 static int __mkdirs(const char *path, mode_t mode)
258 {
259     int len = 0;
260     char prev_path[2048];
261     const char *tmp = path;
262
263     if (!path || strlen(path) > 2048)
264         return -1;
265
266     memset(prev_path, '\0', 2048);
267     while ((tmp = strchr(tmp, '/')) != NULL) {
268         len = tmp - path;
269         tmp++;
270
271         if (len == 0)
272             continue;
273
274         strncpy(prev_path, path, len);
275         prev_path[len] = 0x00;
276
277         if (mkdir(prev_path, mode) == -1) {
278             if (errno != EEXIST) {
279                 strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
280                 LOGE("directory create error : %s", error_buffer);
281                 return -1;
282             }
283         } else {
284             if (__change_ownership(prev_path, UIFW_ID, UIFW_ID) != 0)
285                 LOGE("failed to change ownership");
286         }
287     }
288
289     if (mkdir(prev_path, mode) == -1) {
290         if (errno != EEXIST) {
291             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
292             LOGE("directory create error : %s", error_buffer);
293             return -1;
294         }
295     } else {
296         if (__change_ownership(prev_path, UIFW_ID, UIFW_ID) != 0)
297             LOGE("failed to change ownership");
298     }
299     return 0;
300 }
301
302 static int __file_copy(const char *src, const char *dest)
303 {
304     int ret = 0;
305     int fd = -1, n_fd = -1;
306     char buf[4096];
307     int tmp_err = 0;
308     int size;
309
310     memset(buf, '\0', 4096);
311     fd = open(src, O_RDONLY);
312     n_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0755);
313
314     if (fd == -1 || n_fd == -1) {
315         tmp_err = errno;
316         ret = -1;
317         goto cleanup;
318     }
319
320     while((size = read(fd, buf, 4096))) {
321         if (size == -1) {
322             if(errno == EINTR)
323                 continue;
324
325             tmp_err = errno;
326             ret = -1;
327             goto cleanup;
328         }
329
330         while(write(n_fd, buf, size) == -1) {
331             if(errno == EINTR) {
332                 continue;
333             } else {
334                 tmp_err = errno;
335                 goto cleanup;
336             }
337         }
338     }
339
340 cleanup:
341     if (fd != -1)
342         close(fd);
343
344     if (n_fd != -1)
345         close(n_fd);
346
347     errno = tmp_err;
348     return ret;
349 }
350
351 static char* __convert_sticker_uri(const char *uri, const char *appid, const char *app_path)
352 {
353     int ret;
354     char *rel_path = strdup(uri);
355
356     __remove_app_path(rel_path, app_path);
357     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + strlen(rel_path) + 2;
358     char *new_path = (char *)calloc(len, sizeof(char));
359     if (new_path == NULL) {
360         free(rel_path);
361         rel_path = NULL;
362         return NULL;
363     }
364
365     snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, appid, rel_path);
366
367     if (access(new_path, F_OK) == 0) {
368         LOGE("sticker file already exists");
369         ret = -1;
370         goto cleanup;
371     }
372
373     ret = __mkdirs(new_path, 0755);
374     if (ret != 0) {
375         LOGE("directory create error");
376         goto cleanup;
377     }
378
379     if (__file_copy(uri, new_path) == -1) {
380         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
381         LOGE("failed to copy sticker file : %s", error_buffer);
382         ret = -1;
383         goto cleanup;
384     }
385
386     ret = unlink(uri);
387     if (ret != 0) {
388         strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
389         LOGE("failed to remove sticker file : %s", error_buffer);
390     }
391
392     if (__change_ownership(new_path, UIFW_ID, UIFW_ID) != 0)
393         LOGE("failed to change ownership");
394
395 cleanup:
396     free(rel_path);
397     rel_path = NULL;
398
399     if (ret == 0) {
400         return new_path;
401     } else {
402         free(new_path);
403         new_path = NULL;
404         return NULL;
405     }
406 }
407
408 static void __insert_sticker_info(const char *app_id, int type, const char *uri, const char *group, const char *thumbnail, const char *description, int disp_type)
409 {
410     int ret;
411     sqlite3 *db = NULL;
412     sqlite3_stmt *stmt = NULL;
413     const char *db_path;
414
415     db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
416     db = __db_open(db_path);
417     if (!db)
418         return;
419
420     ret = sqlite3_prepare_v2(db, "INSERT INTO sticker_info (app_id, type, uri, thumbnail, description, group_name, date, display_type) VALUES (?, ?, ?, ?, ?, ?, DateTime('now','localtime'), ?)",-1, &stmt, NULL);
421     if (ret == SQLITE_OK) {
422         sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
423         sqlite3_bind_int(stmt, 2, type);
424         sqlite3_bind_text(stmt, 3, uri, -1, SQLITE_TRANSIENT);
425         sqlite3_bind_text(stmt, 4, thumbnail, -1, SQLITE_TRANSIENT);
426         sqlite3_bind_text(stmt, 5, description, -1, SQLITE_TRANSIENT);
427         sqlite3_bind_text(stmt, 6, group, -1, SQLITE_TRANSIENT);
428         sqlite3_bind_int(stmt, 7, disp_type);
429
430         ret = sqlite3_step(stmt);
431         if (ret != SQLITE_OK && ret != SQLITE_DONE)
432             LOGE("sqlite3_step() failed : ret(%d)", ret);
433
434         if (sqlite3_changes(db) == 0)
435             LOGE("No changes to DB");
436
437         sqlite3_finalize(stmt);
438         sqlite3_close(db);
439     } else {
440         LOGE("failed to insert sticker information : %s", sqlite3_errmsg(db));
441         sqlite3_finalize(stmt);
442         sqlite3_close(db);
443     }
444
445     return;
446 }
447
448 static void __insert_sticker_keyword_info(const char *keyword)
449 {
450     int ret;
451     int record_id;
452     sqlite3 *db = NULL;
453     sqlite3_stmt *stmt = NULL;
454     const char *db_path;
455
456     db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
457     db = __db_open(db_path);
458     if (!db)
459         return;
460
461     ret = sqlite3_prepare_v2(db, "SELECT sticker_info_id FROM sticker_info ORDER BY sticker_info_id DESC LIMIT 1", -1, &stmt, NULL);
462     if (ret == SQLITE_OK) {
463         ret = sqlite3_step(stmt);
464         if (ret == SQLITE_ERROR) {
465             LOGE("sqlite3_step() failed : ret(%d)", ret);
466             sqlite3_finalize(stmt);
467             sqlite3_close(db);
468         } else {
469             record_id = sqlite3_column_int(stmt, 0);
470
471             sqlite3_finalize(stmt);
472             stmt = NULL;
473
474             ret = sqlite3_prepare_v2(db, "INSERT INTO sticker_keyword_info (sticker_info_id, keyword) VALUES (?, ?)", -1, &stmt, NULL);
475             if (ret == SQLITE_OK) {
476                 sqlite3_bind_int(stmt, 1, record_id);
477                 sqlite3_bind_text(stmt, 2, keyword, -1, SQLITE_TRANSIENT);
478
479                 ret = sqlite3_step(stmt);
480                 if (ret != SQLITE_OK && ret != SQLITE_DONE)
481                     LOGE("sqlite3_step() failed : ret(%d)", ret);
482
483                 if (sqlite3_changes(db) == 0)
484                     LOGE("No changes to DB");
485
486                 sqlite3_finalize(stmt);
487                 sqlite3_close(db);
488             } else {
489                 LOGE("fail to insert sticker keyword : %s", sqlite3_errmsg(db));
490                 sqlite3_finalize(stmt);
491                 sqlite3_close(db);
492             }
493         }
494     } else {
495         LOGE("fail to insert sticker information : %s", sqlite3_errmsg(db));
496         sqlite3_finalize(stmt);
497         sqlite3_close(db);
498     }
499
500     return;
501 }
502
503 static void __insert_sticker_whitelist_info(const char *provider, const char *consumer) {
504     int ret;
505     sqlite3 *db = NULL;
506     sqlite3_stmt *stmt = NULL;
507     const char *db_path;
508
509     db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
510     db = __db_open(db_path);
511     if (!db)
512         return;
513
514     ret = sqlite3_prepare_v2(db, "INSERT INTO sticker_whitelist_info (provider_id, consumer_id) VALUES (?, ?)", -1, &stmt, NULL);
515     if (ret == SQLITE_OK) {
516         sqlite3_bind_text(stmt, 1, provider, -1, SQLITE_TRANSIENT);
517         sqlite3_bind_text(stmt, 2, consumer, -1, SQLITE_TRANSIENT);
518
519         ret = sqlite3_step(stmt);
520         if (ret != SQLITE_OK && ret != SQLITE_DONE)
521             LOGE("sqlite3_step() failed : ret(%d)", ret);
522
523         if (sqlite3_changes(db) == 0)
524             LOGE("No changes to DB");
525
526         sqlite3_finalize(stmt);
527         sqlite3_close(db);
528     } else {
529         LOGE("fail to insert sticker whiltelist : %s", sqlite3_errmsg(db));
530         sqlite3_finalize(stmt);
531         sqlite3_close(db);
532     }
533
534     return;
535 }
536
537 static int __get_sticker_info_from_json(const char *appid, const char *file_path, const char *app_path)
538 {
539     int ret = 1;
540     int arr_len = 0;
541     JsonParser* parser = NULL;
542     GError* err_msg = NULL;
543     char *uri = NULL;
544     char *group = NULL;
545     char *description = NULL;
546     char *thumbnail = NULL;
547     char *uri_path = NULL;
548
549     parser = json_parser_new();
550     json_parser_load_from_file(parser, file_path, &err_msg);
551     if (err_msg) {
552         LOGE("failed to load json file. error message: %s", err_msg->message);
553         ret = 0;
554         goto cleanup;
555     }
556
557     JsonNode *root = json_parser_get_root(parser);
558     if (root == NULL) {
559         LOGE("failed to get root");
560         ret = 0;
561         goto cleanup;
562     }
563
564     JsonObject *root_obj = json_node_get_object(root);
565     if (root_obj == NULL) {
566         LOGE("failed to get object");
567         ret = 0;
568         goto cleanup;
569     }
570
571     JsonArray *whitelist_arr = json_object_get_array_member(root_obj, "whitelist");
572     if (whitelist_arr != NULL) {
573         for (int i = 0; i < json_array_get_length(whitelist_arr); i++) {
574             __insert_sticker_whitelist_info(appid, json_array_get_string_element(whitelist_arr, i));
575         }
576     }
577
578     JsonArray *sticker_arr = json_object_get_array_member(root_obj, "sticker");
579     if (sticker_arr == NULL) {
580         LOGE("failed to get array member");
581         ret = 0;
582         goto cleanup;
583     }
584
585     arr_len = json_array_get_length(sticker_arr);
586     for (int i = 0; i < arr_len; i++) {
587         JsonObject *info_object = json_array_get_object_element(sticker_arr, i);
588         if (info_object != NULL) {
589             int type = __get_int_from_object(info_object, "type");
590             if (type < 1)
591                 continue;
592
593             uri = __get_string_from_object(info_object, "uri");
594             if (!uri)
595                 goto free_memory;
596
597             group = __get_string_from_object(info_object, "group");
598             if (!group)
599                 goto free_memory;
600
601             thumbnail = __get_string_from_object(info_object, "thumbnail");
602             description = __get_string_from_object(info_object, "description");
603             int disp_type = __get_int_from_object(info_object, "display_type");
604
605             JsonArray *keyword_arr = json_object_get_array_member(info_object, "keyword");
606             int keyword_arr_len = json_array_get_length(keyword_arr);
607             if (keyword_arr_len < 1)
608                 goto free_memory;
609
610             if (type == 1) {
611                 if (access(uri, F_OK) == 0) {
612                     char *new_uri = __convert_sticker_uri(uri, appid, app_path);
613                     if (!new_uri)
614                         goto free_memory;
615                     __insert_sticker_info(appid, type, new_uri, group, thumbnail, description, disp_type);
616
617                     if (new_uri) {
618                         free(new_uri);
619                         new_uri = NULL;
620                     }
621                 } else {
622                     int path_len = strlen(app_path) + strlen(uri) + 2;
623                     uri_path = (char *)calloc(path_len, sizeof(char));
624                     if (!uri_path) {
625                         LOGE("failed to alloc memory");
626                         goto free_memory;
627                     }
628
629                     if (uri[0] == '/')
630                         snprintf(uri_path, path_len, "%s%s",app_path, uri);
631                     else
632                         snprintf(uri_path, path_len, "%s%s%s",app_path, "/", uri);
633
634                     if (access(uri_path, F_OK) == 0) {
635                         char *new_uri = __convert_sticker_uri(uri_path, appid, app_path);
636                         if (!new_uri) {
637                             free(uri_path);
638                             uri_path = NULL;
639                             goto free_memory;
640                         }
641                         __insert_sticker_info(appid, type, new_uri, group, thumbnail, description, disp_type);
642
643                         free(new_uri);
644                         new_uri = NULL;
645
646                         free(uri_path);
647                         uri_path = NULL;
648                     } else {
649                         LOGE("%s does not exist", uri_path);
650                         free(uri_path);
651                         uri_path = NULL;
652                         goto free_memory;
653                     }
654                 }
655             } else {
656                 __insert_sticker_info(appid, type, uri, group, thumbnail, description, disp_type);
657             }
658
659             for (int j = 0; j < keyword_arr_len; j++) {
660                 __insert_sticker_keyword_info(json_array_get_string_element(keyword_arr, j));
661             }
662
663 free_memory:
664             if (uri) {
665                 free(uri);
666                 uri = NULL;
667             }
668
669             if (group) {
670                 free(group);
671                 group = NULL;
672             }
673
674             if (thumbnail) {
675                 free(thumbnail);
676                 thumbnail = NULL;
677             }
678
679             if (description) {
680                 free(description);
681                 description = NULL;
682             }
683         }
684     }
685
686 cleanup:
687     if (err_msg)
688         g_error_free(err_msg);
689
690     if (parser)
691         g_object_unref(parser);
692
693     return ret;
694 }
695
696 static void __delete_sticker_whitelist(const char *db_path, const char *app_id)
697 {
698     int ret;
699     sqlite3 *db = NULL;
700     sqlite3_stmt *stmt = NULL;
701
702     db = __db_open(db_path);
703     if (!db)
704         return;
705
706     ret = sqlite3_prepare_v2(db, "DELETE FROM sticker_whitelist_info WHERE provider_id = ?", -1, &stmt, NULL);
707     if (ret != SQLITE_OK) {
708         LOGE("failed to delete sticker whitelist : %s", sqlite3_errmsg(db));
709         sqlite3_finalize(stmt);
710         sqlite3_close(db);
711         goto cleanup;
712     }
713
714     sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
715
716     ret = sqlite3_step(stmt);
717     if (ret != SQLITE_OK && ret != SQLITE_DONE) {
718         LOGE("sqlite3_step() failed : ret(%d)", ret);
719         goto cleanup;
720     }
721
722     if (sqlite3_changes(db) == 0) {
723         LOGE("No changes to DB");
724         goto cleanup;
725     }
726
727     sqlite3_finalize(stmt);
728     sqlite3_close(db);
729     return;
730
731 cleanup:
732     sqlite3_finalize(stmt);
733     sqlite3_close(db);
734     return;
735 }
736
737 static void __delete_sticker_info(const char *db_path, int record_id)
738 {
739     int ret;
740     sqlite3 *db = NULL;
741     sqlite3_stmt *stmt = NULL;
742
743     db = __db_open(db_path);
744         if (!db)
745             return;
746
747     ret = sqlite3_prepare_v2(db, "DELETE FROM sticker_info WHERE sticker_info_id = ?", -1, &stmt, NULL);
748     if (ret != SQLITE_OK) {
749         LOGE("failed to delete sticker information : %s", sqlite3_errmsg(db));
750         sqlite3_finalize(stmt);
751         sqlite3_close(db);
752         goto cleanup;
753     }
754
755     sqlite3_bind_int(stmt, 1, record_id);
756
757     ret = sqlite3_step(stmt);
758     if (ret != SQLITE_OK && ret != SQLITE_DONE) {
759         LOGE("sqlite3_step() failed : ret(%d)", ret);
760         goto cleanup;
761     }
762
763     if (sqlite3_changes(db) == 0) {
764         LOGE("No changes to DB");
765         goto cleanup;
766     }
767
768     sqlite3_finalize(stmt);
769     sqlite3_close(db);
770     return;
771
772 cleanup:
773     sqlite3_finalize(stmt);
774     sqlite3_close(db);
775     return;
776 }
777
778 static int __remove_directory(const char *path, int is_error_stop)
779 {
780     DIR *dir_ptr = NULL;
781     struct dirent *file = NULL;
782     struct stat buf;
783     char filename[1024];
784
785     memset(filename, '\0', 1024);
786
787     if (__change_ownership(path, APPFW_ID, APPFW_ID) != 0)
788         LOGE("failed to change ownership");
789
790     dir_ptr = opendir(path);
791     if (dir_ptr == NULL)
792         return unlink(path);
793
794     while ((file = readdir(dir_ptr)) != NULL) {
795         if (strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)
796             continue;
797
798         snprintf(filename, strlen(path) + strlen(file->d_name) + 2, "%s/%s", path, file->d_name);
799
800         if (lstat(filename, &buf) == -1)
801             continue;
802
803         if (S_ISDIR(buf.st_mode)) {
804             if (__remove_directory(filename, is_error_stop) == -1 && is_error_stop) {
805                 closedir(dir_ptr);
806                 return -1;
807             }
808         } else if (S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode)) {
809             if (unlink(filename) == -1 && is_error_stop) {
810                 closedir(dir_ptr);
811                 return -1;
812             }
813         }
814     }
815
816     closedir(dir_ptr);
817     return rmdir(path);
818 }
819
820 EXPORT_API
821 int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
822 {
823     LOGD("METADATA INSTALL");
824     LOGD("pkgid: %s, appid: %s", pkgid, appid);
825
826     metadata *md = (metadata *)list->data;
827     package_info_h package_info = NULL;
828     char *app_path = NULL;
829     char *file_path = NULL;
830     int ret = 0;
831
832     __db_init();
833
834     ret = package_info_create(pkgid, &package_info);
835     if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
836         LOGE("failed to create package_info. ret: %d", ret);
837         goto cleanup;
838     }
839
840     ret = package_info_get_root_path(package_info, &app_path);
841     if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
842         LOGE("failed to create package_info. ret: %d", ret);
843         goto cleanup;
844     }
845
846     int path_len = strlen(app_path) + strlen((char *)md->value) + 2;
847     file_path = (char *)calloc(path_len, sizeof(char));
848     if (!file_path) {
849         LOGE("failed to alloc memory");
850         goto cleanup;
851     }
852
853     if ((char)md->value[0] == '/')
854         snprintf(file_path, path_len, "%s%s",app_path, (char *)md->value);
855     else
856         snprintf(file_path, path_len, "%s%s%s",app_path, "/", (char *)md->value);
857
858     if (__get_sticker_info_from_json(appid, file_path, app_path) == 0)
859             LOGE("failed to get sticker information [path : %s]", file_path);
860
861 cleanup:
862     if (package_info)
863         package_info_destroy(package_info);
864
865     if (app_path) {
866         free(app_path);
867         app_path = NULL;
868     }
869
870     if (file_path) {
871         free(file_path);
872         file_path = NULL;
873     }
874
875     return 0;
876 }
877
878 EXPORT_API
879 int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
880 {
881     LOGD("METADATA UNINSTALL");
882     LOGD("pkgid: %s, appid: %s", pkgid, appid);
883
884     int ret;
885     int del_id;
886     sqlite3 *db = NULL;
887     sqlite3_stmt *stmt = NULL;
888     const char *db_path;
889     GList *id_list = NULL;
890
891     db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
892     db = __db_open(db_path);
893     if (!db)
894         return 0;
895
896     ret = sqlite3_prepare_v2(db, "SELECT sticker_info_id from sticker_info WHERE app_id = ?", -1, &stmt, NULL);
897     if (ret == SQLITE_OK) {
898         sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
899         while (sqlite3_step(stmt) == SQLITE_ROW) {
900             const unsigned char *record_id = sqlite3_column_text(stmt, 0);
901             if (record_id)
902                 id_list = g_list_append(id_list, strdup((const char *)record_id));
903         }
904
905         sqlite3_finalize(stmt);
906         sqlite3_close(db);
907
908         for(GList *tmp = g_list_first(id_list); tmp != NULL; tmp = tmp->next) {
909             del_id = atoi((const char*)tmp->data);
910             __delete_sticker_info(db_path, del_id);
911         }
912
913         if (id_list)
914             g_list_free_full(id_list, free);
915     } else {
916         LOGE("failed to get sticker id");
917         sqlite3_finalize(stmt);
918         sqlite3_close(db);
919     }
920
921     __delete_sticker_whitelist(db_path, appid);
922
923     return 0;
924 }
925
926 EXPORT_API
927 int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
928 {
929     LOGD("METADATA UPGRADE");
930     LOGD("pkgid: %s, appid: %s", pkgid, appid);
931
932     PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
933     PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);
934     return 0;
935 }
936
937 EXPORT_API
938 int PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
939 {
940     LOGD("STICKER CATEGORY INSTALL");
941     LOGD("pkgid: %s, appid: %s", pkgid, appid);
942
943     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + 2;
944     char *dir_path = (char *)calloc(len, sizeof(char));
945
946     if (dir_path != NULL) {
947         snprintf(dir_path, len, "%s%s%s", STICKER_DIRECTORY, "/", appid);
948         LOGD("directory path : %s", dir_path);
949
950         if (mkdir(dir_path, 0755) == -1 && errno != EEXIST) {
951             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
952             LOGE("directory create error : %s", error_buffer);
953         } else {
954             if (__change_ownership(dir_path, UIFW_ID, UIFW_ID) != 0)
955                 LOGE("failed to change ownership");
956         }
957
958         free(dir_path);
959         dir_path = NULL;
960     }
961
962     return 0;
963 }
964
965 EXPORT_API
966 int PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
967 {
968     LOGD("STICKER CATEGORY UNINSTALL");
969     LOGD("pkgid: %s, appid: %s", pkgid, appid);
970
971     int len = strlen(STICKER_DIRECTORY) + strlen(appid) + 2;
972     char * dir_path = (char *)calloc(len, sizeof(char));
973
974     if (dir_path != NULL) {
975         snprintf(dir_path, len, "%s%s%s", STICKER_DIRECTORY, "/", appid);
976         LOGD("directory path : %s", dir_path);
977
978         if (__remove_directory(dir_path, 0) < 0) {
979             strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
980             LOGE("directory remove error : %s", error_buffer);
981         }
982
983         free(dir_path);
984         dir_path = NULL;
985     }
986
987     return 0;
988 }
989
990 EXPORT_API
991 int PKGMGR_CATEGORY_PARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
992 {
993     LOGD("STICKER CATEGORY UPGRADE");
994     LOGD("pkgid: %s, appid: %s", pkgid, appid);
995
996     PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
997     PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL(pkgid, appid, list);
998
999     return 0;
1000 }