Fix use after free
[platform/core/appfw/widget-service.git] / src / widget_service.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 #include <ctype.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <stdbool.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <iniparser.h>
25
26 #include <glib.h>
27 #include <sqlite3.h>
28
29 #include <sys/smack.h>
30 #include <vconf.h>
31 #include <vconf-keys.h>
32 #include <unicode/uloc.h>
33 #include <aul.h>
34 #include <tzplatform_config.h>
35 #include <pkgmgr-info.h>
36 #include <system_info.h>
37 #include <dlog.h>
38 #include <cynara-client.h>
39 #include <stdio.h>
40 #include <fcntl.h>
41 #include <pwd.h>
42
43 #include <aul_widget.h>
44 #include <aul_app_com.h>
45 #include <system_info.h>
46
47 #include "widget_errno.h"
48 #include "debug.h"
49 #include "widget_instance.h"
50 #include "widget_service.h"
51 #include "widget_service_internal.h"
52
53 #define MAX_COLUMN 80
54 #define MAX_BUF_SIZE 4096
55 #define SMACK_LABEL_LEN 255
56
57 #define RESOLUTION_PATH_FORMAT "/usr/share/widget_service/%dx%d/resolution.ini"
58 #define RESOLUTION_PATH_DEFAULT "/usr/share/widget_service/resolution.ini"
59 #define RESOLUTION_SECTION_NAME "resolution"
60 #define RESOLUTION_FORMAT "%dx%d"
61
62 #define CREATE_WIDGET_TABLE " \
63 PRAGMA user_version = 50; \
64 PRAGMA journal_mode = PERSIST; \
65 PRAGMA foreign_keys = ON; \
66 BEGIN EXCLUSIVE TRANSACTION; \
67 CREATE TABLE widget_class ( \
68         classid       TEXT NOT NULL, \
69         update_period INTEGER DEFAULT 0, \
70         setup_appid   TEXT, \
71         appid         TEXT NOT NULL, \
72         pkgid         TEXT NOT NULL, \
73         nodisplay     INTEGER DEFAULT 0, \
74         max_instance  INTEGER DEFAULT 0, \
75         prime         INTEGER DEFAULT 0, \
76         is_disable    INTEGER DEFAULT 0, \
77         PRIMARY KEY(classid) \
78 ); \
79 CREATE TABLE support_size ( \
80         classid TEXT NOT NULL, \
81         preview TEXT NOT NULL, \
82         frame   INTEGER DEFAULT 0, \
83         width   INTEGER NOT NULL, \
84         height  INTEGER NOT NULL, \
85         FOREIGN KEY(classid) REFERENCES widget_class (classid) ON DELETE CASCADE \
86 ); \
87 CREATE TABLE label ( \
88         classid TEXT NOT NULL, \
89         locale  TEXT DEFAULT 'No Locale', \
90         label   TEXT NOT NULL, \
91         FOREIGN KEY(classid) REFERENCES widget_class (classid) ON DELETE CASCADE \
92 ); \
93 CREATE TABLE icon ( \
94         classid TEXT NOT NULL, \
95         locale  TEXT DEFAULT 'No Locale', \
96         icon    TEXT NOT NULL, \
97         FOREIGN KEY(classid) REFERENCES widget_class (classid) ON DELETE CASCADE \
98 ); \
99 COMMIT TRANSACTION; "
100
101 #define DB_LABEL "User::Home"
102 #define SET_SMACK_LABEL(x) \
103 do { \
104         if (smack_setlabel((x), DB_LABEL, SMACK_LABEL_ACCESS)) \
105                 _E("failed chsmack -a %s %s", DB_LABEL, x); \
106         else \
107                 _D("chsmack -a %s %s", DB_LABEL, x); \
108 } while (0)
109
110 #define WIDGET_TBL_COUNT 4
111 #define DISABLE_ENDPOINT "widget.disable"
112
113 static char *_widget_table_list[WIDGET_TBL_COUNT] = {
114         "icon",
115         "label",
116         "support_size",
117         "widget_class"
118 };
119
120 struct widget_instance_info_s {
121         int period;
122         bool exists;
123         const char *instance_id;
124 };
125
126 static GList *lifecycle_cbs;
127 static bool _is_resolution_loaded = false;
128 static const char *_iso3lang;
129 static char _country[ULOC_COUNTRY_CAPACITY];
130 static char *_syslang;
131 static bool _is_corrupted = false;
132 static aul_app_com_connection_h _conn;
133 static widget_disable_event_cb _disable_event_cb;
134 static void *_disable_user_data;
135
136 static inline bool _is_widget_feature_enabled(void)
137 {
138         static bool feature = false;
139         static bool retrieved = false;
140         int ret;
141
142         if (retrieved == true)
143                 return feature;
144
145         ret = system_info_get_platform_bool(
146                         "http://tizen.org/feature/shell.appwidget", &feature);
147         if (ret != SYSTEM_INFO_ERROR_NONE) {
148                 _E("failed to get system info");
149                 return false;
150         }
151
152         retrieved = true;
153
154         return feature;
155 }
156
157 static int check_privilege(const char *privilege)
158 {
159         cynara *p_cynara = NULL;
160
161         int fd = 0;
162         int ret = 0;
163
164         char subject_label[SMACK_LABEL_LEN + 1] = "";
165         char uid[10] = {0,};
166         char *client_session = "";
167
168         ret = cynara_initialize(&p_cynara, NULL);
169         if (ret != CYNARA_API_SUCCESS) {
170                 LOGE("cannot init cynara [%d] failed!", ret);
171                 ret = -1;
172                 goto out;
173         }
174
175         fd = open("/proc/self/attr/current", O_RDONLY);
176         if (fd < 0) {
177                 LOGE("open [%d] failed!", errno);
178                 ret = -1;
179                 goto out;
180         }
181
182         ret = read(fd, subject_label, SMACK_LABEL_LEN);
183         if (ret < 0) {
184                 LOGE("read [%d] failed!", errno);
185                 close(fd);
186                 ret = -1;
187                 goto out;
188         }
189         close(fd);
190
191         snprintf(uid, 10, "%d", getuid());
192
193         ret = cynara_check(p_cynara, subject_label, client_session, uid,
194                                 privilege);
195         if (ret != CYNARA_API_ACCESS_ALLOWED) {
196                 LOGE("cynara access check [%d] failed!", ret);
197                 ret = -1;
198                 goto out;
199         }
200
201         ret = 0;
202 out:
203         if (p_cynara)
204                 cynara_finish(p_cynara);
205
206         return ret;
207 }
208
209 #define ROOT_USER 0
210 #define GLOBALAPP_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
211 static int _is_global(uid_t uid)
212 {
213         if (uid == ROOT_USER || uid == GLOBALAPP_USER)
214                 return 1;
215         else
216                 return 0;
217 }
218
219 static const char *_get_db_path(uid_t uid, bool is_init)
220 {
221         const char *path;
222
223         if (!_is_global(uid))
224                 tzplatform_set_user(uid);
225
226         if (is_init && !_is_global(uid)) {
227                 path = tzplatform_mkpath(TZ_SYS_ETC,
228                                 "skel/.applications/dbspace/.widget.db");
229         } else {
230                 path = tzplatform_mkpath(_is_global(uid) ?
231                                 TZ_SYS_DB : TZ_USER_DB, ".widget.db");
232         }
233
234         tzplatform_reset_user();
235
236         return path;
237 }
238
239 static int _check_integrity_cb(void *pid, int argc, char **argv,
240                 char **not_used)
241 {
242         if (strcmp(argv[0], "ok") == 0)
243                 return 0;
244
245         _E("db integrity result fail : %s" , argv[0]);
246         _is_corrupted = true;
247         return -1;
248 }
249
250 static void __change_smack(const char *path)
251 {
252         char journal_path[PATH_MAX];
253
254         snprintf(journal_path, sizeof(journal_path), "%s-journal", path);
255         SET_SMACK_LABEL(path);
256         SET_SMACK_LABEL(journal_path);
257 }
258
259 static int __change_own(uid_t uid, const char *path)
260 {
261         struct passwd pwd;
262         struct passwd *result;
263         int ret;
264         uid_t new_uid;
265         char buf[MAX_BUF_SIZE];
266         char journal_path[PATH_MAX];
267         mode_t mode;
268
269         ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
270         if (result == NULL) {
271                 if (ret == 0)
272                         printf("no such user: %d", uid);
273                 else
274                         printf("getpwuid_r failed: %d", errno);
275                 return WIDGET_ERROR_FAULT;
276         }
277
278         if (pwd.pw_uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
279                 new_uid = 0;
280         else
281                 new_uid = pwd.pw_uid;
282
283         ret = chown(path, new_uid, pwd.pw_gid);
284         if (ret == -1) {
285                 printf("chown fail %s", path);
286                 return WIDGET_ERROR_FAULT;
287         }
288
289         mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
290         ret = chmod(path, mode);
291         if (ret == -1) {
292                 printf("chmod failed : %s", path);
293                 return WIDGET_ERROR_FAULT;;
294         }
295
296         snprintf(journal_path, sizeof(journal_path), "%s-journal", path);
297         ret = chown(journal_path, new_uid, pwd.pw_gid);
298         if (ret == -1) {
299                 printf("chown fail %s", path);
300                 return WIDGET_ERROR_FAULT;
301         }
302
303         ret = chmod(journal_path, mode);
304         if (ret == -1) {
305                 printf("chmod failed : %s", path);
306                 return WIDGET_ERROR_FAULT;;
307         }
308
309         return WIDGET_ERROR_NONE;
310 }
311
312 static int _recover_db(const char *path, uid_t uid, bool is_init)
313 {
314         sqlite3 *db;
315         int ret;
316         char *errmsg = NULL;
317
318         _I("DB recovery process start");
319         if (access(path, F_OK) == 0)
320                 unlink(path);
321
322         ret = sqlite3_open_v2(path, &db,
323                         SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
324                         NULL);
325         if (ret != SQLITE_OK) {
326                 _E("Failed to open db[%d]", ret);
327                 sqlite3_close_v2(db);
328                 unlink(path);
329                 return WIDGET_ERROR_FAULT;
330         }
331
332         ret = sqlite3_exec(db, CREATE_WIDGET_TABLE, NULL, NULL, &errmsg);
333         sqlite3_close_v2(db);
334         if (ret != SQLITE_OK) {
335                 _E("Failed to exec query[%d][%s]", ret, errmsg);
336                 sqlite3_free(errmsg);
337                 return WIDGET_ERROR_FAULT;
338         }
339
340         __change_smack(path);
341         if (!is_init) {
342                 ret = __change_own(uid, path);
343                 if (ret != WIDGET_ERROR_NONE)
344                         return ret;
345         }
346         _I("DB recovery process done");
347
348         return WIDGET_ERROR_NONE;
349 }
350
351 static int _integrity_check(sqlite3 *db)
352 {
353         int ret;
354         char *errmsg = NULL;
355
356         ret = sqlite3_exec(db, "PRAGMA integrity_check",
357                                _check_integrity_cb, NULL, &errmsg);
358         if (ret != SQLITE_OK || _is_corrupted) {
359                 _E("Failed to exec query[%d][%s]", ret, errmsg);
360                 sqlite3_free(errmsg);
361                 return WIDGET_ERROR_FAULT;
362         }
363
364         return WIDGET_ERROR_NONE;
365 }
366
367 static int _check_table_exist(sqlite3 *db)
368 {
369         int ret;
370         char *val;
371         int idx = 0;
372         sqlite3_stmt *stmt;
373         const char query[] =
374                 "SELECT name FROM sqlite_master WHERE type='table'" \
375                 " ORDER BY name ASC";
376
377         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
378         if (ret != SQLITE_OK) {
379                 /* LCOV_EXCL_START */
380                 _E("prepare error: %s", sqlite3_errmsg(db));
381                 return WIDGET_ERROR_FAULT;
382                 /* LCOV_EXCL_STOP */
383         }
384
385         while (sqlite3_step(stmt) == SQLITE_ROW && idx < WIDGET_TBL_COUNT) {
386                 val = (char *)sqlite3_column_text(stmt, 0);
387                 _I("%s : %s", _widget_table_list[idx], val);
388                 if (strcmp(_widget_table_list[idx], val) != 0)
389                         continue;
390                 idx++;
391         }
392
393         sqlite3_finalize(stmt);
394         if (idx != WIDGET_TBL_COUNT) {
395                 _E("wrong table count");
396                 return WIDGET_ERROR_FAULT;
397         }
398
399         return WIDGET_ERROR_NONE;
400 }
401
402 static int _check_db_integrity(uid_t uid, bool is_init)
403 {
404         int ret;
405         const char *path;
406         sqlite3 *db;
407
408         path = _get_db_path(uid, is_init);
409         if (path == NULL)
410                 return WIDGET_ERROR_FAULT;
411
412         _I("_check_db_integrity %d %d", uid, is_init);
413
414         /* check table exist */
415         ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, NULL);
416         if (ret != SQLITE_OK) {
417                 /* LCOV_EXCL_START */
418                 sqlite3_close_v2(db);
419                 return _recover_db(path, uid, is_init);
420                 /* LCOV_EXCL_STOP */
421         }
422
423         /* check integrity */
424         ret = _integrity_check(db);
425         if (ret != WIDGET_ERROR_NONE) {
426                 sqlite3_close_v2(db);
427                 return _recover_db(path, uid, is_init);
428         }
429
430         /* check table exist */
431         ret = _check_table_exist(db);
432         sqlite3_close_v2(db);
433         if (ret != WIDGET_ERROR_NONE)
434                 return _recover_db(path, uid, is_init);
435
436         return WIDGET_ERROR_NONE;
437 }
438
439 EAPI int widget_service_check_db_integrity(bool is_init)
440 {
441         int ret;
442
443         ret = _check_db_integrity(ROOT_USER, is_init);
444         _I("check global app db result : %d", ret);
445
446         ret = _check_db_integrity(tzplatform_getuid(TZ_SYS_DEFAULT_USER),
447                         is_init);
448         _I("check default user db result : %d", ret);
449
450         return WIDGET_ERROR_NONE;
451 }
452
453 static sqlite3 *_open_db(uid_t uid)
454 {
455         int ret;
456         const char *path;
457         sqlite3 *db;
458
459         path = _get_db_path(uid, false);
460         if (path == NULL)
461                 return NULL;
462
463         ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, NULL);
464         if (ret != SQLITE_OK) {
465                 /* LCOV_EXCL_START */
466                 _E("failed to open widget db. path(%s), result(%d)",
467                                 path, ret);
468                 return NULL;
469                 /* LCOV_EXCL_STOP */
470         }
471
472         return db;
473 }
474
475 static void _get_column_str(sqlite3_stmt *stmt, int idx, char **str)
476 {
477         char *val;
478
479         val = (char *)sqlite3_column_text(stmt, idx);
480         if (val)
481                 *str = strdup(val);
482         else
483                 *str = NULL;
484 }
485
486 static void _get_column_int(sqlite3_stmt *stmt, int idx, int *i)
487 {
488         *i = sqlite3_column_int(stmt, idx);
489 }
490
491 static void _get_column_double(sqlite3_stmt *stmt, int idx, double *i)
492 {
493         *i = sqlite3_column_double(stmt, idx);
494 }
495
496 #define WIDGET_SIZE_TYPE_MAX 21
497 static int size_list[WIDGET_SIZE_TYPE_MAX][5] = {
498         { 1, 1, 175, 175, WIDGET_SIZE_TYPE_1x1 }, /*!< 1x1 */
499         { 2, 1, 354, 175, WIDGET_SIZE_TYPE_2x1 }, /*!< 2x1 */
500         { 2, 2, 354, 354, WIDGET_SIZE_TYPE_2x2 }, /*!< 2x2 */
501         { 4, 1, 712, 175, WIDGET_SIZE_TYPE_4x1 }, /*!< 4x1 */
502         { 4, 2, 712, 354, WIDGET_SIZE_TYPE_4x2 }, /*!< 4x2 */
503         { 4, 3, 712, 533, WIDGET_SIZE_TYPE_4x3 }, /*!< 4x3 */
504         { 4, 4, 712, 712, WIDGET_SIZE_TYPE_4x4 }, /*!< 4x4 */
505         { 4, 5, 712, 891, WIDGET_SIZE_TYPE_4x5 }, /*!< 4x5 */
506         { 4, 6, 712, 1070, WIDGET_SIZE_TYPE_4x6 }, /*!< 4x6 */
507         { 21, 21, 224, 215, WIDGET_SIZE_TYPE_EASY_1x1 }, /*!< 21x21 */
508         { 23, 21, 680, 215, WIDGET_SIZE_TYPE_EASY_3x1 }, /*!< 23x21 */
509         { 23, 23, 680, 653, WIDGET_SIZE_TYPE_EASY_3x3 }, /*!< 23x23 */
510         { 0, 0, 720, 1280, WIDGET_SIZE_TYPE_FULL }, /*!< 0x0 */
511         { 3, 1, 480, 126, WIDGET_SIZE_TYPE_3x1 }, /*!< 3x1 */
512         { 3, 3, 480, 426, WIDGET_SIZE_TYPE_3x3 }, /*!< 3x3 */
513         { 3, 6, 480, 876, WIDGET_SIZE_TYPE_3x6 }, /*!< 3x6 */
514         { 6, 3, 984, 426, WIDGET_SIZE_TYPE_6x3 }, /*!< 6x3 */
515         { 6, 6, 984, 876, WIDGET_SIZE_TYPE_6x6 }, /*!< 6x6 */
516         { 6, 12, 720, 1280, WIDGET_SIZE_TYPE_6x12 }, /*!< 6x12 */
517         { 2, 6, 360, 876, WIDGET_SIZE_TYPE_2x6 }, /*!< 2x6 */
518         { 6, 4, 876, 600, WIDGET_SIZE_TYPE_6x4 }, /*!< 6x4 */
519 };
520
521 static char *_resolution_file_path(void)
522 {
523         char *path;
524         int length;
525         int w, h;
526         int ret;
527
528         length = strlen(RESOLUTION_PATH_FORMAT) + 12;
529         path = calloc(1, length);
530         if (!path) {
531                 _E("calloc: %d\n", errno);
532                 return NULL;
533         }
534
535         ret = system_info_get_platform_int(
536                 "http://tizen.org/feature/screen.width", &w);
537         if (ret != SYSTEM_INFO_ERROR_NONE) {
538                 _E("fail to get width: %d", ret);
539                 free(path);
540                 return NULL;
541         }
542
543         ret = system_info_get_platform_int(
544                 "http://tizen.org/feature/screen.height", &h);
545         if (ret != SYSTEM_INFO_ERROR_NONE) {
546                 _E("fail to get height: %d", ret);
547                 free(path);
548                 return NULL;
549         }
550         _D("screen size : %d %d", w, h);
551
552         snprintf(path, length, RESOLUTION_PATH_FORMAT, w, h);
553         _D("Selected conf file: %s", path);
554         if (access(path, F_OK) != 0) {
555                 _E("Fallback to default, access: %d", errno);
556                 strncpy(path, RESOLUTION_PATH_DEFAULT, length);
557                 if (access(path, F_OK) != 0) {
558                         _E("Serious error - there is no conf file, use default setting: %d\n", errno);
559                         free(path);
560                         path = NULL;
561                 }
562         }
563
564         return path;
565 }
566
567 static void _resolution_update_size_list(int width_type, int height_type, int width, int height)
568 {
569         int idx = 0;
570
571         if (width_type == 1 && height_type == 1) {
572                 idx = 0;
573         } else if (width_type == 2 && height_type == 1) {
574                 idx = 1;
575         } else if (width_type == 2 && height_type == 2) {
576                 idx = 2;
577         } else if (width_type == 4 && height_type == 1) {
578                 idx = 3;
579         } else if (width_type == 4 && height_type == 2) {
580                 idx = 4;
581         } else if (width_type == 4 && height_type == 3) {
582                 idx = 5;
583         } else if (width_type == 4 && height_type == 4) {
584                 idx = 6;
585         } else if (width_type == 4 && height_type == 5) {
586                 idx = 7;
587         } else if (width_type == 4 && height_type == 6) {
588                 idx = 8;
589         } else if (width_type == 21 && height_type == 21) {
590                 idx = 9;
591         } else if (width_type == 23 && height_type == 21) {
592                 idx = 10;
593         } else if (width_type == 23 && height_type == 23) {
594                 idx = 11;
595         } else if (width_type == 0 && height_type == 0) {
596                 idx = 12;
597         } else if (width_type == 3 && height_type == 1) {
598                 idx = 13;
599         } else if (width_type == 3 && height_type == 3) {
600                 idx = 14;
601         } else if (width_type == 3 && height_type == 6) {
602                 idx = 15;
603         } else if (width_type == 6 && height_type == 3) {
604                 idx = 16;
605         } else if (width_type == 6 && height_type == 6) {
606                 idx = 17;
607         } else if (width_type == 6 && height_type == 12) {
608                 idx = 18;
609         } else if (width_type == 2 && height_type == 6) {
610                 idx = 19;
611         } else if (width_type == 6 && height_type == 4) {
612                 idx = 20;
613         } else {
614                 _E("Unknown size type: %dx%d (%dx%d)\n", width_type, height_type, width, height);
615                 return;
616         }
617
618         size_list[idx][2] = width;
619         size_list[idx][3] = height;
620
621         _I("size type(%d): %dx%d (%dx%d)\n", idx, width_type, height_type, width, height);
622 }
623
624 static int _resolution_update_from_file(void)
625 {
626         int width_type = 0;
627         int height_type = 0;
628         int width = 0;
629         int height = 0;
630         char *type_str;
631         const char *size_str;
632         dictionary *dic;
633         char *file_path = NULL;
634         int key_num;
635         char **key_list;
636         char key_format[MAX_COLUMN];
637         int i;
638
639         file_path = _resolution_file_path();
640         if (file_path == NULL)
641                 return WIDGET_ERROR_OUT_OF_MEMORY;
642
643         dic = iniparser_load(file_path);
644         if (dic == NULL) {
645                 _E("fail to load [%s] ", file_path);
646                 free(file_path);
647                 return WIDGET_ERROR_IO_ERROR;
648         }
649         free(file_path);
650         snprintf(key_format, sizeof(key_format), "%s:%s",
651                         RESOLUTION_SECTION_NAME, RESOLUTION_FORMAT);
652         key_num = iniparser_getsecnkeys(dic, RESOLUTION_SECTION_NAME);
653         if (key_num == 0) {
654                 _E("key_num is zero");
655                 iniparser_freedict(dic);
656                 return WIDGET_ERROR_NONE;
657
658         }
659
660         key_list = calloc(key_num, sizeof(char *));
661         if (key_list == NULL) {
662                 _E("Out of memory");
663                 iniparser_freedict(dic);
664                 return WIDGET_ERROR_OUT_OF_MEMORY;
665         }
666
667         if (!iniparser_getseckeys(dic, RESOLUTION_SECTION_NAME,
668                         (const char **)key_list)) {
669                 _E("Failed to get section keys");
670                 free(key_list);
671                 iniparser_freedict(dic);
672                 return WIDGET_ERROR_IO_ERROR;
673         }
674
675         for (i = 0; i < key_num; i++) {
676                 type_str = key_list[i];
677                 size_str = iniparser_getstring(dic, type_str, NULL);
678                 if (sscanf(type_str, key_format, &width_type, &height_type) != 2) {
679                         _E("Invalid syntax: [%s]", type_str);
680                         continue;
681                 }
682
683                 if (size_str == NULL) {
684                         _E("sizen str is NULL");
685                         continue;
686                 }
687
688                 if (sscanf(size_str, "%dx%d", &width, &height) != 2) {
689                         _E("Invalid syntax: [%s]", size_str);
690                         continue;
691                 }
692                 _resolution_update_size_list(width_type, height_type, width, height);
693         }
694
695         free(key_list);
696         iniparser_freedict(dic);
697
698         return WIDGET_ERROR_NONE;
699 }
700
701 static int _get_supported_size_type(int width, int height, int *type)
702 {
703         int i;
704
705         if (!_is_resolution_loaded) {
706                 _resolution_update_from_file();
707                 _is_resolution_loaded = true;
708         }
709
710         for (i = 0; i < WIDGET_SIZE_TYPE_MAX; i++) {
711                 if (width == size_list[i][2] && height == size_list[i][3])
712                         break;
713         }
714
715         if (i == WIDGET_SIZE_TYPE_MAX) {
716                 _E("failed to get supported size");
717                 return -1;
718         }
719
720         *type = size_list[i][4];
721
722         return 0;
723 }
724
725 static int _get_supported_size(int type, int *width, int *height)
726 {
727         int i;
728
729         if (!_is_resolution_loaded) {
730                 _resolution_update_from_file();
731                 _is_resolution_loaded = true;
732         }
733
734         for (i = 0; i < WIDGET_SIZE_TYPE_MAX; i++) {
735                 if (type == size_list[i][4])
736                         break;
737         }
738
739         if (i == WIDGET_SIZE_TYPE_MAX) {
740                 _E("failed to get supported size type");
741                 return -1;
742         }
743
744         *width = size_list[i][2];
745         *height = size_list[i][3];
746
747         return 0;
748 }
749
750 static int _convert_to_support_info(int *width, int *height, int *type, int count)
751 {
752         int i;
753         int j;
754
755         if (!_is_resolution_loaded) {
756                 _resolution_update_from_file();
757                 _is_resolution_loaded = true;
758         }
759
760         for (j = 0; j < count; j++) {
761                 for (i = 0; i < WIDGET_SIZE_TYPE_MAX; i++) {
762                         if (size_list[i][0] == width[j] &&
763                                         size_list[i][1] == height[j])
764                                 break;
765                 }
766                 if (i == WIDGET_SIZE_TYPE_MAX) {
767                         _E("failed to get supported size type");
768                         return -1;
769                 }
770                 width[j] = size_list[i][2];
771                 height[j] = size_list[i][3];
772                 type[j] =  size_list[i][4];
773         }
774
775         return 0;
776 }
777
778 static int _convert_to_support_size(int *width, int *height, int count)
779 {
780         int i;
781         int j;
782
783         if (!_is_resolution_loaded) {
784                 _resolution_update_from_file();
785                 _is_resolution_loaded = true;
786         }
787
788         for (j = 0; j < count; j++) {
789                 for (i = 0; i < WIDGET_SIZE_TYPE_MAX; i++) {
790                         if (size_list[i][0] == width[j] &&
791                                         size_list[i][1] == height[j])
792                                 break;
793                 }
794                 if (i == WIDGET_SIZE_TYPE_MAX) {
795                         _E("failed to get supported size type");
796                         return -1;
797                 }
798                 width[j] = size_list[i][2];
799                 height[j] = size_list[i][3];
800         }
801
802         return 0;
803 }
804
805 static int _convert_type_to_support_size_ratio(int type, int *w, int *h)
806 {
807         int i;
808
809         if (!_is_resolution_loaded) {
810                 _resolution_update_from_file();
811                 _is_resolution_loaded = true;
812         }
813
814         for (i = 0; i < WIDGET_SIZE_TYPE_MAX; i++) {
815                 if (size_list[i][4] == type)
816                         break;
817         }
818
819         if (i == WIDGET_SIZE_TYPE_MAX) {
820                 _E("failed to get support size ratio");
821                 return -1;
822         }
823
824         *w = size_list[i][0];
825         *h = size_list[i][1];
826
827         return 0;
828 }
829
830 static int _get_widget_supported_sizes(const char *widget_id, uid_t uid,
831                 int *cnt, int **w, int **h)
832 {
833         static const char query[] =
834                 "SELECT width, height FROM support_size WHERE classid=?";
835         int ret;
836         sqlite3 *db;
837         sqlite3_stmt *stmt = NULL;
838         int count = 0;
839         int i;
840         int *width = NULL;
841         int *height = NULL;
842
843         db = _open_db(uid);
844         if (db == NULL)
845                 return WIDGET_ERROR_IO_ERROR;
846
847         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
848         if (ret != SQLITE_OK) {
849                 /* LCOV_EXCL_START */
850                 _E("prepare error: %s", sqlite3_errmsg(db));
851                 ret = WIDGET_ERROR_FAULT;
852                 goto err;
853                 /* LCOV_EXCL_STOP */
854         }
855
856         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
857
858         while (sqlite3_step(stmt) == SQLITE_ROW)
859                 count++;
860
861         if (count == 0) {
862                 *cnt = 0;
863                 *w = NULL;
864                 *h = NULL;
865                 ret = WIDGET_ERROR_NOT_EXIST;
866                 goto err;
867         }
868
869         sqlite3_reset(stmt);
870         width = malloc(sizeof(int) * count);
871         if (!width) {
872                 _E("Failed to allocate width");
873                 ret = WIDGET_ERROR_FAULT; /* It shoud be WIDGET_ERROR_OUT_OF_MEMORY */
874                 goto err;
875         }
876
877         height = malloc(sizeof(int) * count);
878         if (!height) {
879                 _E("Failed to allocate height");
880                 ret = WIDGET_ERROR_FAULT; /* It should be WIDGET_ERROR_OUT_OF_MEMORY */
881                 goto err;
882         }
883
884         for (i = 0; i < count; i++) {
885                 ret = sqlite3_step(stmt);
886                 if (ret != SQLITE_ROW) {
887                         _E("sqlite3_step() is failed. err(%s)",
888                                         sqlite3_errmsg(db));
889                         ret = WIDGET_ERROR_FAULT;
890                         goto err;
891                 }
892                 _get_column_int(stmt, 0, &width[i]);
893                 _get_column_int(stmt, 1, &height[i]);
894         }
895
896         if (_convert_to_support_size(width, height, count)) {
897                 _E("failed to convert size");
898                 ret = WIDGET_ERROR_FAULT;
899                 goto err;
900         }
901         *w = width;
902         *h = height;
903         *cnt = count;
904
905         sqlite3_finalize(stmt);
906         sqlite3_close_v2(db);
907
908         return WIDGET_ERROR_NONE;
909
910 err:
911         if (height)
912                 free(height);
913         if (width)
914                 free(width);
915         if (stmt)
916                 sqlite3_finalize(stmt);
917         if (db)
918                 sqlite3_close_v2(db);
919
920         return ret;
921 }
922
923
924 static int _get_widget_supported_info(const char *widget_id, uid_t uid,
925                 int *cnt, int **w, int **h, int **t)
926 {
927         static const char query[] =
928                 "SELECT width, height FROM support_size WHERE classid=?";
929         int ret;
930         sqlite3 *db;
931         sqlite3_stmt *stmt = NULL;
932         int count = 0;
933         int i;
934         int *width = NULL;
935         int *height = NULL;
936         int *type = NULL;
937
938         db = _open_db(uid);
939         if (db == NULL)
940                 return WIDGET_ERROR_IO_ERROR;
941
942         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
943         if (ret != SQLITE_OK) {
944                 /* LCOV_EXCL_START */
945                 _E("prepare error: %s", sqlite3_errmsg(db));
946                 ret = WIDGET_ERROR_FAULT;
947                 goto err;
948                 /* LCOV_EXCL_STOP */
949         }
950
951         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
952
953         while (sqlite3_step(stmt) == SQLITE_ROW)
954                 count++;
955
956         if (count == 0) {
957                 *cnt = 0;
958                 *w = NULL;
959                 *h = NULL;
960                 ret = WIDGET_ERROR_NOT_EXIST;
961                 goto err;
962         }
963
964         sqlite3_reset(stmt);
965         width = malloc(sizeof(int) * count);
966         if (!width) {
967                 _E("Failed to allocate width");
968                 ret = WIDGET_ERROR_FAULT; /* It should be WIDGET_ERROR_OUT_OF_MEMORY */
969                 goto err;
970         }
971
972         height = malloc(sizeof(int) * count);
973         if (!height) {
974                 _E("Failed to allocate height");
975                 ret = WIDGET_ERROR_FAULT; /* It should be WIDGET_ERROR_OUT_OF_MEMORY */
976                 goto err;
977         }
978
979         type = malloc(sizeof(int) * count);
980         if (!type) {
981                 _E("Failed to allocate type");
982                 ret = WIDGET_ERROR_FAULT; /* It should be WIDGET_ERROR_OUT_OF_MEMORY */
983                 goto err;
984         }
985
986         for (i = 0; i < count; i++) {
987                 ret = sqlite3_step(stmt);
988                 if (ret != SQLITE_ROW) {
989                         _E("sqlite3_step() is failed. err(%s)",
990                                         sqlite3_errmsg(db));
991                         ret = WIDGET_ERROR_FAULT;
992                         goto err;
993                 }
994                 _get_column_int(stmt, 0, &width[i]);
995                 _get_column_int(stmt, 1, &height[i]);
996         }
997
998         if (_convert_to_support_info(width, height, type, count)) {
999                 _E("failed to convert size");
1000                 ret = WIDGET_ERROR_FAULT;
1001                 goto err;
1002         }
1003         *t = type;
1004         *w = width;
1005         *h = height;
1006         *cnt = count;
1007
1008         sqlite3_finalize(stmt);
1009         sqlite3_close_v2(db);
1010
1011         return WIDGET_ERROR_NONE;
1012
1013 err:
1014         if (type)
1015                 free(type);
1016         if (height)
1017                 free(height);
1018         if (width)
1019                 free(width);
1020         if (stmt)
1021                 sqlite3_finalize(stmt);
1022         if (db)
1023                 sqlite3_close_v2(db);
1024
1025         return ret;
1026 }
1027
1028 /* LCOV_EXCL_START */
1029 static int _instance_cb(const char *widget_id, const char *instance_id, void *data)
1030 {
1031         int ret;
1032         struct widget_instance_info_s *instance_info = (struct widget_instance_info_s *)data;
1033
1034         _D("widget_id %s, instance_id %s", widget_id, instance_id);
1035         if (strcmp(instance_info->instance_id, instance_id) == 0) {
1036                 ret = widget_instance_change_period(widget_id, instance_id, instance_info->period);
1037                 _D("ret %d ", ret);
1038                 if (ret >= 0)
1039                         instance_info->exists = true;
1040         }
1041         return WIDGET_ERROR_NONE;
1042 }
1043 /* LCOV_EXCL_STOP */
1044
1045 EAPI int widget_service_change_period(const char *pkgname, const char *id, double period)
1046 {
1047         widget_instance_h instance;
1048         struct widget_instance_info_s instance_info;
1049         int ret;
1050
1051         if (!_is_widget_feature_enabled()) {
1052                 _E("not supported");
1053                 return WIDGET_ERROR_NOT_SUPPORTED;
1054         }
1055
1056         if (!pkgname || !id || period < 0.0f) {
1057                 _E("invalid parameter");
1058                 return WIDGET_ERROR_INVALID_PARAMETER;
1059         }
1060
1061         instance = widget_instance_get_instance(pkgname, id);
1062         if (!instance) {
1063                 instance_info.instance_id = id;
1064                 instance_info.exists = false;
1065                 instance_info.period = period;
1066                 ret = widget_service_get_widget_instance_list(pkgname, _instance_cb, &instance_info);
1067                 _D("get list ret %d, %d", ret, instance_info.exists);
1068                 if (ret == 0 || !instance_info.exists) {
1069                         _E("instance not exists or out of bound(package)");
1070                         return WIDGET_ERROR_PERMISSION_DENIED;
1071                 }
1072                 ret = WIDGET_ERROR_NONE;
1073         } else {
1074                 ret = widget_instance_change_period(pkgname, id, period);
1075                 widget_instance_unref(instance);
1076                 if (ret > 0)
1077                         ret = WIDGET_ERROR_NONE;
1078         }
1079
1080         return ret;
1081 }
1082
1083 EAPI int widget_service_trigger_update(const char *widget_id, const char *id, bundle *b, int force)
1084 {
1085         int ret;
1086         bundle_raw *raw = NULL;
1087         int len;
1088
1089         if (!_is_widget_feature_enabled()) {
1090                 _E("not supported");
1091                 return WIDGET_ERROR_NOT_SUPPORTED;
1092         }
1093
1094         if (!widget_id) {
1095                 _E("invalid parameter");
1096                 return WIDGET_ERROR_INVALID_PARAMETER;
1097         }
1098
1099         if (b)
1100                 bundle_encode(b, &raw, &len);
1101
1102         ret = widget_instance_trigger_update_v2(widget_id, id, (const char *)raw, force);
1103
1104         if (raw)
1105                 free(raw);
1106
1107         return ret;
1108 }
1109
1110 struct widget_list_item {
1111         char *classid;
1112         char *pkgid;
1113         int is_prime;
1114 };
1115
1116 static void __free_widget_list(gpointer data)
1117 {
1118         struct widget_list_item *item = (struct widget_list_item *)data;
1119
1120         free(item->classid);
1121         free(item->pkgid);
1122         free(item);
1123 }
1124
1125 static int _get_widget_list(const char *pkgid, uid_t uid, GList **list)
1126 {
1127         static const char query[] =
1128                 "SELECT classid, pkgid, prime FROM widget_class WHERE is_disable = 0";
1129         static const char query_pkgid[] =
1130                 " AND pkgid = ?";
1131         char query_buf[MAX_BUF_SIZE];
1132         int ret;
1133         int len;
1134         sqlite3 *db;
1135         sqlite3_stmt *stmt;
1136         struct widget_list_item *item;
1137
1138         len = snprintf(query_buf, sizeof(query_buf), "%s", query);
1139         if (pkgid != NULL)
1140                 strncat(query_buf, query_pkgid, MAX_BUF_SIZE - len - 1);
1141
1142         db = _open_db(uid);
1143         if (db == NULL)
1144                 return WIDGET_ERROR_IO_ERROR;
1145
1146         ret = sqlite3_prepare_v2(db, query_buf, strlen(query_buf), &stmt, NULL);
1147         if (ret != SQLITE_OK) {
1148                 /* LCOV_EXCL_START */
1149                 _E("prepare error: %s", sqlite3_errmsg(db));
1150                 sqlite3_close_v2(db);
1151                 return WIDGET_ERROR_FAULT;
1152                 /* LCOV_EXCL_STOP */
1153         }
1154
1155         if (pkgid != NULL)
1156                 sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
1157
1158         while (sqlite3_step(stmt) == SQLITE_ROW) {
1159                 item = calloc(1, sizeof(struct widget_list_item));
1160                 if (item == NULL) {
1161                         /* LCOV_EXCL_START */
1162                         _E("out of memory");
1163                         sqlite3_finalize(stmt);
1164                         sqlite3_close_v2(db);
1165                         return WIDGET_ERROR_OUT_OF_MEMORY;
1166                         /* LCOV_EXCL_STOP */
1167                 }
1168
1169                 _get_column_str(stmt, 0, &item->classid);
1170                 _get_column_str(stmt, 1, &item->pkgid);
1171                 _get_column_int(stmt, 2, &item->is_prime);
1172
1173                 *list = g_list_append(*list, item);
1174         }
1175
1176         sqlite3_finalize(stmt);
1177         sqlite3_close_v2(db);
1178
1179         return WIDGET_ERROR_NONE;
1180 }
1181
1182 EAPI int widget_service_get_widget_list(widget_list_cb cb, void *data)
1183 {
1184         int ret;
1185         GList *list = NULL;
1186         GList *tmp;
1187         struct widget_list_item *item;
1188
1189         if (!_is_widget_feature_enabled()) {
1190                 _E("not supported");
1191                 return WIDGET_ERROR_NOT_SUPPORTED;
1192         }
1193
1194         if (cb == NULL) {
1195                 _E("invalid parameter");
1196                 return WIDGET_ERROR_INVALID_PARAMETER;
1197         }
1198
1199         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
1200                 return WIDGET_ERROR_PERMISSION_DENIED;
1201
1202         ret = _get_widget_list(NULL, getuid(), &list);
1203         if (ret == WIDGET_ERROR_NONE && !_is_global(getuid()))
1204                 _get_widget_list(NULL, GLOBALAPP_USER, &list);
1205
1206         for (tmp = list; tmp; tmp = tmp->next) {
1207                 item = (struct widget_list_item *)tmp->data;
1208                 /* TODO: get 'is_prime' */
1209                 if (cb(item->pkgid, item->classid, item->is_prime, data)
1210                                 != WIDGET_ERROR_NONE)
1211                         break;
1212         }
1213
1214         ret = g_list_length(list);
1215         g_list_free_full(list, __free_widget_list);
1216
1217         if (ret == 0)
1218                 return WIDGET_ERROR_NOT_EXIST;
1219
1220         return ret;
1221 }
1222
1223 EAPI int widget_service_get_widget_list_by_pkgid(const char *pkgid,
1224                 widget_list_by_pkgid_cb cb, void *data)
1225 {
1226         int ret;
1227         GList *list = NULL;
1228         GList *tmp;
1229         struct widget_list_item *item;
1230
1231         if (!_is_widget_feature_enabled()) {
1232                 _E("not supported");
1233                 return WIDGET_ERROR_NOT_SUPPORTED;
1234         }
1235
1236         if (pkgid == NULL || cb == NULL) {
1237                 _E("invalid parameter");
1238                 return WIDGET_ERROR_INVALID_PARAMETER;
1239         }
1240
1241         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
1242                 return WIDGET_ERROR_PERMISSION_DENIED;
1243
1244         ret = _get_widget_list(pkgid, getuid(), &list);
1245         if (ret == WIDGET_ERROR_NONE && !_is_global(getuid()))
1246                 _get_widget_list(pkgid, GLOBALAPP_USER, &list);
1247
1248         for (tmp = list; tmp; tmp = tmp->next) {
1249                 item = (struct widget_list_item *)tmp->data;
1250                 /* TODO: get 'is_prime' */
1251                 if (cb(item->classid, item->is_prime, data)
1252                                 != WIDGET_ERROR_NONE)
1253                         break;
1254         }
1255
1256         ret = g_list_length(list);
1257         g_list_free_full(list, __free_widget_list);
1258
1259         return ret;
1260 }
1261
1262 static char *_get_main_app_id(const char *widget_id, uid_t uid)
1263 {
1264         static const char query[] =
1265                 "SELECT pkgid FROM widget_class WHERE classid=?";
1266         int ret;
1267         sqlite3 *db;
1268         sqlite3_stmt *stmt;
1269         char *pkgid;
1270         pkgmgrinfo_pkginfo_h pkginfo;
1271         char *mainappid;
1272         char *appid;
1273
1274         db = _open_db(uid);
1275         if (db == NULL) {
1276                 set_last_result(WIDGET_ERROR_IO_ERROR);
1277                 return NULL;
1278         }
1279
1280         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1281         if (ret != SQLITE_OK) {
1282                 /* LCOV_EXCL_START */
1283                 _E("prepare error: %s", sqlite3_errmsg(db));
1284                 sqlite3_close_v2(db);
1285                 set_last_result(WIDGET_ERROR_FAULT);
1286                 return NULL;
1287                 /* LCOV_EXCL_STOP */
1288         }
1289
1290         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
1291
1292         ret = sqlite3_step(stmt);
1293         if (ret != SQLITE_ROW) {
1294                 sqlite3_finalize(stmt);
1295                 sqlite3_close_v2(db);
1296                 /* TODO: which error should be set? */
1297                 if (ret == SQLITE_DONE) {
1298                         set_last_result(WIDGET_ERROR_NOT_EXIST);
1299                 } else {
1300                         set_last_result(WIDGET_ERROR_FAULT);
1301                         _E("step error: %s", sqlite3_errmsg(db));
1302                 }
1303                 return NULL;
1304         }
1305
1306         _get_column_str(stmt, 0, &pkgid);
1307
1308         sqlite3_finalize(stmt);
1309         sqlite3_close_v2(db);
1310
1311         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, getuid(), &pkginfo);
1312         free(pkgid);
1313         if (ret != PMINFO_R_OK) {
1314                 set_last_result(WIDGET_ERROR_FAULT);
1315                 return NULL;
1316         }
1317
1318         ret = pkgmgrinfo_pkginfo_get_mainappid(pkginfo, &mainappid);
1319         if (ret != PMINFO_R_OK) {
1320                 _E("failed to get mainappid of widget %s", widget_id);
1321                 set_last_result(WIDGET_ERROR_FAULT);
1322                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
1323                 return NULL;
1324         }
1325
1326         appid = strdup(mainappid);
1327         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
1328
1329         set_last_result(WIDGET_ERROR_NONE);
1330
1331         return appid;
1332 }
1333
1334 EAPI char *widget_service_get_main_app_id(const char *widget_id)
1335 {
1336         char *appid;
1337
1338         if (!_is_widget_feature_enabled()) {
1339                 _E("not supported");
1340                 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
1341                 return NULL;
1342         }
1343
1344         if (widget_id == NULL) {
1345                 _E("invalid parameter");
1346                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
1347                 return NULL;
1348         }
1349
1350         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0) {
1351                 set_last_result(WIDGET_ERROR_PERMISSION_DENIED);
1352                 return NULL;
1353         }
1354
1355         appid = _get_main_app_id(widget_id, getuid());
1356         if (appid == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST
1357                         && !_is_global(getuid()))
1358                 appid = _get_main_app_id(widget_id, GLOBALAPP_USER);
1359
1360         if (!appid) {
1361                 _E("Failed to get main appid. widget(%s), result(%d)",
1362                                 widget_id, get_last_result());
1363         }
1364
1365         return appid;
1366 }
1367
1368 EAPI int widget_service_get_supported_size_types(const char *widget_id,
1369                 int *cnt, int **types)
1370 {
1371         int ret;
1372         int *width = NULL;
1373         int *height = NULL;
1374
1375         if (!_is_widget_feature_enabled()) {
1376                 _E("not supported");
1377                 return WIDGET_ERROR_NOT_SUPPORTED;
1378         }
1379
1380         if (widget_id == NULL || cnt == NULL || types == NULL) {
1381                 _E("invalid parameter");
1382                 return WIDGET_ERROR_INVALID_PARAMETER;
1383         }
1384
1385         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
1386                 return WIDGET_ERROR_PERMISSION_DENIED;
1387
1388         _D("id : %s", widget_id);
1389
1390         ret = _get_widget_supported_info(widget_id, getuid(), cnt,
1391                         &width, &height, types);
1392         if (ret == WIDGET_ERROR_NOT_EXIST && !_is_global(getuid()))
1393                 ret = _get_widget_supported_info(widget_id, GLOBALAPP_USER,
1394                                 cnt, &width, &height, types);
1395
1396         if (ret == WIDGET_ERROR_NOT_EXIST) {
1397                 _E("cannot find supported sizes for widget %s", widget_id);
1398                 *types = NULL;
1399                 return WIDGET_ERROR_NONE;
1400         } else if (ret != WIDGET_ERROR_NONE) {
1401                 return ret;
1402         }
1403
1404         free(width);
1405         free(height);
1406
1407         return WIDGET_ERROR_NONE;
1408 }
1409
1410 static char *_get_app_id_of_setup_app(const char *widget_id, uid_t uid)
1411 {
1412         static const char query[] =
1413                 "SELECT setup_appid FROM widget_class WHERE classid=?";
1414         int ret;
1415         sqlite3 *db;
1416         sqlite3_stmt *stmt;
1417         char *appid;
1418
1419         db = _open_db(uid);
1420         if (db == NULL) {
1421                 set_last_result(WIDGET_ERROR_IO_ERROR);
1422                 return NULL;
1423         }
1424
1425         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1426         if (ret != SQLITE_OK) {
1427                 /* LCOV_EXCL_START */
1428                 _E("prepare error: %s", sqlite3_errmsg(db));
1429                 sqlite3_close_v2(db);
1430                 set_last_result(WIDGET_ERROR_FAULT);
1431                 return NULL;
1432                 /* LCOV_EXCL_STOP */
1433         }
1434
1435         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
1436
1437         ret = sqlite3_step(stmt);
1438         if (ret != SQLITE_ROW) {
1439                 sqlite3_finalize(stmt);
1440                 sqlite3_close_v2(db);
1441                 /* TODO: which error should be set? */
1442                 if (ret == SQLITE_DONE) {
1443                         set_last_result(WIDGET_ERROR_NOT_EXIST);
1444                 } else {
1445                         set_last_result(WIDGET_ERROR_FAULT);
1446                         _E("step error: %s", sqlite3_errmsg(db));
1447                 }
1448                 return NULL;
1449         }
1450
1451         _get_column_str(stmt, 0, &appid);
1452
1453         sqlite3_finalize(stmt);
1454         sqlite3_close_v2(db);
1455
1456         set_last_result(WIDGET_ERROR_NONE);
1457
1458         return appid;
1459 }
1460
1461 EAPI char *widget_service_get_app_id_of_setup_app(const char *widget_id)
1462 {
1463         char *appid;
1464
1465         if (!_is_widget_feature_enabled()) {
1466                 _E("not supported");
1467                 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
1468                 return NULL;
1469         }
1470
1471         if (widget_id == NULL) {
1472                 _E("invalid parameter");
1473                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
1474                 return NULL;
1475         }
1476
1477         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0) {
1478                 _E("permission denied");
1479                 set_last_result(WIDGET_ERROR_PERMISSION_DENIED);
1480                 return NULL;
1481         }
1482
1483         appid = _get_app_id_of_setup_app(widget_id, getuid());
1484         if (appid == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST
1485                         && !_is_global(getuid()))
1486                 appid = _get_app_id_of_setup_app(widget_id, GLOBALAPP_USER);
1487
1488         if (!appid) {
1489                 _E("Failed to get setdup app. widget_id(%s), result(%d)",
1490                                 widget_id, get_last_result());
1491         }
1492
1493         return appid;
1494 }
1495
1496 static int _get_nodisplay(const char *widget_id, uid_t uid)
1497 {
1498         static const char query[] =
1499                 "SELECT nodisplay FROM widget_class WHERE classid=?";
1500         int ret;
1501         sqlite3 *db;
1502         sqlite3_stmt *stmt;
1503         int nodisplay = 0;
1504
1505         db = _open_db(uid);
1506         if (db == NULL) {
1507                 set_last_result(WIDGET_ERROR_IO_ERROR);
1508                 return 0;
1509         }
1510
1511         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1512         if (ret != SQLITE_OK) {
1513                 _E("prepare error: %s", sqlite3_errmsg(db));
1514                 sqlite3_close_v2(db);
1515                 set_last_result(WIDGET_ERROR_FAULT);
1516                 return 0;
1517         }
1518
1519         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
1520
1521         ret = sqlite3_step(stmt);
1522         if (ret != SQLITE_ROW) {
1523                 sqlite3_finalize(stmt);
1524                 sqlite3_close_v2(db);
1525                 /* TODO: which error should be set? */
1526                 if (ret == SQLITE_DONE) {
1527                         set_last_result(WIDGET_ERROR_NOT_EXIST);
1528                 } else {
1529                         set_last_result(WIDGET_ERROR_FAULT);
1530                         _E("step error: %s", sqlite3_errmsg(db));
1531                 }
1532                 return 0;
1533         }
1534
1535         _get_column_int(stmt, 0, &nodisplay);
1536
1537         sqlite3_finalize(stmt);
1538         sqlite3_close_v2(db);
1539
1540         set_last_result(WIDGET_ERROR_NONE);
1541
1542         return nodisplay;
1543 }
1544
1545 static int _get_update_period(const char *widget_id, uid_t uid, double *period)
1546 {
1547         static const char query[] =
1548                 "SELECT update_period FROM widget_class WHERE classid=?";
1549         int ret;
1550         sqlite3 *db;
1551         sqlite3_stmt *stmt;
1552
1553         db = _open_db(uid);
1554         if (db == NULL) {
1555                 return WIDGET_ERROR_IO_ERROR;
1556         }
1557
1558         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1559         if (ret != SQLITE_OK) {
1560                 _E("prepare error: %s", sqlite3_errmsg(db));
1561                 sqlite3_close_v2(db);
1562                 return WIDGET_ERROR_FAULT;
1563         }
1564
1565         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
1566
1567         ret = sqlite3_step(stmt);
1568         if (ret != SQLITE_ROW) {
1569                 sqlite3_finalize(stmt);
1570                 sqlite3_close_v2(db);
1571                 if (ret == SQLITE_DONE) {
1572                         return WIDGET_ERROR_NOT_EXIST;
1573                 } else {
1574                         _E("step error: %s", sqlite3_errmsg(db));
1575                         return WIDGET_ERROR_FAULT;
1576                 }
1577         }
1578
1579         _get_column_double(stmt, 0, period);
1580         sqlite3_finalize(stmt);
1581         sqlite3_close_v2(db);
1582
1583         return WIDGET_ERROR_NONE;
1584 }
1585
1586 int widget_service_get_update_period(const char *widget_id, double *period)
1587 {
1588         int ret;
1589
1590         ret = _get_update_period(widget_id, getuid(), period);
1591         if (ret == WIDGET_ERROR_NOT_EXIST)
1592                 ret = _get_update_period(widget_id, GLOBALAPP_USER, period);
1593
1594         if (ret != WIDGET_ERROR_NONE) {
1595                 _E("Failed to get update period. widget(%s), result(%d)",
1596                                 widget_id, ret);
1597         }
1598
1599         return ret;
1600 }
1601
1602 EAPI int widget_service_get_nodisplay(const char *widget_id)
1603 {
1604         int nodisplay;
1605
1606         if (!_is_widget_feature_enabled()) {
1607                 _E("not supported");
1608                 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
1609                 return 0;
1610         }
1611
1612         if (widget_id == NULL) {
1613                 _E("invalid parameter");
1614                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
1615                 return 0;
1616         }
1617
1618         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0) {
1619                 _E("permission denied");
1620                 set_last_result(WIDGET_ERROR_PERMISSION_DENIED);
1621                 return 0;
1622         }
1623
1624         nodisplay = _get_nodisplay(widget_id, getuid());
1625         if (get_last_result() == WIDGET_ERROR_NOT_EXIST
1626                         && !_is_global(getuid()))
1627                 nodisplay = _get_nodisplay(widget_id, GLOBALAPP_USER);
1628
1629         if (get_last_result() != WIDGET_ERROR_NONE) {
1630                 _E("Failed to get nodisplay. widget(%s), result(%d)",
1631                                 widget_id, get_last_result());
1632         }
1633
1634         return nodisplay;
1635 }
1636
1637 /* deprecated, always return need_of_frame as false */
1638 EAPI int widget_service_get_need_of_frame(const char *pkgid, widget_size_type_e size_type, bool *need_of_frame)
1639 {
1640         if (!_is_widget_feature_enabled()) {
1641                 _E("not supported");
1642                 return WIDGET_ERROR_NOT_SUPPORTED;
1643         }
1644
1645         if (!pkgid) {
1646                 _E("invalid parameter");
1647                 return WIDGET_ERROR_INVALID_PARAMETER;
1648         }
1649
1650         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
1651                 return WIDGET_ERROR_PERMISSION_DENIED;
1652
1653         *need_of_frame = false;
1654
1655         return WIDGET_ERROR_NONE;
1656 }
1657
1658 /* deprecated, always return need_of_touch_event as false */
1659 EAPI int widget_service_get_need_of_touch_effect(const char *pkgid, widget_size_type_e size_type, bool *need_of_touch_event)
1660 {
1661         if (!_is_widget_feature_enabled()) {
1662                 _E("not supported");
1663                 return WIDGET_ERROR_NOT_SUPPORTED;
1664         }
1665
1666         if (!pkgid) {
1667                 _E("invalid parameter");
1668                 return WIDGET_ERROR_INVALID_PARAMETER;
1669         }
1670
1671         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
1672                 return WIDGET_ERROR_PERMISSION_DENIED;
1673
1674         *need_of_touch_event = false;
1675
1676         return WIDGET_ERROR_NONE;
1677 }
1678
1679 /* deprecated, always return need_of_mouse_event as false */
1680 EAPI int widget_service_get_need_of_mouse_event(const char *pkgid, widget_size_type_e size_type, bool *need_of_mouse_event)
1681 {
1682         if (!_is_widget_feature_enabled()) {
1683                 _E("not supported");
1684                 return WIDGET_ERROR_NOT_SUPPORTED;
1685         }
1686
1687         if (!pkgid) {
1688                 _E("invalid parameter");
1689                 return WIDGET_ERROR_INVALID_PARAMETER;
1690         }
1691
1692         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
1693                 return WIDGET_ERROR_PERMISSION_DENIED;
1694
1695         *need_of_mouse_event = false;
1696         return WIDGET_ERROR_NONE;
1697 }
1698
1699 static char *_get_preview_image_path(const char *widget_id, int width,
1700                 int height, uid_t uid)
1701 {
1702         static const char query[] =
1703                 "SELECT preview FROM support_size WHERE "
1704                 "classid=? AND width=? AND height=?";
1705         int ret;
1706         sqlite3 *db;
1707         sqlite3_stmt *stmt;
1708         char *path;
1709
1710         db = _open_db(uid);
1711         if (db == NULL) {
1712                 set_last_result(WIDGET_ERROR_IO_ERROR);
1713                 return NULL;
1714         }
1715
1716         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1717         if (ret != SQLITE_OK) {
1718                 /* LCOV_EXCL_START */
1719                 _E("prepare error: %s", sqlite3_errmsg(db));
1720                 sqlite3_close_v2(db);
1721                 set_last_result(WIDGET_ERROR_FAULT);
1722                 return NULL;
1723                 /* LCOV_EXCL_STOP */
1724         }
1725
1726         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
1727         sqlite3_bind_int(stmt, 2, width);
1728         sqlite3_bind_int(stmt, 3, height);
1729
1730         ret = sqlite3_step(stmt);
1731         if (ret != SQLITE_ROW) {
1732                 sqlite3_finalize(stmt);
1733                 sqlite3_close_v2(db);
1734                 /* TODO: which error should be set? */
1735                 if (ret == SQLITE_DONE) {
1736                         set_last_result(WIDGET_ERROR_NOT_EXIST);
1737                 } else {
1738                         set_last_result(WIDGET_ERROR_FAULT);
1739                         _E("step error: %s", sqlite3_errmsg(db));
1740                 }
1741                 return NULL;
1742         }
1743
1744         _get_column_str(stmt, 0, &path);
1745
1746         sqlite3_finalize(stmt);
1747         sqlite3_close_v2(db);
1748
1749         set_last_result(WIDGET_ERROR_NONE);
1750
1751         return path;
1752 }
1753
1754 static int update_lang_info(void)
1755 {
1756         char *syslang;
1757         UErrorCode err;
1758         int country_len;
1759
1760         syslang = vconf_get_str(VCONFKEY_LANGSET);
1761         if (!syslang) {
1762                 ErrPrint("Failed to get vconf-lang");
1763                 return -EFAULT;
1764         }
1765
1766         if (_syslang && !strcmp(_syslang, syslang)) {
1767                 _D("Syslang is not changed: %s", syslang);
1768                 free(syslang);
1769                 return 0;
1770         }
1771
1772         free(_syslang);
1773         _syslang = syslang;
1774
1775         err = U_ZERO_ERROR;
1776         uloc_setDefault((const char *)_syslang, &err);
1777         if (!U_SUCCESS(err)) {
1778                 _E("Failed to set default lang: %s", u_errorName(err));
1779                 free(_syslang);
1780                 _syslang = NULL;
1781                 return -EFAULT;
1782         }
1783
1784         _iso3lang = uloc_getISO3Language(uloc_getDefault());
1785         if (!_iso3lang || !strlen(_iso3lang)) {
1786                 _E("Failed to get iso3lang");
1787                 free(_syslang);
1788                 _syslang = NULL;
1789                 return -EFAULT;
1790         }
1791
1792         err = U_ZERO_ERROR;
1793         country_len = uloc_getCountry(uloc_getDefault(), _country, ULOC_COUNTRY_CAPACITY, &err);
1794         if (!U_SUCCESS(err) || country_len <= 0) {
1795                 _E("Failed to get locale: %s, %s, %d (%s)", u_errorName(err), _iso3lang, country_len, _country);
1796                 free(_syslang);
1797                 _syslang = NULL;
1798                 return -EFAULT;
1799         }
1800
1801         return 0;
1802 }
1803
1804 EAPI char *widget_service_get_preview_image_path(const char *widget_id,
1805                 widget_size_type_e size_type)
1806 {
1807         char *path;
1808         int w = -1;
1809         int h = -1;
1810         char *lang_path;
1811         int buf_len;
1812         int i;
1813         int printed;
1814
1815         if (!_is_widget_feature_enabled()) {
1816                 _E("not supported");
1817                 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
1818                 return NULL;
1819         }
1820
1821         /* TODO: validate size_type */
1822         if (widget_id == NULL) {
1823                 _E("invalid parameter");
1824                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
1825                 return NULL;
1826         }
1827
1828         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0) {
1829                 set_last_result(WIDGET_ERROR_PERMISSION_DENIED);
1830                 return NULL;
1831         }
1832
1833         _convert_type_to_support_size_ratio(size_type, &w, &h);
1834         path = _get_preview_image_path(widget_id, w, h, getuid());
1835         if (path == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST
1836                         && !_is_global(getuid()))
1837                 path = _get_preview_image_path(widget_id, w, h, GLOBALAPP_USER);
1838
1839         if (path == NULL) {
1840                 _E("Can not find preview path");
1841                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
1842                 return NULL;
1843         }
1844
1845         if (update_lang_info() != 0)
1846                 return path;
1847
1848         buf_len = strlen(path) + strlen(_iso3lang) + strlen(_country) + 3; /* '/' '-' '/' */
1849         lang_path = malloc(buf_len + 1);
1850         if (!lang_path) {
1851                 /* LCOV_EXCL_START */
1852                 set_last_result(WIDGET_ERROR_OUT_OF_MEMORY);
1853                 _E("Heap: %d", errno);
1854                 free(path);
1855                 return NULL;
1856                 /* LCOV_EXCL_STOP */
1857         }
1858
1859         for (i = strlen(path); i >= 0 && path[i] != '/'; i--);
1860         i++; /* Skip '/' */
1861
1862         strncpy(lang_path, path, i);
1863         printed = snprintf(lang_path + i, buf_len - i, "%s-%s/%s", _iso3lang, _country, path + i);
1864         if (lang_path[i + printed] != '\0') {
1865                 _E("Path is truncated");
1866                 lang_path[i + printed] = '\0';
1867         }
1868
1869         if (access(lang_path, R_OK) != 0) {
1870                 _D("Access failed: %s, %d", lang_path, errno);
1871                 free(lang_path);
1872         } else {
1873                 free(path);
1874                 path = lang_path;
1875         }
1876
1877         return path;
1878 }
1879
1880
1881 static char *_get_main_widget_id(const char *pkg_id, uid_t uid)
1882 {
1883         static const char query[] =
1884                 "SELECT classid FROM widget_class "
1885                 "WHERE pkgid=? and prime=1 ";
1886         int ret;
1887         sqlite3 *db;
1888         sqlite3_stmt *stmt;
1889         char *widget_id;
1890
1891         db = _open_db(uid);
1892         if (db == NULL) {
1893                 set_last_result(WIDGET_ERROR_IO_ERROR);
1894                 return NULL;
1895         }
1896
1897         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1898         if (ret != SQLITE_OK) {
1899                 /* LCOV_EXCL_START */
1900                 _E("prepare error: %s", sqlite3_errmsg(db));
1901                 sqlite3_close_v2(db);
1902                 set_last_result(WIDGET_ERROR_FAULT);
1903                 return NULL;
1904                 /* LCOV_EXCL_STOP */
1905         }
1906
1907         sqlite3_bind_text(stmt, 1, pkg_id, -1, SQLITE_STATIC);
1908
1909         ret = sqlite3_step(stmt);
1910         if (ret != SQLITE_ROW) {
1911                 if (ret != SQLITE_DONE)
1912                         _E("step error: %s", sqlite3_errmsg(db));
1913                 sqlite3_finalize(stmt);
1914                 sqlite3_close_v2(db);
1915                 /* TODO: which error should be set? */
1916                 set_last_result(ret == SQLITE_DONE ? WIDGET_ERROR_NOT_EXIST :
1917                                 WIDGET_ERROR_FAULT);
1918                 return NULL;
1919         }
1920
1921         _get_column_str(stmt, 0, &widget_id);
1922
1923         sqlite3_finalize(stmt);
1924         sqlite3_close_v2(db);
1925
1926         set_last_result(WIDGET_ERROR_NONE);
1927
1928         return widget_id;
1929 }
1930
1931 static char *_get_icon(const char *widget_id, const char *lang, uid_t uid)
1932 {
1933         static const char query[] =
1934                 "SELECT icon FROM icon "
1935                 "WHERE classid=? AND (locale=? OR locale IS NULL) "
1936                 "ORDER BY locale DESC";
1937         int ret;
1938         sqlite3 *db;
1939         sqlite3_stmt *stmt;
1940         char *icon;
1941
1942         db = _open_db(uid);
1943         if (db == NULL) {
1944                 set_last_result(WIDGET_ERROR_IO_ERROR);
1945                 return NULL;
1946         }
1947
1948         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
1949         if (ret != SQLITE_OK) {
1950                 /* LCOV_EXCL_START */
1951                 _E("prepare error: %s", sqlite3_errmsg(db));
1952                 sqlite3_close_v2(db);
1953                 set_last_result(WIDGET_ERROR_FAULT);
1954                 return NULL;
1955                 /* LCOV_EXCL_STOP */
1956         }
1957
1958         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
1959         if (lang)
1960                 sqlite3_bind_text(stmt, 2, lang, -1, SQLITE_STATIC);
1961         else
1962                 sqlite3_bind_null(stmt, 2);
1963
1964         ret = sqlite3_step(stmt);
1965         if (ret != SQLITE_ROW) {
1966                 if (ret != SQLITE_DONE)
1967                         _E("step error: %s", sqlite3_errmsg(db));
1968                 sqlite3_finalize(stmt);
1969                 sqlite3_close_v2(db);
1970                 /* TODO: which error should be set? */
1971                 set_last_result(ret == SQLITE_DONE ? WIDGET_ERROR_NOT_EXIST :
1972                                 WIDGET_ERROR_FAULT);
1973                 return NULL;
1974         }
1975
1976         _get_column_str(stmt, 0, &icon);
1977
1978         sqlite3_finalize(stmt);
1979         sqlite3_close_v2(db);
1980
1981         set_last_result(WIDGET_ERROR_NONE);
1982
1983         return icon;
1984 }
1985
1986 EAPI char *widget_service_get_icon(const char *pkgid, const char *lang)
1987 {
1988         char *icon;
1989         char *widget_id;
1990
1991         if (!_is_widget_feature_enabled()) {
1992                 _E("not supported");
1993                 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
1994                 return NULL;
1995         }
1996
1997         if (pkgid == NULL) {
1998                 _E("invalid parameter");
1999                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
2000                 return NULL;
2001         }
2002
2003         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0) {
2004                 set_last_result(WIDGET_ERROR_PERMISSION_DENIED);
2005                 return NULL;
2006         }
2007
2008         widget_id = _get_main_widget_id(pkgid, getuid());
2009         if (widget_id == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST
2010                         && !_is_global(getuid()))
2011                 widget_id = _get_main_widget_id(pkgid, GLOBALAPP_USER);
2012
2013         icon = _get_icon(widget_id, lang, getuid());
2014         if (icon == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST
2015                         && !_is_global(getuid()))
2016                 icon = _get_icon(widget_id, lang, GLOBALAPP_USER);
2017
2018         if (!icon) {
2019                 _E("Failed to get icon. pkgid(%s), lang(%s), result(%d)",
2020                                 pkgid, lang, get_last_result());
2021         }
2022
2023         return icon;
2024 }
2025
2026 static char *_get_name(const char *widget_id, const char *lang, uid_t uid)
2027 {
2028         static const char query[] =
2029                 "SELECT label FROM label "
2030                 "WHERE classid=? AND (LOWER(locale)=LOWER(?) OR locale IS NULL) "
2031                 "ORDER BY locale DESC";
2032         int ret;
2033         sqlite3 *db;
2034         sqlite3_stmt *stmt;
2035         char *label;
2036
2037         db = _open_db(uid);
2038         if (db == NULL) {
2039                 set_last_result(WIDGET_ERROR_IO_ERROR);
2040                 return NULL;
2041         }
2042
2043         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2044         if (ret != SQLITE_OK) {
2045                 /* LCOV_EXCL_START */
2046                 _E("step error: %s", sqlite3_errmsg(db));
2047                 sqlite3_close_v2(db);
2048                 set_last_result(WIDGET_ERROR_FAULT);
2049                 return NULL;
2050                 /* LCOV_EXCL_STOP */
2051         }
2052
2053         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
2054         if (lang)
2055                 sqlite3_bind_text(stmt, 2, lang, -1, SQLITE_STATIC);
2056         else
2057                 sqlite3_bind_null(stmt, 2);
2058
2059         ret = sqlite3_step(stmt);
2060         if (ret != SQLITE_ROW) {
2061                 if (ret != SQLITE_DONE)
2062                         _E("step error: %s", sqlite3_errmsg(db));
2063                 sqlite3_finalize(stmt);
2064                 sqlite3_close_v2(db);
2065                 /* TODO: which error should be set? */
2066                 set_last_result(ret == SQLITE_DONE ? WIDGET_ERROR_NOT_EXIST :
2067                                 WIDGET_ERROR_FAULT);
2068                 return NULL;
2069         }
2070
2071         _get_column_str(stmt, 0, &label);
2072
2073         sqlite3_finalize(stmt);
2074         sqlite3_close_v2(db);
2075
2076         set_last_result(WIDGET_ERROR_NONE);
2077
2078         return label;
2079
2080 }
2081
2082 static char *__get_cur_locale(void)
2083 {
2084         char *language;
2085         char *ptr;
2086
2087         language = vconf_get_str(VCONFKEY_LANGSET);
2088         if (language) {
2089                 ptr = language;
2090                 while (*ptr) {
2091                         if (*ptr == '.') {
2092                                 *ptr = '\0';
2093                                 break;
2094                         }
2095
2096                         if (*ptr == '_')
2097                                 *ptr = '-';
2098
2099                         ptr++;
2100                 }
2101         } else {
2102                 language = strdup("en-us");
2103         }
2104
2105         return language;
2106 }
2107
2108 EAPI char *widget_service_get_name(const char *widget_id, const char *lang)
2109 {
2110         char *name;
2111         char *language;
2112
2113         if (!_is_widget_feature_enabled()) {
2114                 _E("not supported");
2115                 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
2116                 return NULL;
2117         }
2118
2119         if (widget_id == NULL) {
2120                 _E("invalid parameter");
2121                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
2122                 return NULL;
2123         }
2124
2125         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0) {
2126                 set_last_result(WIDGET_ERROR_PERMISSION_DENIED);
2127                 return NULL;
2128         }
2129
2130         if (!lang)
2131                 language = __get_cur_locale();
2132         else
2133                 language = strdup(lang);
2134
2135         if (!language) {
2136                 /* LCOV_EXCL_START */
2137                 _E("Out-of-memory");
2138                 set_last_result(WIDGET_ERROR_OUT_OF_MEMORY);
2139                 return NULL;
2140                 /* LCOV_EXCL_STOP */
2141         }
2142
2143         name = _get_name(widget_id, language, getuid());
2144         if (name == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST
2145                         && !_is_global(getuid()))
2146                 name = _get_name(widget_id, language, GLOBALAPP_USER);
2147
2148         if (!name) {
2149                 _E("Failed to get name. widget(%s), lang(%s), result(%d)",
2150                                 widget_id, lang, get_last_result());
2151         }
2152
2153         free(language);
2154
2155         return name;
2156 }
2157
2158 EAPI int widget_service_get_supported_sizes(const char *widget_id, int *cnt,
2159                 int **w, int **h)
2160 {
2161         int ret;
2162
2163         if (!_is_widget_feature_enabled()) {
2164                 _E("not supported");
2165                 return WIDGET_ERROR_NOT_SUPPORTED;
2166         }
2167
2168         if (widget_id == NULL || cnt == NULL || w == NULL || h == NULL) {
2169                 _E("invalid parameter");
2170                 return WIDGET_ERROR_INVALID_PARAMETER;
2171         }
2172
2173         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
2174                 return WIDGET_ERROR_PERMISSION_DENIED;
2175
2176         ret = _get_widget_supported_sizes(widget_id, getuid(), cnt, w, h);
2177         if (ret == WIDGET_ERROR_NOT_EXIST
2178                         && !_is_global(getuid()))
2179                 ret = _get_widget_supported_sizes(widget_id, GLOBALAPP_USER,
2180                                 cnt, w, h);
2181
2182         if (ret != WIDGET_ERROR_NONE) {
2183                 if (ret == WIDGET_ERROR_NOT_EXIST) {
2184                         _E("cannot find supported sizes for widget %s",
2185                                         widget_id);
2186                 } else {
2187                         _E("Failed to get widget(%s) supported size",
2188                                         widget_id);
2189                 }
2190         }
2191
2192         return ret;
2193 }
2194
2195 static char *_get_widget_id(const char *appid, uid_t uid)
2196 {
2197         static const char query[] =
2198                 "SELECT classid FROM widget_class WHERE appid=?";
2199         int ret;
2200         sqlite3 *db;
2201         sqlite3_stmt *stmt;
2202         char *classid;
2203
2204         db = _open_db(uid);
2205         if (db == NULL) {
2206                 set_last_result(WIDGET_ERROR_IO_ERROR);
2207                 return NULL;
2208         }
2209
2210         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2211         if (ret != SQLITE_OK) {
2212                 /* LCOV_EXCL_START */
2213                 _E("prepare error: %s", sqlite3_errmsg(db));
2214                 sqlite3_close_v2(db);
2215                 set_last_result(WIDGET_ERROR_FAULT);
2216                 return NULL;
2217                 /* LCOV_EXCL_STOP */
2218         }
2219
2220         sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_STATIC);
2221
2222         ret = sqlite3_step(stmt);
2223         if (ret != SQLITE_ROW) {
2224                 _E("step error: %s", sqlite3_errmsg(db));
2225                 sqlite3_finalize(stmt);
2226                 sqlite3_close_v2(db);
2227                 /* TODO: which error should be set? */
2228                 set_last_result(ret == SQLITE_DONE ? WIDGET_ERROR_NOT_EXIST :
2229                                 WIDGET_ERROR_FAULT);
2230                 return NULL;
2231         }
2232
2233         _get_column_str(stmt, 0, &classid);
2234
2235         sqlite3_finalize(stmt);
2236         sqlite3_close_v2(db);
2237
2238         set_last_result(WIDGET_ERROR_NONE);
2239
2240         return classid;
2241 }
2242
2243 static char *__get_widget_main_appid_from_pkgid_or_appid(const char *id)
2244 {
2245         pkgmgrinfo_appinfo_h appinfo = NULL;
2246         pkgmgrinfo_pkginfo_h pkginfo = NULL;
2247         char *new_pkgid = NULL;
2248         char *pkgid = NULL;
2249         GList *widget_list = NULL;
2250         GList *iter;
2251         char *widget_id = NULL;
2252         int ret;
2253         struct widget_list_item *item;
2254
2255         ret = pkgmgrinfo_pkginfo_get_pkginfo(id, &pkginfo);
2256         if (ret != PMINFO_R_OK) {
2257                 ret = pkgmgrinfo_appinfo_get_appinfo(id, &appinfo);
2258                 if (ret != PMINFO_R_OK) {
2259                         _E("Failed to get app/pkg info - %s", id);
2260                         goto end;
2261                 }
2262
2263                 ret = pkgmgrinfo_appinfo_get_pkgid(appinfo, &pkgid);
2264                 if (ret != PMINFO_R_OK) {
2265                         _E("Failed to get pkgid - %s", id);
2266                         goto end;
2267                 }
2268
2269                 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkginfo);
2270                 if (ret != PMINFO_R_OK) {
2271                         _E("Failed to get pkginfo - %s", id);
2272                         goto end;
2273                 }
2274
2275                 new_pkgid = strdup(pkgid);
2276                 if (new_pkgid == NULL) {
2277                         _E("out of memory"); /* LCOV_EXCL_LINE */
2278                         goto end; /* LCOV_EXCL_LINE */
2279                 }
2280                 id = new_pkgid;
2281         }
2282
2283         ret = _get_widget_list(id, getuid(), &widget_list);
2284         if ((ret != WIDGET_ERROR_NONE || widget_list == NULL)
2285                         && !_is_global(getuid()))
2286                 ret = _get_widget_list(id, GLOBALAPP_USER, &widget_list);
2287
2288         if (widget_list == NULL)
2289                 goto end;
2290
2291         iter = g_list_first(widget_list);
2292         while (iter) {
2293                 item = (struct widget_list_item *)iter->data;
2294                 iter = g_list_next(iter);
2295                 if (item) {
2296                         widget_list = g_list_remove(widget_list, item);
2297                         if (item->is_prime) {
2298                                 if (widget_id)
2299                                         free(widget_id);
2300                                 widget_id = strdup(item->classid);
2301                         }
2302
2303                         if (widget_id == NULL)
2304                                 widget_id = strdup(item->classid);
2305
2306                         free(item->classid);
2307                         free(item->pkgid);
2308                         free(item);
2309                 }
2310         }
2311
2312 end:
2313         if (pkginfo)
2314                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
2315         if (appinfo)
2316                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
2317         if (new_pkgid)
2318                 free(new_pkgid);
2319
2320         return widget_id;
2321 }
2322
2323 EAPI char *widget_service_get_widget_id(const char *appid)
2324 {
2325         char *classid;
2326         char *widget_id;
2327
2328         if (!_is_widget_feature_enabled()) {
2329                 _E("not supported");
2330                 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
2331                 return NULL;
2332         }
2333
2334         if (appid == NULL) {
2335                 _E("invalid parameter");
2336                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
2337                 return NULL;
2338         }
2339
2340         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0) {
2341                 set_last_result(WIDGET_ERROR_PERMISSION_DENIED);
2342                 return NULL;
2343         }
2344
2345         classid = _get_widget_id(appid, getuid());
2346         if (classid == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST
2347                         && !_is_global(getuid()))
2348                 classid = _get_widget_id(appid, GLOBALAPP_USER);
2349
2350         if (classid)
2351                 return classid;
2352         else if (get_last_result() != WIDGET_ERROR_NOT_EXIST)
2353                 return NULL;
2354
2355         widget_id = __get_widget_main_appid_from_pkgid_or_appid(appid);
2356         if (widget_id == NULL) {
2357                 _E("Failed to get widget id");
2358                 return NULL;
2359         }
2360
2361         classid = _get_widget_id(widget_id, getuid());
2362         if (classid == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST
2363                         && !_is_global(getuid()))
2364                 classid = _get_widget_id(widget_id, GLOBALAPP_USER);
2365
2366         if (!classid) {
2367                 _E("Failed to get widget id. appid(%s), result(%d)",
2368                                 appid, get_last_result());
2369         }
2370
2371         free(widget_id);
2372
2373         return classid;
2374 }
2375
2376 static char *_get_package_id(const char *widget_id, uid_t uid)
2377 {
2378         static const char query[] =
2379                 "SELECT pkgid FROM widget_class WHERE classid=?";
2380         int ret;
2381         sqlite3 *db;
2382         sqlite3_stmt *stmt;
2383         char *pkgid;
2384
2385         db = _open_db(uid);
2386         if (db == NULL) {
2387                 set_last_result(WIDGET_ERROR_IO_ERROR);
2388                 return NULL;
2389         }
2390
2391         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2392         if (ret != SQLITE_OK) {
2393                 /* LCOV_EXCL_START */
2394                 _E("prepare error: %s", sqlite3_errmsg(db));
2395                 sqlite3_close_v2(db);
2396                 set_last_result(WIDGET_ERROR_FAULT);
2397                 return NULL;
2398                 /* LCOV_EXCL_STOP */
2399         }
2400
2401         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
2402
2403         ret = sqlite3_step(stmt);
2404         if (ret != SQLITE_ROW) {
2405                 sqlite3_finalize(stmt);
2406                 sqlite3_close_v2(db);
2407                 /* TODO: which error should be set? */
2408                 if (ret == SQLITE_DONE) {
2409                         set_last_result(WIDGET_ERROR_NOT_EXIST);
2410                 } else {
2411                         set_last_result(WIDGET_ERROR_FAULT);
2412                         _E("step error: %s", sqlite3_errmsg(db));
2413                 }
2414                 return NULL;
2415         }
2416
2417         _get_column_str(stmt, 0, &pkgid);
2418
2419         sqlite3_finalize(stmt);
2420         sqlite3_close_v2(db);
2421
2422         set_last_result(WIDGET_ERROR_NONE);
2423
2424         return pkgid;
2425 }
2426
2427 EAPI char *widget_service_get_package_id(const char *widget_id)
2428 {
2429         char *pkgid;
2430
2431         if (!_is_widget_feature_enabled()) {
2432                 _E("not supported");
2433                 set_last_result(WIDGET_ERROR_NOT_SUPPORTED);
2434                 return NULL;
2435         }
2436
2437         if (widget_id == NULL) {
2438                 _E("invalid parameter");
2439                 set_last_result(WIDGET_ERROR_INVALID_PARAMETER);
2440                 return NULL;
2441         }
2442
2443         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0) {
2444                 set_last_result(WIDGET_ERROR_PERMISSION_DENIED);
2445                 return NULL;
2446         }
2447
2448         pkgid = _get_package_id(widget_id, getuid());
2449         if (pkgid == NULL && get_last_result() == WIDGET_ERROR_NOT_EXIST
2450                         && !_is_global(getuid()))
2451                 pkgid = _get_package_id(widget_id, GLOBALAPP_USER);
2452
2453         if (!pkgid) {
2454                 _E("Failed to get package id. widget(%s), result(%d)",
2455                                 widget_id, get_last_result());
2456         }
2457
2458         return pkgid;
2459 }
2460
2461 EAPI int widget_service_get_size(widget_size_type_e type, int *width,
2462                 int *height)
2463 {
2464         if (!_is_widget_feature_enabled()) {
2465                 _E("not supported");
2466                 return WIDGET_ERROR_NOT_SUPPORTED;
2467         }
2468
2469         if (width == NULL || height == NULL) {
2470                 _E("invalid parameter");
2471                 return WIDGET_ERROR_INVALID_PARAMETER;
2472         }
2473
2474         if (_get_supported_size(type, width, height))
2475                 return WIDGET_ERROR_INVALID_PARAMETER;
2476
2477         return WIDGET_ERROR_NONE;
2478 }
2479
2480 EAPI int widget_service_get_size_type(int width, int height,
2481                 widget_size_type_e *size_type)
2482 {
2483         if (!_is_widget_feature_enabled()) {
2484                 _E("not supported");
2485                 return WIDGET_ERROR_NOT_SUPPORTED;
2486         }
2487
2488         if (width <= 0 || height <= 0 || size_type == NULL) {
2489                 _E("invalid parameter");
2490                 return WIDGET_ERROR_INVALID_PARAMETER;
2491         }
2492
2493         if (_get_supported_size_type(width, height, (int *)size_type))
2494                 return WIDGET_ERROR_INVALID_PARAMETER;
2495
2496         return WIDGET_ERROR_NONE;
2497 }
2498
2499 EAPI int widget_service_get_content_of_widget_instance(const char *widget_id, const char *widget_instance_id, bundle **b)
2500 {
2501         char *raw = NULL;
2502         int ret;
2503
2504         if (!_is_widget_feature_enabled()) {
2505                 _E("not supported");
2506                 return WIDGET_ERROR_NOT_SUPPORTED;
2507         }
2508
2509         if (widget_id == NULL || widget_instance_id == NULL || b == NULL) {
2510                 _E("invalid parameter");
2511                 return WIDGET_ERROR_INVALID_PARAMETER;
2512         }
2513
2514         ret = aul_widget_instance_get_content(widget_id, widget_instance_id, &raw);
2515         if (raw) {
2516                 *b = bundle_decode((const bundle_raw *)raw, strlen(raw));
2517                 free(raw);
2518                 return WIDGET_ERROR_NONE;
2519         }
2520
2521         switch (ret) {
2522         case AUL_R_EINVAL:
2523                 ret = WIDGET_ERROR_INVALID_PARAMETER;
2524                 break;
2525         case AUL_R_ECOMM:
2526                 ret = WIDGET_ERROR_IO_ERROR;
2527                 break;
2528         case AUL_R_ENOAPP:
2529                 ret = WIDGET_ERROR_NOT_EXIST;
2530                 break;
2531         case AUL_R_EILLACC:
2532                 ret = WIDGET_ERROR_PERMISSION_DENIED;
2533                 break;
2534         default:
2535                 ret = WIDGET_ERROR_FAULT;
2536         }
2537
2538         return ret;
2539 }
2540
2541 struct instance_cb {
2542         const char  *widget_id;
2543         widget_instance_list_cb cb;
2544         void *data;
2545         int cnt;
2546 };
2547
2548 /* LCOV_EXCL_START */
2549 static void __instance_list_cb(const char *instance_id, void *user_data)
2550 {
2551         struct instance_cb *cb_data = (struct instance_cb *)user_data;
2552
2553         if (!cb_data)
2554                 return;
2555
2556         cb_data->cnt++;
2557
2558         _D("instance list: %s %s", cb_data->widget_id, instance_id);
2559         if (cb_data->cb)
2560                 cb_data->cb(cb_data->widget_id, instance_id, cb_data->data);
2561 }
2562 /* LCOV_EXCL_STOP */
2563
2564 EAPI int widget_service_get_widget_instance_list(const char *widget_id, widget_instance_list_cb cb, void *data)
2565 {
2566         struct instance_cb cb_data;
2567         int ret;
2568
2569         cb_data.widget_id = widget_id;
2570         cb_data.cb = cb;
2571         cb_data.data = data;
2572         cb_data.cnt = 0;
2573
2574         if (!_is_widget_feature_enabled()) {
2575                 _E("not supported");
2576                 return WIDGET_ERROR_NOT_SUPPORTED;
2577         }
2578
2579         if (widget_id == NULL || cb == NULL) {
2580                 _E("inavlid parameter");
2581                 return WIDGET_ERROR_INVALID_PARAMETER;
2582         }
2583
2584         ret = aul_widget_instance_foreach(widget_id, __instance_list_cb, &cb_data);
2585
2586         if (ret == AUL_R_EILLACC)
2587                 return WIDGET_ERROR_PERMISSION_DENIED;
2588
2589         if (ret == AUL_R_ENOAPP || cb_data.cnt == 0)
2590                 return WIDGET_ERROR_NOT_EXIST;
2591
2592         return cb_data.cnt;
2593 }
2594
2595 struct lifecycle_s {
2596         char *widget_id;
2597         widget_lifecycle_event_cb cb;
2598         void *data;
2599 };
2600
2601 static int __listen_status(const char *widget_id, const char *instance_id, int status, void *data)
2602 {
2603         struct lifecycle_s *cb_info = (struct lifecycle_s *)data;
2604
2605         if (!cb_info)
2606                 return 0;
2607
2608         cb_info->cb(widget_id, status, instance_id, cb_info->data);
2609
2610         return 0;
2611 }
2612
2613 EAPI int widget_service_set_lifecycle_event_cb(const char *widget_id, widget_lifecycle_event_cb cb, void *data)
2614 {
2615         int ret = WIDGET_ERROR_NONE;
2616         struct lifecycle_s *cb_info;
2617         GList *head = lifecycle_cbs;
2618
2619         if (!_is_widget_feature_enabled()) {
2620                 _E("not supported");
2621                 return WIDGET_ERROR_NOT_SUPPORTED;
2622         }
2623
2624         if (cb == NULL) {
2625                 _E("invalid parameter");
2626                 return WIDGET_ERROR_INVALID_PARAMETER;
2627         }
2628
2629         while (head) {
2630                 cb_info = (struct lifecycle_s *)head->data;
2631                 if (cb_info && widget_id && cb_info->widget_id) {
2632                         if (strlen(widget_id) != strlen(cb_info->widget_id)) {
2633                                 head = head->next;
2634                                 continue;
2635                         }
2636
2637                         if (strncmp(cb_info->widget_id, widget_id, strlen(widget_id)) == 0)
2638                                 return WIDGET_ERROR_INVALID_PARAMETER;
2639
2640                 } else if (cb_info && widget_id == NULL && cb_info->widget_id == NULL) {
2641                         return WIDGET_ERROR_INVALID_PARAMETER;
2642                 }
2643
2644                 head = head->next;
2645         }
2646
2647         cb_info = (struct lifecycle_s *)malloc(sizeof(struct lifecycle_s));
2648         if (cb_info == NULL)
2649                 return WIDGET_ERROR_OUT_OF_MEMORY;
2650
2651         if (widget_id)
2652                 cb_info->widget_id = strdup(widget_id);
2653         else
2654                 cb_info->widget_id = NULL;
2655
2656         cb_info->cb = cb;
2657         cb_info->data = data;
2658
2659         lifecycle_cbs = g_list_append(lifecycle_cbs, cb_info);
2660
2661         widget_instance_listen_status(widget_id, __listen_status, cb_info);
2662
2663         return ret;
2664 }
2665
2666 EAPI int widget_service_unset_lifecycle_event_cb(const char *widget_id, void **user_data)
2667 {
2668         struct lifecycle_s *cb_info;
2669         struct lifecycle_s *found = NULL;
2670         GList *head = lifecycle_cbs;
2671
2672         if (!_is_widget_feature_enabled()) {
2673                 _E("not supported");
2674                 return WIDGET_ERROR_NOT_SUPPORTED;
2675         }
2676
2677         while (head) {
2678                 cb_info = (struct lifecycle_s *)head->data;
2679                 if (cb_info && widget_id && cb_info->widget_id) {
2680                         if (strncmp(cb_info->widget_id, widget_id, strlen(widget_id)) == 0) {
2681                                 found = cb_info;
2682                                 break;
2683                         }
2684                 } else if (cb_info && widget_id == NULL && cb_info->widget_id == NULL) {
2685                         found = cb_info;
2686                         break;
2687                 }
2688
2689                 head = head->next;
2690         }
2691
2692         if (found) {
2693                 lifecycle_cbs = g_list_remove(lifecycle_cbs, found);
2694                 if (user_data)
2695                         *user_data = found->data;
2696
2697                 if (found->widget_id)
2698                         free(found->widget_id);
2699
2700                 free(found);
2701
2702                 widget_instance_unlisten_status(widget_id);
2703
2704                 return WIDGET_ERROR_NONE;
2705         }
2706
2707         return WIDGET_ERROR_NOT_EXIST;
2708 }
2709
2710 static int __get_max_instance(const char *widget_id, uid_t uid)
2711 {
2712         static const char query[] =
2713                 "SELECT max_instance FROM widget_class WHERE classid=?";
2714         int ret;
2715         sqlite3 *db;
2716         sqlite3_stmt *stmt;
2717         int max_instance = 0;
2718
2719         db = _open_db(uid);
2720         if (db == NULL)
2721                 return WIDGET_ERROR_IO_ERROR;
2722
2723         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2724         if (ret != SQLITE_OK) {
2725                 _E("prepare error: %s", sqlite3_errmsg(db));
2726                 sqlite3_close_v2(db);
2727                 return WIDGET_ERROR_FAULT;
2728         }
2729
2730         sqlite3_bind_text(stmt, 1, widget_id, -1, SQLITE_STATIC);
2731
2732         ret = sqlite3_step(stmt);
2733         if (ret != SQLITE_ROW) {
2734                 sqlite3_finalize(stmt);
2735                 sqlite3_close_v2(db);
2736                 if (ret == SQLITE_DONE) {
2737                         return WIDGET_ERROR_NOT_EXIST;
2738                 } else {
2739                         _E("step error: %s", sqlite3_errmsg(db));
2740                         return WIDGET_ERROR_FAULT;
2741                 }
2742         }
2743
2744         _get_column_int(stmt, 0, &max_instance);
2745         _D("widget_id: %s, max-instance: %d", widget_id, max_instance);
2746
2747         sqlite3_finalize(stmt);
2748         sqlite3_close_v2(db);
2749
2750         return max_instance;
2751 }
2752
2753 EAPI int widget_service_get_widget_max_count(const char *widget_id)
2754 {
2755         int ret;
2756
2757         if (!_is_widget_feature_enabled()) {
2758                 _E("Not supported");
2759                 return WIDGET_ERROR_NOT_SUPPORTED;
2760         }
2761
2762         if (widget_id == NULL) {
2763                 _E("Invalid parameter");
2764                 return WIDGET_ERROR_INVALID_PARAMETER;
2765         }
2766
2767         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
2768                 return WIDGET_ERROR_PERMISSION_DENIED;
2769
2770         ret = __get_max_instance(widget_id, getuid());
2771         if (ret == WIDGET_ERROR_NOT_EXIST && !_is_global(getuid()))
2772                 ret = __get_max_instance(widget_id, GLOBALAPP_USER);
2773         _I("Widget(%s) max count. result(%d)", widget_id, ret);
2774
2775         return ret;
2776 }
2777
2778 EAPI int widget_service_get_instance_count(const char *widget_id, const char *cluster, const char *category)
2779 {
2780         int ret;
2781
2782         if (!_is_widget_feature_enabled()) {
2783                 _E("Not supported");
2784                 return WIDGET_ERROR_NOT_SUPPORTED;
2785         }
2786
2787         if (widget_id == NULL) {
2788                 _E("Invalid parameter");
2789                 return WIDGET_ERROR_INVALID_PARAMETER;
2790         }
2791
2792         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
2793                 return WIDGET_ERROR_PERMISSION_DENIED;
2794
2795         ret = aul_widget_instance_count(widget_id);
2796         if (ret == AUL_R_EILLACC)
2797                 return WIDGET_ERROR_PERMISSION_DENIED;
2798
2799         return ret;
2800 }
2801
2802 EAPI int widget_service_set_widget_disabled(const char *widget_id,
2803                 bool disabled)
2804 {
2805         int ret;
2806
2807         if (!_is_widget_feature_enabled()) {
2808                 _E("Not supported");
2809                 return WIDGET_ERROR_NOT_SUPPORTED;
2810         }
2811
2812         if (widget_id == NULL) {
2813                 _E("Invalid parameter");
2814                 return WIDGET_ERROR_INVALID_PARAMETER;
2815         }
2816
2817         ret = aul_widget_service_set_disable(widget_id, disabled);
2818         if (ret) {
2819                 _E("set disable error : %d", ret);
2820                 switch (ret) {
2821                 case AUL_R_ECOMM:
2822                         ret = WIDGET_ERROR_IO_ERROR;
2823                         break;
2824                 case AUL_R_EILLACC:
2825                         ret = WIDGET_ERROR_PERMISSION_DENIED;
2826                         break;
2827                 default:
2828                         ret = WIDGET_ERROR_FAULT;
2829                 }
2830         }
2831
2832         return ret;
2833 }
2834
2835 static int _get_disable(const char *widget_id, bool *is_disabled, uid_t uid)
2836 {
2837         int ret;
2838         sqlite3 *db;
2839         sqlite3_stmt *stmt;
2840         char *query;
2841         int disable;
2842
2843         query = sqlite3_mprintf("SELECT is_disable FROM widget_class"
2844             " WHERE classid = %Q", widget_id);
2845
2846         db = _open_db(uid);
2847         if (db == NULL) {
2848                 _E("_get_disable db null");
2849                 sqlite3_free(query);
2850                 return WIDGET_ERROR_IO_ERROR;
2851         }
2852
2853         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
2854         if (ret != SQLITE_OK) {
2855                 _E("prepare error: %s", sqlite3_errmsg(db));
2856                 sqlite3_free(query);
2857                 sqlite3_close_v2(db);
2858                 return WIDGET_ERROR_FAULT;
2859         }
2860
2861         ret = sqlite3_step(stmt);
2862         if (ret != SQLITE_ROW) {
2863                 sqlite3_free(query);
2864                 sqlite3_finalize(stmt);
2865                 sqlite3_close_v2(db);
2866                 if (ret == SQLITE_DONE) {
2867                         return WIDGET_ERROR_NOT_EXIST;
2868                 } else {
2869                         _E("step error: %s, %d", sqlite3_errmsg(db), ret);
2870                         return WIDGET_ERROR_FAULT;
2871                 }
2872         }
2873         _get_column_int(stmt, 0, &disable);
2874
2875         *is_disabled = (bool)disable;
2876
2877         sqlite3_free(query);
2878         sqlite3_finalize(stmt);
2879         sqlite3_close_v2(db);
2880
2881         return WIDGET_ERROR_NONE;
2882 }
2883
2884 EAPI int widget_service_get_widget_disabled(const char *widget_id,
2885                 bool *is_disabled)
2886 {
2887         int ret;
2888
2889         if (!_is_widget_feature_enabled()) {
2890                 _E("Not supported");
2891                 return WIDGET_ERROR_NOT_SUPPORTED;
2892         }
2893
2894         if (widget_id == NULL || is_disabled == NULL) {
2895                 _E("Invalid parameter");
2896                 return WIDGET_ERROR_INVALID_PARAMETER;
2897         }
2898
2899         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
2900                 return WIDGET_ERROR_PERMISSION_DENIED;
2901
2902         ret = _get_disable(widget_id, is_disabled, getuid());
2903         if (ret != WIDGET_ERROR_NONE && !_is_global(getuid())) {
2904                 ret = _get_disable(widget_id, is_disabled, GLOBALAPP_USER);
2905                 if (ret)
2906                         _E("failed to get disable");
2907         }
2908
2909         return ret;
2910 }
2911
2912 static void __notify_disable(const char *widget_id, bool is_disabled)
2913 {
2914         _disable_event_cb(widget_id, is_disabled, _disable_user_data);
2915 }
2916
2917 static int __disable_cb(const char *endpoint, aul_app_com_result_e e,
2918                 bundle *widget_info, void *user_data)
2919 {
2920         char *disable = NULL;
2921         char *widget_id = NULL;
2922
2923         bundle_get_str(widget_info, AUL_K_WIDGET_DISABLE, &disable);
2924         bundle_get_str(widget_info, AUL_K_WIDGET_ID, &widget_id);
2925
2926         __notify_disable(widget_id, (bool)atoi(disable));
2927
2928         return WIDGET_ERROR_NONE;
2929 }
2930
2931 EAPI int widget_service_set_disable_event_cb(widget_disable_event_cb callback,
2932                 void *user_data)
2933 {
2934         if (callback == NULL) {
2935                 _E("invalid parameter");
2936                 return WIDGET_ERROR_INVALID_PARAMETER;
2937         }
2938
2939         if (!_is_widget_feature_enabled()) {
2940                 _E("Not supported");
2941                 return WIDGET_ERROR_NOT_SUPPORTED;
2942         }
2943
2944         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
2945                 return WIDGET_ERROR_PERMISSION_DENIED;
2946
2947         if (aul_app_com_create(DISABLE_ENDPOINT, NULL,
2948                         __disable_cb, NULL, &_conn) < 0) {
2949                 _E("failed to create app com endpoint");
2950                 return WIDGET_ERROR_IO_ERROR;
2951         }
2952
2953         _disable_event_cb = callback;
2954         _disable_user_data = user_data;
2955
2956         return WIDGET_ERROR_NONE;
2957 }
2958
2959 EAPI int widget_service_unset_disable_event_cb(void)
2960 {
2961         if (!_is_widget_feature_enabled()) {
2962                 _E("not supported");
2963                 return WIDGET_ERROR_NOT_SUPPORTED;
2964         }
2965
2966         if (check_privilege("http://tizen.org/privilege/widget.viewer") < 0)
2967                 return WIDGET_ERROR_PERMISSION_DENIED;
2968
2969         if (_conn) {
2970                 if (aul_app_com_leave(_conn) < 0) {
2971                         _E("failed to leave app com disable");
2972                         return WIDGET_ERROR_IO_ERROR;
2973                 }
2974                 _conn = NULL;
2975         } else {
2976                 return WIDGET_ERROR_IO_ERROR;
2977         }
2978
2979         if (_disable_event_cb)
2980                 _disable_event_cb = NULL;
2981
2982         if (_disable_user_data)
2983                 _disable_user_data = NULL;
2984
2985         return WIDGET_ERROR_NONE;
2986 }