Fix clear cache
[platform/core/appfw/slp-pkgmgr.git] / client / src / pkgmgr.c
1 /*
2  * slp-pkgmgr
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <dlfcn.h>
28 #include <dirent.h>
29 #include <fcntl.h>
30 #include <sys/wait.h>
31 #include <sys/time.h>
32
33 #include <glib.h>
34
35 #include <pkgmgr-info.h>
36 #include <iniparser.h>
37 /* For multi-user support */
38 #include <tzplatform_config.h>
39
40 #include "package-manager.h"
41 #include "pkgmgr-internal.h"
42 #include "pkgmgr-debug.h"
43 #include "pkgmgr-api.h"
44 #include "comm_client.h"
45
46 #define PKG_TMP_PATH tzplatform_mkpath(TZ_USER_APP, "tmp")
47
48 #define BINSH_NAME      "/bin/sh"
49 #define BINSH_SIZE      7
50
51 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
52
53 static int _get_request_id()
54 {
55         static int internal_req_id = 1;
56
57         return internal_req_id++;
58 }
59
60 typedef struct _req_cb_info {
61         int request_id;
62         char *req_key;
63         pkgmgr_handler event_cb;
64         void *data;
65         struct _req_cb_info *next;
66 } req_cb_info;
67
68 typedef struct _listen_cb_info {
69         int request_id;
70         pkgmgr_handler event_cb;
71         void *data;
72         struct _listen_cb_info *next;
73 } listen_cb_info;
74
75 typedef struct _pkgmgr_client_t {
76         client_type ctype;
77         int status_type;
78         union {
79                 struct _request {
80                         comm_client *cc;
81                         req_cb_info *rhead;
82                 } request;
83                 struct _listening {
84                         comm_client *cc;
85                         listen_cb_info *lhead;
86                 } listening;
87         } info;
88         void *new_event_cb;
89 } pkgmgr_client_t;
90
91 typedef struct _iter_data {
92         pkgmgr_iter_fn iter_fn;
93         void *data;
94 } iter_data;
95
96 static int __xsystem(const char *argv[])
97 {
98         int status = 0;
99         pid_t pid;
100         pid = fork();
101         switch (pid) {
102         case -1:
103                 perror("fork failed");
104                 return -1;
105         case 0:
106                 /* child */
107                 execvp(argv[0], (char *const *)argv);
108                 _exit(-1);
109         default:
110                 /* parent */
111                 break;
112         }
113         if (waitpid(pid, &status, 0) == -1) {
114                 perror("waitpid failed");
115                 return -1;
116         }
117         if (WIFSIGNALED(status)) {
118                 perror("signal");
119                 return -1;
120         }
121         if (!WIFEXITED(status)) {
122                 /* shouldn't happen */
123                 perror("should not happen");
124                 return -1;
125         }
126         return WEXITSTATUS(status);
127 }
128
129 static void __error_to_string(int errnumber, char **errstr)
130 {
131         if (errstr == NULL)
132                 return;
133         switch (errnumber) {
134         case PKGCMD_ERR_PACKAGE_NOT_FOUND:
135                 *errstr = PKGCMD_ERR_PACKAGE_NOT_FOUND_STR;
136                 break;
137         case PKGCMD_ERR_PACKAGE_INVALID:
138                 *errstr = PKGCMD_ERR_PACKAGE_INVALID_STR;
139                 break;
140         case PKGCMD_ERR_PACKAGE_LOWER_VERSION:
141                 *errstr = PKGCMD_ERR_PACKAGE_LOWER_VERSION_STR;
142                 break;
143         case PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND:
144                 *errstr = PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND_STR;
145                 break;
146         case PKGCMD_ERR_MANIFEST_INVALID:
147                 *errstr = PKGCMD_ERR_MANIFEST_INVALID_STR;
148                 break;
149         case PKGCMD_ERR_CONFIG_NOT_FOUND:
150                 *errstr = PKGCMD_ERR_CONFIG_NOT_FOUND_STR;
151                 break;
152         case PKGCMD_ERR_CONFIG_INVALID:
153                 *errstr = PKGCMD_ERR_CONFIG_INVALID_STR;
154                 break;
155         case PKGCMD_ERR_SIGNATURE_NOT_FOUND:
156                 *errstr = PKGCMD_ERR_SIGNATURE_NOT_FOUND_STR;
157                 break;
158         case PKGCMD_ERR_SIGNATURE_INVALID:
159                 *errstr = PKGCMD_ERR_SIGNATURE_INVALID_STR;
160                 break;
161         case PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED:
162                 *errstr = PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED_STR;
163                 break;
164         case PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND:
165                 *errstr = PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND_STR;
166                 break;
167         case PKGCMD_ERR_CERTIFICATE_INVALID:
168                 *errstr = PKGCMD_ERR_CERTIFICATE_INVALID_STR;
169                 break;
170         case PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
171                 *errstr = PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED_STR;
172                 break;
173         case PKGCMD_ERR_CERTIFICATE_EXPIRED:
174                 *errstr = PKGCMD_ERR_CERTIFICATE_EXPIRED_STR;
175                 break;
176         case PKGCMD_ERR_INVALID_PRIVILEGE:
177                 *errstr = PKGCMD_ERR_INVALID_PRIVILEGE_STR;
178                 break;
179         case PKGCMD_ERR_MENU_ICON_NOT_FOUND:
180                 *errstr = PKGCMD_ERR_MENU_ICON_NOT_FOUND_STR;
181                 break;
182         case PKGCMD_ERR_FATAL_ERROR:
183                 *errstr = PKGCMD_ERR_FATAL_ERROR_STR;
184                 break;
185         case PKGCMD_ERR_OUT_OF_STORAGE:
186                 *errstr = PKGCMD_ERR_OUT_OF_STORAGE_STR;
187                 break;
188         case PKGCMD_ERR_OUT_OF_MEMORY:
189                 *errstr = PKGCMD_ERR_OUT_OF_MEMORY_STR;
190                 break;
191         case PKGCMD_ERR_ARGUMENT_INVALID:
192                 *errstr = PKGCMD_ERR_ARGUMENT_INVALID_STR;
193                 break;
194         default:
195                 *errstr = PKGCMD_ERR_UNKNOWN_STR;
196                 break;
197         }
198 }
199
200 static void __add_op_cbinfo(pkgmgr_client_t * pc, int request_id,
201                             const char *req_key, pkgmgr_handler event_cb, void *new_event_cb,
202                             void *data)
203 {
204         req_cb_info *cb_info;
205         req_cb_info *current;
206         req_cb_info *prev;
207
208         cb_info = (req_cb_info *) calloc(1, sizeof(req_cb_info));
209         if (cb_info == NULL) {
210                 DBG("calloc failed");
211                 return;
212         }
213         cb_info->request_id = request_id;
214         cb_info->req_key = strdup(req_key);
215         cb_info->event_cb = event_cb;
216         cb_info->data = data;
217         cb_info->next = NULL;
218         pc->new_event_cb = new_event_cb;
219
220         if (pc->info.request.rhead == NULL)
221                 pc->info.request.rhead = cb_info;
222         else {
223                 current = prev = pc->info.request.rhead;
224                 while (current) {
225                         prev = current;
226                         current = current->next;
227                 }
228
229                 prev->next = cb_info;
230         }
231 }
232
233 static req_cb_info *__find_op_cbinfo(pkgmgr_client_t *pc, const char *req_key)
234 {
235         req_cb_info *tmp;
236
237         tmp = pc->info.request.rhead;
238
239         if (tmp == NULL) {
240                 ERR("tmp is NULL");
241                 return NULL;
242         }
243
244         DBG("tmp->req_key %s, req_key %s", tmp->req_key, req_key);
245
246         while (tmp) {
247                 if (strncmp(tmp->req_key, req_key, strlen(tmp->req_key)) == 0)
248                         return tmp;
249                 tmp = tmp->next;
250         }
251         return NULL;
252 }
253
254 static void __add_stat_cbinfo(pkgmgr_client_t *pc, int request_id,
255                               pkgmgr_handler event_cb, void *data)
256 {
257         listen_cb_info *cb_info;
258         listen_cb_info *current;
259         listen_cb_info *prev;
260
261         cb_info = (listen_cb_info *) calloc(1, sizeof(listen_cb_info));
262         if (cb_info == NULL) {
263                 DBG("calloc failed");
264                 return;
265         }
266         cb_info->request_id = request_id;
267         cb_info->event_cb = event_cb;
268         cb_info->data = data;
269         cb_info->next = NULL;
270
271         /* TODO - check the order of callback - FIFO or LIFO => Should be changed to LIFO */
272         if (pc->info.listening.lhead == NULL)
273                 pc->info.listening.lhead = cb_info;
274         else {
275                 current = prev = pc->info.listening.lhead;
276                 while (current) {
277                         prev = current;
278                         current = current->next;
279                 }
280
281                 prev->next = cb_info;
282         }
283 }
284
285 static void __operation_callback(void *cb_data, uid_t target_uid,
286                                  const char *req_id, const char *pkg_type,
287                                  const char *pkgid, const char *key,
288                                  const char *val)
289 {
290         pkgmgr_client_t *pc;
291         req_cb_info *cb_info;
292
293         pc = (pkgmgr_client_t *) cb_data;
294
295         /* find callback info */
296         cb_info = __find_op_cbinfo(pc, req_id);
297         if (cb_info == NULL) {
298                 ERR("cannot fint cb_info for req_id:%s", req_id);
299                 return;
300         }
301
302         /* call callback */
303         if (cb_info->event_cb) {
304                 if (pc->new_event_cb)
305                         cb_info->event_cb(target_uid, cb_info->request_id,
306                                         pkg_type, pkgid, key, val, pc,
307                                         cb_info->data);
308                 else
309                         cb_info->event_cb(target_uid, cb_info->request_id,
310                                         pkg_type, pkgid, key, val, NULL,
311                                         cb_info->data);
312         }
313
314         return;
315 }
316
317 static void __status_callback(void *cb_data, uid_t target_uid,
318                               const char *req_id, const char *pkg_type,
319                               const char *pkgid,  const char *key,
320                               const char *val)
321 {
322         pkgmgr_client_t *pc;
323         listen_cb_info *tmp;
324
325         pc = (pkgmgr_client_t *) cb_data;
326
327         tmp = pc->info.listening.lhead;
328         while (tmp) {
329                 if (tmp->event_cb(target_uid, tmp->request_id, pkg_type, pkgid,
330                                   key, val, NULL, tmp->data) != 0)
331                         break;
332                 tmp = tmp->next;
333         }
334
335         return;
336 }
337
338 static inline int __read_proc(const char *path, char *buf, int size)
339 {
340         int fd = 0;
341         int ret = 0;
342
343         if (buf == NULL || path == NULL)
344                 return -1;
345
346         fd = open(path, O_RDONLY);
347         if (fd < 0)
348                 return -1;
349
350         ret = read(fd, buf, size - 1);
351         if (ret <= 0) {
352                 close(fd);
353                 return -1;
354         } else
355                 buf[ret] = 0;
356
357         close(fd);
358
359         return ret;
360 }
361
362 char *__proc_get_cmdline_bypid(int pid)
363 {
364         char buf[PKG_STRING_LEN_MAX] = {'\0', };
365         int ret = 0;
366
367         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
368         ret = __read_proc(buf, buf, sizeof(buf));
369         if (ret <= 0)
370                 return NULL;
371
372         /* support app launched by shell script*/
373         if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
374                 return strdup(&buf[BINSH_SIZE + 1]);
375         else
376                 return strdup(buf);
377 }
378
379 static inline int __pkgmgr_read_proc(const char *path, char *buf, int size)
380 {
381         int fd;
382         int ret;
383
384         if (buf == NULL || path == NULL)
385                 return -1;
386
387         fd = open(path, O_RDONLY);
388         if (fd < 0)
389                 return -1;
390
391         ret = read(fd, buf, size - 1);
392         if (ret <= 0) {
393                 close(fd);
394                 return -1;
395         } else
396                 buf[ret] = 0;
397
398         close(fd);
399
400         return ret;
401 }
402
403 static inline int __pkgmgr_find_pid_by_cmdline(const char *dname,
404                                       const char *cmdline, const char *apppath)
405 {
406         int pid = 0;
407
408         if (strncmp(cmdline, apppath, PKG_STRING_LEN_MAX-1) == 0) {
409                 pid = atoi(dname);
410                 if (pid != getpgid(pid))
411                         pid = 0;
412         }
413
414         return pid;
415 }
416
417 static int __sync_process(const char *req_key)
418 {
419         int ret;
420         char info_file[PKG_STRING_LEN_MAX] = {'\0', };
421         int result = -1;
422         int check_cnt = 0;
423         FILE *fp;
424         char buf[PKG_STRING_LEN_MAX] = {0, };
425
426         snprintf(info_file, PKG_STRING_LEN_MAX, "%s/%s", PKG_SIZE_INFO_PATH, req_key);
427         while(1)
428         {
429                 check_cnt++;
430
431                 if (access(info_file, F_OK) == 0) {
432                         fp = fopen(info_file, "r");
433                         if (fp == NULL) {
434                                 DBG("file is not generated yet.... wait\n");
435                                 usleep(100 * 1000);     /* 100ms sleep*/
436                                 continue;
437                         }
438
439                         if (fgets(buf, PKG_STRING_LEN_MAX, fp) == NULL) {
440                                 ERR("failed to read info file");
441                                 fclose(fp);
442                                 break;
443                         }
444                         fclose(fp);
445
446                         DBG("info_file file is generated, result = %s. \n", buf);
447                         result = atoi(buf);
448                         break;
449                 }
450
451                 DBG("file is not generated yet.... wait\n");
452                 usleep(100 * 1000);     /* 100ms sleep*/
453
454                 if (check_cnt > 6000) { /* 60s * 10 time over*/
455                         ERR("wait time over!!\n");
456                         break;
457                 }
458         }
459
460         ret = remove(info_file);
461         if (ret < 0)
462                 ERR("file is can not remove[%s, %d]\n", info_file, ret);
463
464         return result;
465 }
466
467 static int __csc_process(const char *csc_path, char *result_path)
468 {
469         int ret = 0;
470         int cnt = 0;
471         int count = 0;
472         int csc_fail = 0;
473         int fd = 0;
474         char *pkgtype = NULL;
475         char *des = NULL;
476         char buf[PKG_STRING_LEN_MAX] = {0,};
477         char type_buf[1024] = { 0 };
478         char des_buf[1024] = { 0 };
479         dictionary *csc = NULL;
480         FILE* file = NULL;
481
482         csc = iniparser_load(csc_path);
483         retvm_if(csc == NULL, PKGMGR_R_EINVAL, "cannot open parse file [%s]", csc_path);
484
485         file = fopen(result_path, "w");
486         tryvm_if(file == NULL, ret = PKGMGR_R_EINVAL, "cannot open result file [%s]", result_path);
487
488         count = iniparser_getint(csc, "csc packages:count", -1);
489         tryvm_if(count == 0, ret = PKGMGR_R_ERROR, "csc [%s] dont have packages", csc_path);
490
491         snprintf(buf, PKG_STRING_LEN_MAX, "[result]\n");
492         fwrite(buf, 1, strlen(buf), file);
493         snprintf(buf, PKG_STRING_LEN_MAX, "count = %d\n", count);
494         fwrite(buf, 1, strlen(buf), file);
495
496         for(cnt = 1 ; cnt <= count ; cnt++)
497         {
498                 snprintf(type_buf, PKG_STRING_LEN_MAX - 1, "csc packages:type_%03d", cnt);
499                 snprintf(des_buf, PKG_STRING_LEN_MAX - 1, "csc packages:description_%03d", cnt);
500
501                 pkgtype = iniparser_getstring(csc, type_buf, NULL);
502                 des = iniparser_getstring(csc, des_buf, NULL);
503                 ret = 0;
504
505                 if (pkgtype == NULL) {
506                         csc_fail++;
507                         snprintf(buf, PKG_STRING_LEN_MAX, "%s = Fail to get pkgtype\n", type_buf);
508                         fwrite(buf, 1, strlen(buf), file);
509                         continue;
510                 } else if (des == NULL) {
511                         csc_fail++;
512                         snprintf(buf, PKG_STRING_LEN_MAX, "%s = Fail to get description\n", des_buf);
513                         fwrite(buf, 1, strlen(buf), file);
514                         continue;
515                 }
516
517                 snprintf(buf, PKG_STRING_LEN_MAX, "type_%03d = %s\n", cnt, pkgtype);
518                 fwrite(buf, 1, strlen(buf), file);
519                 snprintf(buf, PKG_STRING_LEN_MAX, "description_%03d = %s\n", cnt, des);
520                 fwrite(buf, 1, strlen(buf), file);
521
522                 if (strcmp(pkgtype, "tpk") == 0) {
523                         const char *ospinstaller_argv[] = { "/usr/bin/osp-installer", "-c", des, NULL };
524                         ret = __xsystem(ospinstaller_argv);
525                 } else if (strcmp(pkgtype, "wgt")== 0) {
526                         const char *wrtinstaller_argv[] = { "/usr/bin/wrt-installer", "-c", des, NULL };
527                         ret = __xsystem(wrtinstaller_argv);
528                 } else {
529                         csc_fail++;
530                         ret = -1;
531                 }
532
533                 if (ret != 0) {
534                         char *errstr = NULL;
535                         __error_to_string(ret, &errstr);
536                         snprintf(buf, PKG_STRING_LEN_MAX, "result_%03d = fail[%s]\n", cnt, errstr);
537                 }
538                 else
539                         snprintf(buf, PKG_STRING_LEN_MAX, "result_%03d = success\n", cnt);
540
541                 fwrite(buf, 1, strlen(buf), file);
542         }
543
544 catch:
545         iniparser_freedict(csc);
546         if (file != NULL) {
547                 fflush(file);
548                 fd = fileno(file);
549                 fsync(fd);
550                 fclose(file);
551         }
552         return ret;
553 }
554
555 static int __get_size_process(pkgmgr_client * pc, const char *pkgid, uid_t uid,
556                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
557                 void *data)
558 {
559         GVariant *result;
560         int ret = PKGMGR_R_ECOMM;
561         char *req_key = NULL;
562         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
563
564         if (pc == NULL || pkgid == NULL) {
565                 ERR("invalid parameter");
566                 return PKGMGR_R_EINVAL;
567         }
568
569         if (mpc->ctype != PC_REQUEST) {
570                 ERR("mpc->ctype is not PC_REQUEST");
571                 return PKGMGR_R_EINVAL;
572         }
573         result = comm_client_request(mpc->info.request.cc, "getsize",
574                         g_variant_new("(si)", pkgid, get_type));
575         if (result == NULL)
576                 return PKGMGR_R_ECOMM;
577
578         g_variant_get(result, "(i&s)", &ret, &req_key);
579         if (req_key == NULL) {
580                 g_variant_unref(result);
581                 return PKGMGR_R_ECOMM;
582         }
583         if (ret != PKGMGR_R_OK) {
584                 g_variant_unref(result);
585                 return ret;
586         }
587
588         ret = __sync_process(req_key);
589         if (ret < 0)
590                 ERR("get size failed, ret=%d\n", ret);
591
592         g_variant_unref(result);
593
594         return ret;
595 }
596
597 static int __move_pkg_process(pkgmgr_client *pc, const char *pkgid,
598                 const char *pkg_type, uid_t uid, pkgmgr_move_type move_type,
599                 pkgmgr_handler event_cb, void *data)
600 {
601         int ret;
602
603         ret = pkgmgr_client_usr_move(pc, pkg_type, pkgid, move_type, 0, uid);
604         if (ret < 0) {
605                 ERR("move request failed");
606                 return ret;
607         }
608
609         /* FIXME */
610         ret = __sync_process(pkgid);
611         if (ret != 0)
612                 ERR("move pkg failed, ret=%d\n", ret);
613
614         return ret;
615 }
616
617 static int __check_app_process(pkgmgr_request_service_type service_type,
618                 pkgmgr_client *pc, const char *pkgid, uid_t uid, void *data)
619 {
620         GVariant *result = NULL;
621         int ret = PKGMGR_R_ECOMM;
622         pkgmgrinfo_pkginfo_h handle;
623         int pid = -1;
624         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
625
626         retvm_if(mpc->ctype != PC_REQUEST, PKGMGR_R_EINVAL, "mpc->ctype is not PC_REQUEST\n");
627
628         if (uid != GLOBAL_USER)
629                 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
630         else
631                 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
632         retvm_if(ret < 0, PKGMGR_R_ERROR, "pkgmgrinfo_pkginfo_get_pkginfo failed");
633
634         if (service_type == PM_REQUEST_KILL_APP)
635                 result = comm_client_request(mpc->info.request.cc, "kill",
636                                 g_variant_new("(s)", pkgid));
637         else if (service_type == PM_REQUEST_CHECK_APP)
638                 result = comm_client_request(mpc->info.request.cc, "check",
639                                 g_variant_new("(s)", pkgid));
640
641         if (result == NULL)
642                 return PKGMGR_R_ECOMM;
643         g_variant_get(result, "(i)", &ret);
644         g_variant_unref(result);
645         if (ret != PKGMGR_R_OK) {
646                 ERR("request failed, ret=%d", ret);
647                 return ret;
648         }
649
650         /* FIXME */
651         pid  = __sync_process(pkgid);
652         *(int *)data = pid;
653
654         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
655
656         return ret;
657
658 }
659
660 static int __request_size_info(pkgmgr_client *pc, uid_t uid)
661 {
662         GVariant *result;
663         int ret = PKGMGR_R_ECOMM;
664         char *req_key = NULL;
665         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
666
667         if (pc == NULL) {
668                 ERR("invalid parameter");
669                 return PKGMGR_R_EINVAL;
670         }
671
672         if (mpc->ctype != PC_REQUEST) {
673                 ERR("mpc->ctype is not PC_REQUEST");
674                 return PKGMGR_R_EINVAL;
675         }
676
677         result = comm_client_request(mpc->info.request.cc, "getsize",
678                         g_variant_new("(si)", "size_info", PM_GET_SIZE_INFO));
679         if (result == NULL)
680                 return PKGMGR_R_ECOMM;
681
682         g_variant_get(result, "(i&s)", &ret, &req_key);
683         if (req_key == NULL) {
684                 g_variant_unref(result);
685                 return PKGMGR_R_ECOMM;
686         }
687
688         g_variant_unref(result);
689
690         return ret;
691 }
692
693 static int __change_op_cb_for_getsize(pkgmgr_client *pc)
694 {
695         int ret = -1;
696
697         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
698         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
699
700         /*  free listening head */
701         req_cb_info *tmp = NULL;
702         req_cb_info *prev = NULL;
703         for (tmp = mpc->info.request.rhead; tmp;) {
704                 prev = tmp;
705                 tmp = tmp->next;
706                 free(prev);
707         }
708
709         /* free dbus connection */
710         ret = comm_client_free(mpc->info.request.cc);
711         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
712
713         /* Manage pc for seperated event */
714         mpc->ctype = PC_REQUEST;
715         mpc->status_type = PKGMGR_CLIENT_STATUS_GET_SIZE;
716
717
718         mpc->info.request.cc = comm_client_new();
719         retvm_if(mpc->info.request.cc == NULL, PKGMGR_R_ERROR, "client creation failed");
720
721         ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_GET_SIZE, mpc->info.request.cc, __operation_callback, pc);
722         retvm_if(ret < 0, PKGMGR_R_ERROR, "set_status_callback() failed - %d", ret);
723
724         return PKGMGR_R_OK;
725 }
726
727 static int __get_pkg_size_info_cb(uid_t target_uid, int req_id, const char *req_type,
728                 const char *pkgid, const char *key,
729                 const char *value, const void *pc, void *user_data)
730 {
731         int ret = 0;
732         DBG("target_uid: %u, reqid: %d, req type: %s, pkgid: %s, unused key: %s, size info: %s",
733                         target_uid, req_id, req_type, pkgid, key, value);
734
735         pkg_size_info_t *size_info = (pkg_size_info_t *)malloc(sizeof(pkg_size_info_t));
736         retvm_if(size_info == NULL, -1, "The memory is insufficient.");
737
738         char *save_ptr = NULL;
739         char *token = strtok_r((char*)value, ":", &save_ptr);
740         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
741         size_info->data_size = atoll(token);
742         token = strtok_r(NULL, ":", &save_ptr);
743         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
744         size_info->cache_size = atoll(token);
745         token = strtok_r(NULL, ":", &save_ptr);
746         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
747         size_info->app_size = atoll(token);
748         token = strtok_r(NULL, ":", &save_ptr);
749         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
750         size_info->ext_data_size = atoll(token);
751         token = strtok_r(NULL, ":", &save_ptr);
752         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
753         size_info->ext_cache_size = atoll(token);
754         token = strtok_r(NULL, ":", &save_ptr);
755         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
756         size_info->ext_app_size = atoll(token);
757
758         DBG("data: %lld, cache: %lld, app: %lld, ext_data: %lld, ext_cache: %lld, ext_app: %lld",
759                         size_info->data_size, size_info->cache_size, size_info->app_size,
760                         size_info->ext_data_size, size_info->ext_cache_size, size_info->ext_app_size);
761
762         pkgmgr_client_t *pmc = (pkgmgr_client_t *)pc;
763         tryvm_if(pmc == NULL, ret = -1, "pkgmgr_client instance is null.");
764
765         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
766         {       // total package size info
767                 pkgmgr_total_pkg_size_info_receive_cb callback = (pkgmgr_total_pkg_size_info_receive_cb)(pmc->new_event_cb);
768                 callback((pkgmgr_client *)pc, size_info, user_data);
769         }
770         else
771         {
772                 pkgmgr_pkg_size_info_receive_cb callback = (pkgmgr_pkg_size_info_receive_cb)(pmc->new_event_cb);
773                 callback((pkgmgr_client *)pc, pkgid, size_info, user_data);
774         }
775
776 catch:
777
778         if(size_info){
779                 free(size_info);
780                 size_info = NULL;
781         }
782         return ret;
783 }
784
785 API pkgmgr_client *pkgmgr_client_new(client_type ctype)
786 {
787         pkgmgr_client_t *pc = NULL;
788         int ret = -1;
789
790         retvm_if(ctype == PC_BROADCAST, NULL, "broadcast type is not supported");
791         retvm_if(ctype != PC_REQUEST && ctype != PC_LISTENING, NULL, "ctype is not client_type");
792
793         /* Allocate memory for ADT:pkgmgr_client */
794         pc = calloc(1, sizeof(pkgmgr_client_t));
795         retvm_if(pc == NULL, NULL, "No memory");
796
797         /* Manage pc */
798         pc->ctype = ctype;
799         pc->status_type = PKGMGR_CLIENT_STATUS_ALL;
800
801         if (pc->ctype == PC_REQUEST) {
802                 pc->info.request.cc = comm_client_new();
803                 trym_if(pc->info.request.cc == NULL, "client creation failed");
804
805                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_ALL, pc->info.request.cc, __operation_callback, pc);
806                 trym_if(ret < 0L, "comm_client_set_status_callback() failed - %d", ret);
807         } else if (pc->ctype == PC_LISTENING) {
808                 pc->info.listening.cc = comm_client_new();
809                 trym_if(pc->info.listening.cc == NULL, "client creation failed");
810
811                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_ALL, pc->info.listening.cc, __status_callback, pc);
812                 trym_if(ret < 0L, "comm_client_set_status_callback() failed - %d", ret);
813         }
814
815         return (pkgmgr_client *) pc;
816
817  catch:
818         if (pc)
819                 free(pc);
820         return NULL;
821 }
822
823 API int pkgmgr_client_free(pkgmgr_client *pc)
824 {
825         int ret = -1;
826         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
827         retvm_if(mpc == NULL, PKGMGR_R_EINVAL, "Invalid argument");
828
829         if (mpc->ctype == PC_REQUEST) {
830                 req_cb_info *tmp;
831                 req_cb_info *prev;
832                 for (tmp = mpc->info.request.rhead; tmp;) {
833                         prev = tmp;
834                         tmp = tmp->next;
835                         free(prev);
836                 }
837
838                 ret = comm_client_free(mpc->info.request.cc);
839                 tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "comm_client_free() failed");
840         } else if (mpc->ctype == PC_LISTENING) {
841                         listen_cb_info *tmp;
842                         listen_cb_info *prev;
843                         for (tmp = mpc->info.listening.lhead; tmp;) {
844                                 prev = tmp;
845                                 tmp = tmp->next;
846                                 free(prev);
847                         }
848
849                         ret = comm_client_free(mpc->info.listening.cc);
850                         tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "comm_client_free() failed");
851         } else if (mpc->ctype == PC_BROADCAST) {
852                 ret = 0;
853         } else {
854                 ERR("Invalid client type\n");
855                 return PKGMGR_R_EINVAL;
856         }
857
858         free(mpc);
859         mpc = NULL;
860         return PKGMGR_R_OK;
861
862  catch:
863         if (mpc) {
864                 free(mpc);
865                 mpc = NULL;
866         }
867         return PKGMGR_R_ERROR;
868 }
869
870
871 API int pkgmgr_client_usr_install(pkgmgr_client *pc, const char *pkg_type,
872                 const char *descriptor_path, const char *pkg_path,
873                 const char *optional_file, pkgmgr_mode mode,
874                 pkgmgr_handler event_cb, void *data, uid_t uid)
875 {
876         GVariant *result;
877         int ret = PKGMGR_R_ECOMM;
878         char *req_key = NULL;
879         int req_id;
880         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
881
882         if (pc == NULL || pkg_type == NULL || pkg_path == NULL) {
883                 ERR("invalid parameter");
884                 return PKGMGR_R_EINVAL;
885         }
886
887         if (mpc->ctype != PC_REQUEST) {
888                 ERR("mpc->ctype is not PC_REQUEST");
889                 return PKGMGR_R_EINVAL;
890         }
891
892         result = comm_client_request(mpc->info.request.cc, "install",
893                         g_variant_new("(ss)", pkg_type, pkg_path));
894         if (result == NULL)
895                 return PKGMGR_R_ECOMM;
896         g_variant_get(result, "(i&s)", &ret, &req_key);
897         if (req_key == NULL) {
898                 g_variant_unref(result);
899                 return PKGMGR_R_ECOMM;
900         }
901         if (ret != PKGMGR_R_OK) {
902                 g_variant_unref(result);
903                 return ret;
904         }
905
906         req_id = _get_request_id();
907         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
908
909         g_variant_unref(result);
910
911         return req_id;
912 }
913
914 API int pkgmgr_client_install(pkgmgr_client *pc, const char *pkg_type,
915                 const char *descriptor_path, const char *pkg_path,
916                 const char *optional_file, pkgmgr_mode mode,
917                 pkgmgr_handler event_cb, void *data)
918 {
919         return pkgmgr_client_usr_install(pc, pkg_type, descriptor_path,
920                         pkg_path, optional_file, mode, event_cb,data,
921                         GLOBAL_USER);
922 }
923
924 API int pkgmgr_client_reinstall(pkgmgr_client *pc, const char *pkg_type,
925                 const char *pkgid, const char *optional_file, pkgmgr_mode mode,
926                 pkgmgr_handler event_cb, void *data)
927 {
928         return pkgmgr_client_usr_reinstall(pc, pkg_type, pkgid, optional_file,
929                         mode, event_cb, data,GLOBAL_USER);
930 }
931
932 API int pkgmgr_client_usr_reinstall(pkgmgr_client * pc, const char *pkg_type,
933                 const char *pkgid, const char *optional_file, pkgmgr_mode mode,
934                 pkgmgr_handler event_cb, void *data, uid_t uid)
935 {
936         GVariant *result;
937         int ret = PKGMGR_R_ECOMM;
938         char *req_key = NULL;
939         int req_id;
940         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
941
942         if (pc == NULL || pkg_type == NULL || pkgid == NULL) {
943                 ERR("invalid parameter");
944                 return PKGMGR_R_EINVAL;
945         }
946
947         if (mpc->ctype != PC_REQUEST) {
948                 ERR("mpc->ctype is not PC_REQUEST");
949                 return PKGMGR_R_EINVAL;
950         }
951
952         result = comm_client_request(mpc->info.request.cc, "reinstall",
953                         g_variant_new("(ss)", pkg_type, pkgid));
954         if (result == NULL)
955                 return PKGMGR_R_ECOMM;
956         g_variant_get(result, "(i&s)", &ret, &req_key);
957         if (req_key == NULL) {
958                 g_variant_unref(result);
959                 return PKGMGR_R_ECOMM;
960         }
961         if (ret != PKGMGR_R_OK) {
962                 g_variant_unref(result);
963                 return ret;
964         }
965
966         req_id = _get_request_id();
967         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
968
969         g_variant_unref(result);
970
971         return req_id;
972 }
973
974 API int pkgmgr_client_uninstall(pkgmgr_client *pc, const char *pkg_type,
975                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
976                 void *data)
977 {
978         return pkgmgr_client_usr_uninstall(pc, pkg_type,pkgid, mode, event_cb,
979                         data, GLOBAL_USER);
980 }
981
982 API int pkgmgr_client_usr_uninstall(pkgmgr_client *pc, const char *pkg_type,
983                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
984                 void *data, uid_t uid)
985 {
986         GVariant *result;
987         int ret = PKGMGR_R_ECOMM;
988         char *req_key = NULL;
989         int req_id;
990         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
991         char *pkgtype;
992         pkgmgrinfo_pkginfo_h handle;
993
994         if (pc == NULL || pkgid == NULL) {
995                 ERR("invalid parameter");
996                 return PKGMGR_R_EINVAL;
997         }
998
999         if (mpc->ctype != PC_REQUEST) {
1000                 ERR("mpc->ctype is not PC_REQUEST");
1001                 return PKGMGR_R_EINVAL;
1002         }
1003
1004         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
1005         if (ret < 0)
1006                 return PKGMGR_R_ERROR;
1007
1008         ret = pkgmgrinfo_pkginfo_get_type(handle, &pkgtype);
1009         if (ret < 0) {
1010                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1011                 return PKGMGR_R_ERROR;
1012         }
1013
1014         /* TODO: check removable ? */
1015
1016         result = comm_client_request(mpc->info.request.cc, "uninstall",
1017                         g_variant_new("(ss)", pkgtype, pkgid));
1018         if (result == NULL) {
1019                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1020                 return PKGMGR_R_ECOMM;
1021         }
1022         g_variant_get(result, "(i&s)", &ret, &req_key);
1023         if (req_key == NULL) {
1024                 g_variant_unref(result);
1025                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1026                 return PKGMGR_R_ECOMM;
1027         }
1028         if (ret != PKGMGR_R_OK) {
1029                 g_variant_unref(result);
1030                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1031                 return ret;
1032         }
1033
1034         req_id = _get_request_id();
1035         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1036
1037         g_variant_unref(result);
1038         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1039
1040         return req_id;
1041 }
1042
1043 API int pkgmgr_client_move(pkgmgr_client *pc, const char *pkg_type,
1044                 const char *pkgid, pkgmgr_move_type move_type, pkgmgr_mode mode)
1045 {
1046         return pkgmgr_client_usr_move(pc, pkg_type, pkgid, move_type, mode,
1047                         GLOBAL_USER);
1048 }
1049 API int pkgmgr_client_usr_move(pkgmgr_client *pc, const char *pkg_type,
1050                 const char *pkgid, pkgmgr_move_type move_type,
1051                 pkgmgr_mode mode, uid_t uid)
1052 {
1053         GVariant *result;
1054         int ret = PKGMGR_R_ECOMM;
1055         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1056
1057         if (pc == NULL || pkg_type == NULL || pkgid == NULL) {
1058                 ERR("invalid parameter");
1059                 return PKGMGR_R_EINVAL;
1060         }
1061
1062         if ((move_type < PM_MOVE_TO_INTERNAL) || (move_type > PM_MOVE_TO_SDCARD))
1063                 return PKGMGR_R_EINVAL;
1064
1065         if (mpc->ctype != PC_REQUEST) {
1066                 ERR("mpc->ctype is not PC_REQUEST");
1067                 return PKGMGR_R_EINVAL;
1068         }
1069
1070         result = comm_client_request(mpc->info.request.cc, "move",
1071                         g_variant_new("(ss)", pkg_type, pkgid));
1072         if (result == NULL)
1073                 return PKGMGR_R_ECOMM;
1074         g_variant_get(result, "(i)", &ret);
1075         g_variant_unref(result);
1076
1077         return ret;
1078 }
1079
1080 API int pkgmgr_client_usr_activate(pkgmgr_client *pc, const char *pkg_type,
1081                 const char *pkgid, uid_t uid)
1082 {
1083         GVariant *result;
1084         int ret = PKGMGR_R_ECOMM;
1085         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1086
1087         if (pc == NULL || pkgid == NULL) {
1088                 ERR("invalid parameter");
1089                 return PKGMGR_R_EINVAL;
1090         }
1091
1092         result = comm_client_request(mpc->info.request.cc, "enable_pkg",
1093                         g_variant_new("(s)", pkgid));
1094         if (result == NULL)
1095                 return PKGMGR_R_ECOMM;
1096         g_variant_get(result, "(i)", &ret);
1097         g_variant_unref(result);
1098
1099         return ret;
1100 }
1101
1102 API int pkgmgr_client_activate(pkgmgr_client *pc, const char *pkg_type,
1103                 const char *pkgid)
1104 {
1105         return pkgmgr_client_usr_activate(pc, pkg_type, pkgid, GLOBAL_USER);
1106 }
1107
1108 API int pkgmgr_client_usr_deactivate(pkgmgr_client *pc, const char *pkg_type,
1109                                  const char *pkgid, uid_t uid)
1110 {
1111         GVariant *result;
1112         int ret = PKGMGR_R_ECOMM;
1113         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1114
1115         if (pc == NULL || pkgid == NULL) {
1116                 ERR("invalid parameter");
1117                 return PKGMGR_R_EINVAL;
1118         }
1119
1120         result = comm_client_request(mpc->info.request.cc, "disable_pkg",
1121                         g_variant_new("(s)", pkgid));
1122         if (result == NULL)
1123                 return PKGMGR_R_ECOMM;
1124         g_variant_get(result, "(i)", &ret);
1125         g_variant_unref(result);
1126
1127         return ret;
1128 }
1129
1130 API int pkgmgr_client_deactivate(pkgmgr_client *pc, const char *pkg_type,
1131                                  const char *pkgid)
1132 {
1133         return pkgmgr_client_usr_deactivate(pc, pkg_type, pkgid, GLOBAL_USER);
1134 }
1135
1136 API int pkgmgr_client_usr_activate_app(pkgmgr_client *pc, const char *appid,
1137                 uid_t uid)
1138 {
1139         GVariant *result;
1140         int ret = PKGMGR_R_ECOMM;
1141         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1142
1143         if (pc == NULL || appid == NULL) {
1144                 ERR("invalid parameter");
1145                 return PKGMGR_R_EINVAL;
1146         }
1147
1148         result = comm_client_request(mpc->info.request.cc, "enable_app",
1149                         g_variant_new("(s)", appid));
1150         if (result == NULL)
1151                 return PKGMGR_R_ECOMM;
1152         g_variant_get(result, "(i)", &ret);
1153         g_variant_unref(result);
1154
1155         return ret;
1156 }
1157
1158 API int pkgmgr_client_activate_app(pkgmgr_client * pc, const char *appid)
1159 {
1160         return pkgmgr_client_usr_activate_app(pc, appid, GLOBAL_USER);
1161 }
1162
1163 /* TODO: deprecate? */
1164 API int pkgmgr_client_usr_activate_appv(pkgmgr_client *pc, const char *appid,
1165                 char *const argv[], uid_t uid)
1166 {
1167         return pkgmgr_client_usr_activate_app(pc, appid, uid);
1168 }
1169
1170 API int pkgmgr_client_activate_appv(pkgmgr_client *pc, const char *appid,
1171                 char *const argv[])
1172 {
1173         return pkgmgr_client_usr_activate_app(pc, appid, GLOBAL_USER);
1174 }
1175
1176 API int pkgmgr_client_usr_deactivate_app(pkgmgr_client *pc, const char *appid,
1177                 uid_t uid)
1178 {
1179         GVariant *result;
1180         int ret = PKGMGR_R_ECOMM;
1181         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1182
1183         if (pc == NULL || appid == NULL) {
1184                 ERR("invalid parameter");
1185                 return PKGMGR_R_EINVAL;
1186         }
1187
1188         result = comm_client_request(mpc->info.request.cc, "disable_app",
1189                         g_variant_new("(s)", appid));
1190         if (result == NULL)
1191                 return PKGMGR_R_ECOMM;
1192         g_variant_get(result, "(i)", &ret);
1193         g_variant_unref(result);
1194
1195         return ret;
1196 }
1197
1198 API int pkgmgr_client_deactivate_app(pkgmgr_client *pc, const char *appid)
1199 {
1200         return pkgmgr_client_usr_deactivate_app(pc, appid, GLOBAL_USER);
1201 }
1202
1203 API int pkgmgr_client_usr_clear_user_data(pkgmgr_client *pc,
1204                 const char *pkg_type, const char *appid, pkgmgr_mode mode,
1205                 uid_t uid)
1206 {
1207         GVariant *result;
1208         int ret = PKGMGR_R_ECOMM;
1209         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1210
1211         if (pc == NULL || pkg_type == NULL || appid == NULL) {
1212                 ERR("invalid parameter");
1213                 return PKGMGR_R_EINVAL;
1214         }
1215
1216         if (mpc->ctype != PC_REQUEST) {
1217                 ERR("mpc->ctype is not PC_REQUEST");
1218                 return PKGMGR_R_EINVAL;
1219         }
1220
1221         result = comm_client_request(mpc->info.request.cc, "cleardata",
1222                         g_variant_new("(ss)", pkg_type, appid));
1223         if (result == NULL)
1224                 return PKGMGR_R_ECOMM;
1225
1226         g_variant_get(result, "(i)", &ret);
1227         g_variant_unref(result);
1228
1229         return ret;
1230 }
1231
1232 API int pkgmgr_client_clear_user_data(pkgmgr_client *pc, const char *pkg_type,
1233                 const char *appid, pkgmgr_mode mode)
1234 {
1235         return pkgmgr_client_usr_clear_user_data(pc, pkg_type, appid, mode,
1236                         GLOBAL_USER);
1237 }
1238
1239 API int pkgmgr_client_set_status_type(pkgmgr_client *pc, int status_type)
1240 {
1241         int ret = -1;
1242
1243         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1244         retvm_if(status_type == PKGMGR_CLIENT_STATUS_ALL, PKGMGR_R_OK, "status_type is PKGMGR_CLIENT_STATUS_ALL");
1245         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1246
1247         /*  free listening head */
1248         listen_cb_info *tmp = NULL;
1249         listen_cb_info *prev = NULL;
1250         for (tmp = mpc->info.listening.lhead; tmp;) {
1251                 prev = tmp;
1252                 tmp = tmp->next;
1253                 free(prev);
1254         }
1255
1256         /* free dbus connection */
1257         ret = comm_client_free(mpc->info.listening.cc);
1258         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
1259
1260         /* Manage pc for seperated event */
1261         mpc->ctype = PC_LISTENING;
1262         mpc->status_type = status_type;
1263
1264         mpc->info.listening.cc = comm_client_new();
1265         retvm_if(mpc->info.listening.cc == NULL, PKGMGR_R_EINVAL, "client creation failed");
1266
1267         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_INSTALL) == PKGMGR_CLIENT_STATUS_INSTALL) {
1268                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_INSTALL, mpc->info.listening.cc, __status_callback, pc);
1269                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "PKGMGR_CLIENT_STATUS_INSTALL failed - %d", ret);
1270         }
1271
1272         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_UNINSTALL) == PKGMGR_CLIENT_STATUS_UNINSTALL) {
1273                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_UNINSTALL, mpc->info.listening.cc, __status_callback, pc);
1274                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_UNINSTALL failed - %d", ret);
1275         }
1276
1277         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_MOVE) == PKGMGR_CLIENT_STATUS_MOVE) {
1278                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_MOVE, mpc->info.listening.cc, __status_callback, pc);
1279                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_MOVE failed - %d", ret);
1280         }
1281
1282         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS) == PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS) {
1283                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_INSTALL_PROGRESS, mpc->info.listening.cc, __status_callback, pc);
1284                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_INSTALL_PROGRESS failed - %d", ret);
1285         }
1286
1287    if ((mpc->status_type & PKGMGR_CLIENT_STATUS_UPGRADE) == PKGMGR_CLIENT_STATUS_UPGRADE) {
1288            ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_UPGRADE, mpc->info.listening.cc, __status_callback, pc);
1289            retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_UPGRADE failed - %d", ret);
1290    }
1291
1292    return PKGMGR_R_OK;
1293 }
1294
1295 API int pkgmgr_client_listen_status(pkgmgr_client *pc, pkgmgr_handler event_cb,
1296                                     void *data)
1297 {
1298         int req_id;
1299         /* Check for NULL value of pc */
1300         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1301         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1302
1303         /* 0. check input */
1304         retvm_if(mpc->ctype != PC_LISTENING, PKGMGR_R_EINVAL, "ctype is not PC_LISTENING");
1305         retvm_if(event_cb == NULL, PKGMGR_R_EINVAL, "event_cb is NULL");
1306
1307         /* 1. get id */
1308         req_id = _get_request_id();
1309
1310         /* 2. add callback info to pkgmgr_client */
1311         __add_stat_cbinfo(mpc, req_id, event_cb, data);
1312         return req_id;
1313 }
1314
1315 API int pkgmgr_client_broadcast_status(pkgmgr_client *pc, const char *pkg_type,
1316                                        const char *pkgid, const char *key,
1317                                        const char *val)
1318 {
1319         /* client cannot broadcast signal */
1320         return PKGMGR_R_OK;
1321 }
1322
1323 API int pkgmgr_client_request_service(pkgmgr_request_service_type service_type, int service_mode,
1324                                   pkgmgr_client * pc, const char *pkg_type, const char *pkgid,
1325                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1326 {
1327         return pkgmgr_client_usr_request_service(service_type, service_mode, pc, pkg_type, pkgid, GLOBAL_USER, custom_info, event_cb, data);
1328 }
1329
1330 API int pkgmgr_client_usr_request_service(pkgmgr_request_service_type service_type, int service_mode,
1331                                   pkgmgr_client * pc, const char *pkg_type, const char *pkgid, uid_t uid,
1332                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1333 {
1334         int ret =0;
1335
1336         /* Check for NULL value of service type */
1337         retvm_if(service_type > PM_REQUEST_MAX, PKGMGR_R_EINVAL, "service type is not defined\n");
1338         retvm_if(service_type < 0, PKGMGR_R_EINVAL, "service type is error\n");
1339
1340         switch (service_type) {
1341         case PM_REQUEST_CSC:
1342                 tryvm_if(custom_info == NULL, ret = PKGMGR_R_EINVAL, "custom_info is NULL\n");
1343                 tryvm_if(strlen(custom_info) >= PKG_STRING_LEN_MAX, ret = PKGMGR_R_EINVAL, "optional_file over PKG_STRING_LEN_MAX");
1344                 tryvm_if(data == NULL, ret = PKGMGR_R_EINVAL, "data is NULL\n");
1345
1346                 ret = __csc_process(custom_info, (char *)data);
1347                 if (ret < 0)
1348                         ERR("__csc_process fail \n");
1349                 else
1350                         ret = PKGMGR_R_OK;
1351
1352                 break;
1353
1354         case PM_REQUEST_MOVE:
1355                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1356                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1357                 tryvm_if((service_mode < PM_MOVE_TO_INTERNAL) || (service_mode > PM_MOVE_TO_SDCARD), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1358
1359                 ret = __move_pkg_process(pc, pkgid, pkg_type, uid, (pkgmgr_move_type)service_mode, event_cb, data);
1360                 break;
1361
1362         case PM_REQUEST_GET_SIZE:
1363                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1364                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1365                 tryvm_if((service_mode < PM_GET_TOTAL_SIZE) || (service_mode >= PM_GET_MAX), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1366
1367                 ret = __get_size_process(pc, pkgid, uid, (pkgmgr_getsize_type)service_mode, event_cb, data);
1368                 break;
1369
1370         case PM_REQUEST_KILL_APP:
1371         case PM_REQUEST_CHECK_APP:
1372                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1373                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1374
1375                 ret = __check_app_process(service_type, pc, pkgid, uid, data);
1376                 if (ret < 0)
1377                         ERR("__check_app_process fail \n");
1378                 else
1379                         ret = PKGMGR_R_OK;
1380
1381                 break;
1382
1383         default:
1384                 ERR("Wrong Request\n");
1385                 ret = -1;
1386                 break;
1387         }
1388
1389 catch:
1390
1391         return ret;
1392 }
1393
1394
1395 API int pkgmgr_client_usr_request_size_info(uid_t uid)
1396 {
1397         int ret = 0;
1398         pkgmgr_client *pc = NULL;
1399
1400         pc = pkgmgr_client_new(PC_REQUEST);
1401         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "request pc is null\n");
1402
1403         ret = __request_size_info(pc, uid);
1404         if (ret < 0) {
1405                 ERR("__request_size_info fail \n");
1406         }
1407
1408         pkgmgr_client_free(pc);
1409         return ret;
1410 }
1411
1412 API int pkgmgr_client_request_size_info(void) // get all package size (data, total)
1413 {
1414         return pkgmgr_client_usr_request_size_info(GLOBAL_USER);
1415 }
1416
1417 API int pkgmgr_client_usr_clear_cache_dir(const char *pkgid, uid_t uid)
1418 {
1419         GVariant *result;
1420         int ret = PKGMGR_R_ECOMM;
1421         pkgmgr_client_t *pc;
1422
1423         if (pkgid == NULL) {
1424                 ERR("invalid parameter");
1425                 return PKGMGR_R_EINVAL;
1426         }
1427
1428         pc = pkgmgr_client_new(PC_REQUEST);
1429         if (pc == NULL) {
1430                 ERR("out of memory");
1431                 return PKGMGR_R_ESYSTEM;
1432         }
1433
1434         result = comm_client_request(pc->info.request.cc, "clearcache",
1435                         g_variant_new("(s)", pkgid));
1436         if (result == NULL)
1437                 return PKGMGR_R_ECOMM;
1438         g_variant_get(result, "(i)", &ret);
1439         g_variant_unref(result);
1440
1441         return ret;
1442 }
1443
1444 API int pkgmgr_client_clear_cache_dir(const char *pkgid)
1445 {
1446         return pkgmgr_client_usr_clear_cache_dir(pkgid, GLOBAL_USER);
1447 }
1448
1449 API int pkgmgr_client_clear_usr_all_cache_dir(uid_t uid)
1450 {
1451         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, uid);
1452 }
1453
1454 API int pkgmgr_client_clear_all_cache_dir(void)
1455 {
1456         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, GLOBAL_USER);
1457 }
1458
1459 API int pkgmgr_client_get_size(pkgmgr_client * pc, const char *pkgid,
1460                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1461                 void *data)
1462 {
1463         return pkgmgr_client_usr_get_size(pc, pkgid, get_type, event_cb, data,
1464                         GLOBAL_USER);
1465 }
1466
1467 API int pkgmgr_client_usr_get_size(pkgmgr_client * pc, const char *pkgid,
1468                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1469                 void *data, uid_t uid)
1470 {
1471         GVariant *result;
1472         int ret = PKGMGR_R_ECOMM;
1473         char *req_key = NULL;
1474         int req_id;
1475         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1476
1477         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1478                 ERR("invalid parameter");
1479                 return PKGMGR_R_EINVAL;
1480         }
1481
1482         if (mpc->ctype != PC_REQUEST) {
1483                 ERR("mpc->ctype is not PC_REQUEST");
1484                 return PKGMGR_R_EINVAL;
1485         }
1486
1487         /* FIXME */
1488         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1489                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1490         else
1491                 get_type = PM_GET_PKG_SIZE_INFO;
1492         result = comm_client_request(mpc->info.request.cc, "getsize",
1493                         g_variant_new("(si)", pkgid, get_type));
1494         if (result == NULL)
1495                 return PKGMGR_R_ECOMM;
1496
1497         g_variant_get(result, "(i&s)", &ret, &req_key);
1498         if (req_key == NULL) {
1499                 g_variant_unref(result);
1500                 return PKGMGR_R_ECOMM;
1501         }
1502         if (ret != PKGMGR_R_OK) {
1503                 g_variant_unref(result);
1504                 return ret;
1505         }
1506
1507         req_id = _get_request_id();
1508         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1509
1510         g_variant_unref(result);
1511
1512         return PKGMGR_R_OK;
1513 }
1514
1515 API int pkgmgr_client_usr_get_package_size_info(pkgmgr_client *pc,
1516                 const char *pkgid, pkgmgr_pkg_size_info_receive_cb event_cb,
1517                 void *user_data, uid_t uid)
1518 {
1519         GVariant *result;
1520         int ret = PKGMGR_R_ECOMM;
1521         char *req_key = NULL;
1522         int req_id;
1523         int get_type;
1524         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1525
1526         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1527                 ERR("invalid parameter");
1528                 return PKGMGR_R_EINVAL;
1529         }
1530
1531         if (mpc->ctype != PC_REQUEST) {
1532                 ERR("mpc->ctype is not PC_REQUEST");
1533                 return PKGMGR_R_EINVAL;
1534         }
1535
1536         /* FIXME */
1537         if (__change_op_cb_for_getsize(mpc) < 0) {
1538                 ERR("__change_op_cb_for_getsize failed");
1539                 return PKGMGR_R_ESYSTEM;
1540         }
1541
1542         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1543                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1544         else
1545                 get_type = PM_GET_PKG_SIZE_INFO;
1546         result = comm_client_request(mpc->info.request.cc, "getsize",
1547                         g_variant_new("(si)", pkgid, get_type));
1548         if (result == NULL)
1549                 return PKGMGR_R_ECOMM;
1550
1551         g_variant_get(result, "(i&s)", &ret, &req_key);
1552         if (req_key == NULL) {
1553                 g_variant_unref(result);
1554                 return PKGMGR_R_ECOMM;
1555         }
1556         if (ret != PKGMGR_R_OK) {
1557                 g_variant_unref(result);
1558                 return ret;
1559         }
1560
1561         req_id = _get_request_id();
1562         __add_op_cbinfo(mpc, req_id, req_key, __get_pkg_size_info_cb, event_cb,
1563                         user_data);
1564
1565         g_variant_unref(result);
1566
1567         return PKGMGR_R_OK;
1568 }
1569
1570 API int pkgmgr_client_get_package_size_info(pkgmgr_client *pc, const char *pkgid, pkgmgr_pkg_size_info_receive_cb event_cb, void *user_data)
1571 {
1572         return pkgmgr_client_usr_get_package_size_info(pc, pkgid, event_cb, user_data, GLOBAL_USER);
1573 }
1574
1575 API int pkgmgr_client_usr_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb event_cb, void *user_data, uid_t uid)
1576 {       // total package size info
1577         return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, uid);
1578 }
1579
1580 API int pkgmgr_client_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb event_cb, void *user_data)
1581 {
1582         return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, GLOBAL_USER);
1583 }