Clean up event signal related code
[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 "comm_client.h"
44
45 /* API export macro */
46 #ifndef API
47 #define API __attribute__ ((visibility("default")))
48 #endif
49
50 #define PKG_TMP_PATH tzplatform_mkpath(TZ_USER_APP, "tmp")
51
52 #define BINSH_NAME      "/bin/sh"
53 #define BINSH_SIZE      7
54
55 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
56 #define REGULAR_USER 5000
57
58 static inline uid_t _getuid(void)
59 {
60         uid_t uid = getuid();
61
62         if (uid < REGULAR_USER)
63                 return GLOBAL_USER;
64         else
65                 return uid;
66 }
67
68 static int _get_request_id()
69 {
70         static int internal_req_id = 1;
71
72         return internal_req_id++;
73 }
74
75 typedef struct _req_cb_info {
76         int request_id;
77         char *req_key;
78         pkgmgr_handler event_cb;
79         pkgmgr_app_handler app_event_cb;
80         void *data;
81         struct _req_cb_info *next;
82 } req_cb_info;
83
84 typedef struct _listen_cb_info {
85         int request_id;
86         pkgmgr_handler event_cb;
87         pkgmgr_app_handler app_event_cb;
88         void *data;
89         struct _listen_cb_info *next;
90 } listen_cb_info;
91
92 typedef struct _pkgmgr_client_t {
93         client_type ctype;
94         int status_type;
95         union {
96                 struct _request {
97                         comm_client *cc;
98                         req_cb_info *rhead;
99                 } request;
100                 struct _listening {
101                         comm_client *cc;
102                         listen_cb_info *lhead;
103                 } listening;
104         } info;
105         void *new_event_cb;
106         char *tep_path;
107         bool tep_move;
108 } pkgmgr_client_t;
109
110 typedef struct _iter_data {
111         pkgmgr_iter_fn iter_fn;
112         void *data;
113 } iter_data;
114
115 static int __xsystem(const char *argv[])
116 {
117         int status = 0;
118         pid_t pid;
119         pid = fork();
120         switch (pid) {
121         case -1:
122                 perror("fork failed");
123                 return -1;
124         case 0:
125                 /* child */
126                 execvp(argv[0], (char *const *)argv);
127                 _exit(-1);
128         default:
129                 /* parent */
130                 break;
131         }
132         if (waitpid(pid, &status, 0) == -1) {
133                 perror("waitpid failed");
134                 return -1;
135         }
136         if (WIFSIGNALED(status)) {
137                 perror("signal");
138                 return -1;
139         }
140         if (!WIFEXITED(status)) {
141                 /* shouldn't happen */
142                 perror("should not happen");
143                 return -1;
144         }
145         return WEXITSTATUS(status);
146 }
147
148 static void __error_to_string(int errnumber, char **errstr)
149 {
150         if (errstr == NULL)
151                 return;
152         switch (errnumber) {
153         case PKGCMD_ERR_PACKAGE_NOT_FOUND:
154                 *errstr = PKGCMD_ERR_PACKAGE_NOT_FOUND_STR;
155                 break;
156         case PKGCMD_ERR_PACKAGE_INVALID:
157                 *errstr = PKGCMD_ERR_PACKAGE_INVALID_STR;
158                 break;
159         case PKGCMD_ERR_PACKAGE_LOWER_VERSION:
160                 *errstr = PKGCMD_ERR_PACKAGE_LOWER_VERSION_STR;
161                 break;
162         case PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND:
163                 *errstr = PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND_STR;
164                 break;
165         case PKGCMD_ERR_MANIFEST_INVALID:
166                 *errstr = PKGCMD_ERR_MANIFEST_INVALID_STR;
167                 break;
168         case PKGCMD_ERR_CONFIG_NOT_FOUND:
169                 *errstr = PKGCMD_ERR_CONFIG_NOT_FOUND_STR;
170                 break;
171         case PKGCMD_ERR_CONFIG_INVALID:
172                 *errstr = PKGCMD_ERR_CONFIG_INVALID_STR;
173                 break;
174         case PKGCMD_ERR_SIGNATURE_NOT_FOUND:
175                 *errstr = PKGCMD_ERR_SIGNATURE_NOT_FOUND_STR;
176                 break;
177         case PKGCMD_ERR_SIGNATURE_INVALID:
178                 *errstr = PKGCMD_ERR_SIGNATURE_INVALID_STR;
179                 break;
180         case PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED:
181                 *errstr = PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED_STR;
182                 break;
183         case PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND:
184                 *errstr = PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND_STR;
185                 break;
186         case PKGCMD_ERR_CERTIFICATE_INVALID:
187                 *errstr = PKGCMD_ERR_CERTIFICATE_INVALID_STR;
188                 break;
189         case PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
190                 *errstr = PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED_STR;
191                 break;
192         case PKGCMD_ERR_CERTIFICATE_EXPIRED:
193                 *errstr = PKGCMD_ERR_CERTIFICATE_EXPIRED_STR;
194                 break;
195         case PKGCMD_ERR_INVALID_PRIVILEGE:
196                 *errstr = PKGCMD_ERR_INVALID_PRIVILEGE_STR;
197                 break;
198         case PKGCMD_ERR_MENU_ICON_NOT_FOUND:
199                 *errstr = PKGCMD_ERR_MENU_ICON_NOT_FOUND_STR;
200                 break;
201         case PKGCMD_ERR_FATAL_ERROR:
202                 *errstr = PKGCMD_ERR_FATAL_ERROR_STR;
203                 break;
204         case PKGCMD_ERR_OUT_OF_STORAGE:
205                 *errstr = PKGCMD_ERR_OUT_OF_STORAGE_STR;
206                 break;
207         case PKGCMD_ERR_OUT_OF_MEMORY:
208                 *errstr = PKGCMD_ERR_OUT_OF_MEMORY_STR;
209                 break;
210         case PKGCMD_ERR_ARGUMENT_INVALID:
211                 *errstr = PKGCMD_ERR_ARGUMENT_INVALID_STR;
212                 break;
213         default:
214                 *errstr = PKGCMD_ERR_UNKNOWN_STR;
215                 break;
216         }
217 }
218
219 static void __add_op_cbinfo(pkgmgr_client_t *pc, int request_id,
220                             const char *req_key, pkgmgr_handler event_cb, void *new_event_cb,
221                             void *data)
222 {
223         req_cb_info *cb_info;
224         req_cb_info *current;
225         req_cb_info *prev;
226
227         cb_info = (req_cb_info *) calloc(1, sizeof(req_cb_info));
228         if (cb_info == NULL) {
229                 DBG("calloc failed");
230                 return;
231         }
232         cb_info->request_id = request_id;
233         cb_info->req_key = strdup(req_key);
234         cb_info->event_cb = event_cb;
235         cb_info->data = data;
236         cb_info->next = NULL;
237         cb_info->app_event_cb = NULL;
238         pc->new_event_cb = new_event_cb;
239
240         if (pc->info.request.rhead == NULL)
241                 pc->info.request.rhead = cb_info;
242         else {
243                 current = prev = pc->info.request.rhead;
244                 while (current) {
245                         prev = current;
246                         current = current->next;
247                 }
248
249                 prev->next = cb_info;
250         }
251 }
252
253 static void __add_op_app_cbinfo(pkgmgr_client_t *pc, int request_id,
254                             const char *req_key, pkgmgr_app_handler app_event_cb, void *data)
255 {
256         req_cb_info *cb_info;
257         req_cb_info *current;
258         req_cb_info *prev;
259
260         cb_info = (req_cb_info *) calloc(1, sizeof(req_cb_info));
261         if (cb_info == NULL) {
262                 DBG("calloc failed");
263                 return;
264         }
265         cb_info->request_id = request_id;
266         cb_info->req_key = strdup(req_key);
267         cb_info->event_cb = NULL;
268         cb_info->app_event_cb = app_event_cb;
269         cb_info->data = data;
270         cb_info->next = NULL;
271         pc->new_event_cb = NULL;
272
273         if (pc->info.request.rhead == NULL)
274                 pc->info.request.rhead = cb_info;
275         else {
276                 current = prev = pc->info.request.rhead;
277                 while (current) {
278                         prev = current;
279                         current = current->next;
280                 }
281
282                 prev->next = cb_info;
283         }
284 }
285
286 static req_cb_info *__find_op_cbinfo(pkgmgr_client_t *pc, const char *req_key)
287 {
288         req_cb_info *tmp;
289
290         tmp = pc->info.request.rhead;
291
292         if (tmp == NULL) {
293                 ERR("tmp is NULL");
294                 return NULL;
295         }
296
297         DBG("tmp->req_key %s, req_key %s", tmp->req_key, req_key);
298
299         while (tmp) {
300                 if (strncmp(tmp->req_key, req_key, strlen(tmp->req_key)) == 0)
301                         return tmp;
302                 tmp = tmp->next;
303         }
304         return NULL;
305 }
306
307 static int __remove_stat_cbinfo(pkgmgr_client_t *pc)
308 {
309         listen_cb_info *info = pc->info.listening.lhead;
310         listen_cb_info *next = NULL;
311
312         while (info != NULL) {
313                 next = info->next;
314                 free(info);
315                 info = next;
316         }
317
318         pc->info.listening.lhead = NULL;
319         return 0;
320 }
321
322 static void __add_app_stat_cbinfo(pkgmgr_client_t *pc, int request_id,
323                               pkgmgr_app_handler event_cb, void *data)
324 {
325         listen_cb_info *cb_info;
326         listen_cb_info *current;
327         listen_cb_info *prev;
328
329         cb_info = (listen_cb_info *) calloc(1, sizeof(listen_cb_info));
330         if (cb_info == NULL) {
331                 DBG("calloc failed");
332                 return;
333         }
334         cb_info->request_id = request_id;
335         cb_info->app_event_cb = event_cb;
336         cb_info->data = data;
337         cb_info->next = NULL;
338
339         if (pc->info.listening.lhead == NULL)
340                 pc->info.listening.lhead = cb_info;
341         else {
342                 current = prev = pc->info.listening.lhead;
343                 while (current) {
344                         prev = current;
345                         current = current->next;
346                 }
347
348                 prev->next = cb_info;
349         }
350 }
351
352 static void __add_stat_cbinfo(pkgmgr_client_t *pc, int request_id,
353                               pkgmgr_handler event_cb, void *data)
354 {
355         listen_cb_info *cb_info;
356         listen_cb_info *current;
357         listen_cb_info *prev;
358
359         cb_info = (listen_cb_info *) calloc(1, sizeof(listen_cb_info));
360         if (cb_info == NULL) {
361                 DBG("calloc failed");
362                 return;
363         }
364         cb_info->request_id = request_id;
365         cb_info->event_cb = event_cb;
366         cb_info->data = data;
367         cb_info->next = NULL;
368
369         /* TODO - check the order of callback - FIFO or LIFO => Should be changed to LIFO */
370         if (pc->info.listening.lhead == NULL)
371                 pc->info.listening.lhead = cb_info;
372         else {
373                 current = prev = pc->info.listening.lhead;
374                 while (current) {
375                         prev = current;
376                         current = current->next;
377                 }
378
379                 prev->next = cb_info;
380         }
381 }
382
383 static void __operation_callback(void *cb_data, uid_t target_uid,
384                                  const char *req_id, const char *pkg_type,
385                                  const char *pkgid,  const char *appid,
386                                  const char *key,    const char *val)
387 {
388         pkgmgr_client_t *pc;
389         req_cb_info *cb_info;
390
391         pc = (pkgmgr_client_t *) cb_data;
392
393         /* find callback info */
394         cb_info = __find_op_cbinfo(pc, req_id);
395         if (cb_info == NULL) {
396                 ERR("cannot find cb_info for req_id:%s", req_id);
397                 return;
398         }
399
400         /* call callback */
401         if (appid != NULL && strlen(appid) != 0 && cb_info->app_event_cb) {
402                 /* run app callback */
403                 if (pc->new_event_cb)
404                         cb_info->app_event_cb(target_uid, cb_info->request_id,
405                                         pkg_type, pkgid, appid, key, val, pc,
406                                         cb_info->data);
407                 else
408                         cb_info->app_event_cb(target_uid, cb_info->request_id,
409                                         pkg_type, pkgid, appid, key, val, NULL,
410                                         cb_info->data);
411         } else if (cb_info->event_cb) {
412                 /* run pkg callback */
413                 if (pc->new_event_cb)
414                         cb_info->event_cb(target_uid, cb_info->request_id,
415                                         pkg_type, pkgid, key, val, pc,
416                                         cb_info->data);
417                 else
418                         cb_info->event_cb(target_uid, cb_info->request_id,
419                                         pkg_type, pkgid, key, val, NULL,
420                                         cb_info->data);
421         }
422
423         return;
424 }
425
426 static void __status_callback(void *cb_data, uid_t target_uid,
427                               const char *req_id, const char *pkg_type,
428                               const char *pkgid,  const char *appid,
429                               const char *key,    const char *val)
430 {
431         pkgmgr_client_t *pc;
432         listen_cb_info *tmp;
433
434         pc = (pkgmgr_client_t *) cb_data;
435
436         tmp = pc->info.listening.lhead;
437         while (tmp) {
438                 if (appid != NULL && strlen(appid) != 0) {
439                         /* run app callback */
440                         if (tmp->app_event_cb && tmp->app_event_cb(
441                                         target_uid, tmp->request_id, pkg_type, pkgid,
442                                         appid, key, val, NULL, tmp->data) != 0)
443                                 break;
444                 } else {
445                         /* run pkg callback */
446                         if (tmp->event_cb && tmp->event_cb(
447                                 target_uid, tmp->request_id, pkg_type, pkgid,
448                                 key, val, NULL, tmp->data) != 0)
449                                 break;
450                 }
451                 tmp = tmp->next;
452         }
453
454         return;
455 }
456
457 static inline int __read_proc(const char *path, char *buf, int size)
458 {
459         int fd = 0;
460         int ret = 0;
461
462         if (buf == NULL || path == NULL)
463                 return -1;
464
465         fd = open(path, O_RDONLY);
466         if (fd < 0)
467                 return -1;
468
469         ret = read(fd, buf, size - 1);
470         if (ret <= 0) {
471                 close(fd);
472                 return -1;
473         } else
474                 buf[ret] = 0;
475
476         close(fd);
477
478         return ret;
479 }
480
481 char *__proc_get_cmdline_bypid(int pid)
482 {
483         char buf[PKG_STRING_LEN_MAX] = {'\0', };
484         int ret = 0;
485
486         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
487         ret = __read_proc(buf, buf, sizeof(buf));
488         if (ret <= 0)
489                 return NULL;
490
491         /* support app launched by shell script*/
492         if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
493                 return strdup(&buf[BINSH_SIZE + 1]);
494         else
495                 return strdup(buf);
496 }
497
498 static inline int __pkgmgr_read_proc(const char *path, char *buf, int size)
499 {
500         int fd;
501         int ret;
502
503         if (buf == NULL || path == NULL)
504                 return -1;
505
506         fd = open(path, O_RDONLY);
507         if (fd < 0)
508                 return -1;
509
510         ret = read(fd, buf, size - 1);
511         if (ret <= 0) {
512                 close(fd);
513                 return -1;
514         } else
515                 buf[ret] = 0;
516
517         close(fd);
518
519         return ret;
520 }
521
522 static int __sync_process(const char *req_key)
523 {
524         int ret;
525         char info_file[PKG_STRING_LEN_MAX] = {'\0', };
526         int result = -1;
527         int check_cnt = 0;
528         FILE *fp;
529         char buf[PKG_STRING_LEN_MAX] = {0, };
530
531         snprintf(info_file, PKG_STRING_LEN_MAX, "%s/%s", PKG_SIZE_INFO_PATH, req_key);
532         while (1) {
533                 check_cnt++;
534
535                 if (access(info_file, F_OK) == 0) {
536                         fp = fopen(info_file, "r");
537                         if (fp == NULL) {
538                                 DBG("file is not generated yet.... wait\n");
539                                 usleep(100 * 1000);     /* 100ms sleep*/
540                                 continue;
541                         }
542
543                         if (fgets(buf, PKG_STRING_LEN_MAX, fp) == NULL) {
544                                 ERR("failed to read info file");
545                                 fclose(fp);
546                                 break;
547                         }
548                         fclose(fp);
549
550                         DBG("info_file file is generated, result = %s. \n", buf);
551                         result = atoi(buf);
552                         break;
553                 }
554
555                 DBG("file is not generated yet.... wait\n");
556                 usleep(100 * 1000);     /* 100ms sleep*/
557
558                 if (check_cnt > 6000) { /* 60s * 10 time over*/
559                         ERR("wait time over!!\n");
560                         break;
561                 }
562         }
563
564         ret = remove(info_file);
565         if (ret < 0)
566                 ERR("file is can not remove[%s, %d]\n", info_file, ret);
567
568         return result;
569 }
570
571 static int __get_size_process(pkgmgr_client *pc, const char *pkgid, uid_t uid,
572                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
573                 void *data)
574 {
575         GVariant *result;
576         int ret = PKGMGR_R_ECOMM;
577         char *req_key = NULL;
578         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
579
580         if (pc == NULL || pkgid == NULL) {
581                 ERR("invalid parameter");
582                 return PKGMGR_R_EINVAL;
583         }
584
585         if (mpc->ctype != PC_REQUEST) {
586                 ERR("mpc->ctype is not PC_REQUEST");
587                 return PKGMGR_R_EINVAL;
588         }
589
590         ret = comm_client_request(mpc->info.request.cc, "getsize",
591                         g_variant_new("(usi)", uid, pkgid, get_type), &result);
592         if (ret != PKGMGR_R_OK) {
593                 ERR("request failed: %d", ret);
594                 return ret;
595         }
596
597         g_variant_get(result, "(i&s)", &ret, &req_key);
598         if (req_key == NULL) {
599                 g_variant_unref(result);
600                 return PKGMGR_R_ECOMM;
601         }
602         if (ret != PKGMGR_R_OK) {
603                 g_variant_unref(result);
604                 return ret;
605         }
606
607         ret = __sync_process(req_key);
608         if (ret < 0)
609                 ERR("get size failed, ret=%d\n", ret);
610
611         g_variant_unref(result);
612
613         return ret;
614 }
615
616 static int __move_pkg_process(pkgmgr_client *pc, const char *pkgid,
617                 const char *pkg_type, uid_t uid, pkgmgr_move_type move_type,
618                 pkgmgr_handler event_cb, void *data)
619 {
620         int ret;
621
622         ret = pkgmgr_client_usr_move(pc, pkg_type, pkgid, move_type, event_cb, data, uid);
623         if (ret < 0) {
624                 ERR("move request failed");
625                 return ret;
626         }
627
628         return ret;
629 }
630
631 static int __check_app_process(pkgmgr_request_service_type service_type,
632                 pkgmgr_client *pc, const char *pkgid, uid_t uid, void *data)
633 {
634         GVariant *result;
635         int ret = PKGMGR_R_ECOMM;
636         pkgmgrinfo_pkginfo_h handle;
637         int pid = -1;
638         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
639
640         retvm_if(mpc->ctype != PC_REQUEST, PKGMGR_R_EINVAL, "mpc->ctype is not PC_REQUEST\n");
641
642         if (uid != GLOBAL_USER)
643                 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
644         else
645                 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
646         retvm_if(ret < 0, PKGMGR_R_ERROR, "pkgmgrinfo_pkginfo_get_pkginfo failed");
647
648         if (service_type == PM_REQUEST_KILL_APP)
649                 ret = comm_client_request(mpc->info.request.cc, "kill",
650                                 g_variant_new("(us)", uid, pkgid), &result);
651         else if (service_type == PM_REQUEST_CHECK_APP)
652                 ret = comm_client_request(mpc->info.request.cc, "check",
653                                 g_variant_new("(us)", uid, pkgid), &result);
654         if (ret != PKGMGR_R_OK) {
655                 ERR("request failed: %d", ret);
656                 return ret;
657         }
658
659         g_variant_get(result, "(i)", &ret);
660         g_variant_unref(result);
661         if (ret != PKGMGR_R_OK) {
662                 ERR("request failed, ret=%d", ret);
663                 return ret;
664         }
665
666         /* FIXME */
667         pid  = __sync_process(pkgid);
668         *(int *)data = pid;
669
670         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
671
672         return ret;
673
674 }
675
676 static int __request_size_info(pkgmgr_client *pc, uid_t uid)
677 {
678         GVariant *result;
679         int ret = PKGMGR_R_ECOMM;
680         char *req_key = NULL;
681         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
682
683         if (pc == NULL) {
684                 ERR("invalid parameter");
685                 return PKGMGR_R_EINVAL;
686         }
687
688         if (mpc->ctype != PC_REQUEST) {
689                 ERR("mpc->ctype is not PC_REQUEST");
690                 return PKGMGR_R_EINVAL;
691         }
692
693         ret = comm_client_request(mpc->info.request.cc, "getsize",
694                         g_variant_new("(usi)", uid, "size_info",
695                                 PM_GET_SIZE_INFO),
696                         &result);
697         if (ret != PKGMGR_R_OK) {
698                 ERR("request failed: %d", ret);
699                 return ret;
700         }
701
702         g_variant_get(result, "(i&s)", &ret, &req_key);
703         if (req_key == NULL) {
704                 g_variant_unref(result);
705                 return PKGMGR_R_ECOMM;
706         }
707
708         g_variant_unref(result);
709
710         return ret;
711 }
712
713 static int __change_op_cb_for_getsize(pkgmgr_client *pc)
714 {
715         int ret = -1;
716
717         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
718         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
719
720         /*  free listening head */
721         req_cb_info *tmp = NULL;
722         req_cb_info *prev = NULL;
723         for (tmp = mpc->info.request.rhead; tmp;) {
724                 prev = tmp;
725                 tmp = tmp->next;
726                 free(prev);
727         }
728
729         /* free dbus connection */
730         ret = comm_client_free(mpc->info.request.cc);
731         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
732
733         /* Manage pc for seperated event */
734         mpc->ctype = PC_REQUEST;
735         mpc->status_type = PKGMGR_CLIENT_STATUS_GET_SIZE;
736
737
738         mpc->info.request.cc = comm_client_new(PC_REQUEST);
739         retvm_if(mpc->info.request.cc == NULL, PKGMGR_R_ERROR, "client creation failed");
740
741         ret = comm_client_set_status_callback(PKGMGR_CLIENT_STATUS_GET_SIZE, mpc->info.request.cc, __operation_callback, pc);
742         retvm_if(ret < 0, PKGMGR_R_ERROR, "set_status_callback() failed - %d", ret);
743
744         return PKGMGR_R_OK;
745 }
746
747 static int __change_op_cb_for_enable_disable(pkgmgr_client *pc, bool is_disable)
748 {
749         int ret = -1;
750
751         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
752         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
753
754         /*  free listening head */
755         req_cb_info *tmp = NULL;
756         req_cb_info *prev = NULL;
757         for (tmp = mpc->info.request.rhead; tmp;) {
758                 prev = tmp;
759                 tmp = tmp->next;
760                 free(prev);
761         }
762
763         /* free dbus connection */
764         ret = comm_client_free(mpc->info.request.cc);
765         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
766
767         /* Manage pc for seperated event */
768         mpc->ctype = PC_REQUEST;
769         if (is_disable)
770                 mpc->status_type = PKGMGR_CLIENT_STATUS_DISABLE_APP;
771         else
772                 mpc->status_type = PKGMGR_CLIENT_STATUS_ENABLE_APP;
773
774
775         mpc->info.request.cc = comm_client_new(PC_REQUEST);
776         retvm_if(mpc->info.request.cc == NULL, PKGMGR_R_ERROR, "client creation failed");
777
778         ret = comm_client_set_status_callback(mpc->status_type, mpc->info.request.cc, __operation_callback, pc);
779         retvm_if(ret < 0, PKGMGR_R_ERROR, "set_status_callback() failed - %d", ret);
780
781         return PKGMGR_R_OK;
782 }
783
784 static int __get_pkg_size_info_cb(uid_t target_uid, int req_id, const char *req_type,
785                 const char *pkgid, const char *key,
786                 const char *value, const void *pc, void *user_data)
787 {
788         int ret = 0;
789         DBG("target_uid: %u, reqid: %d, req type: %s, pkgid: %s, unused key: %s, size info: %s",
790                         target_uid, req_id, req_type, pkgid, key, value);
791
792         pkg_size_info_t *size_info = (pkg_size_info_t *)malloc(sizeof(pkg_size_info_t));
793         retvm_if(size_info == NULL, -1, "The memory is insufficient.");
794
795         char *save_ptr = NULL;
796         char *token = strtok_r((char *)value, ":", &save_ptr);
797         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
798         size_info->data_size = atoll(token);
799         token = strtok_r(NULL, ":", &save_ptr);
800         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
801         size_info->cache_size = atoll(token);
802         token = strtok_r(NULL, ":", &save_ptr);
803         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
804         size_info->app_size = atoll(token);
805         token = strtok_r(NULL, ":", &save_ptr);
806         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
807         size_info->ext_data_size = atoll(token);
808         token = strtok_r(NULL, ":", &save_ptr);
809         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
810         size_info->ext_cache_size = atoll(token);
811         token = strtok_r(NULL, ":", &save_ptr);
812         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
813         size_info->ext_app_size = atoll(token);
814
815         DBG("data: %lld, cache: %lld, app: %lld, ext_data: %lld, ext_cache: %lld, ext_app: %lld",
816                         size_info->data_size, size_info->cache_size, size_info->app_size,
817                         size_info->ext_data_size, size_info->ext_cache_size, size_info->ext_app_size);
818
819         pkgmgr_client_t *pmc = (pkgmgr_client_t *)pc;
820         tryvm_if(pmc == NULL, ret = -1, "pkgmgr_client instance is null.");
821
822         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0) {  /* total package size info */
823                 pkgmgr_total_pkg_size_info_receive_cb callback = (pkgmgr_total_pkg_size_info_receive_cb)(pmc->new_event_cb);
824                 callback((pkgmgr_client *)pc, size_info, user_data);
825         } else {
826                 pkgmgr_pkg_size_info_receive_cb callback = (pkgmgr_pkg_size_info_receive_cb)(pmc->new_event_cb);
827                 callback((pkgmgr_client *)pc, pkgid, size_info, user_data);
828         }
829
830 catch:
831
832         if (size_info) {
833                 free(size_info);
834                 size_info = NULL;
835         }
836         return ret;
837 }
838
839 API pkgmgr_client *pkgmgr_client_new(client_type ctype)
840 {
841         pkgmgr_client_t *pc = NULL;
842         int ret = -1;
843
844         retvm_if(ctype == PC_BROADCAST, NULL, "broadcast type is not supported");
845         retvm_if(ctype != PC_REQUEST && ctype != PC_LISTENING, NULL, "ctype is not client_type");
846
847         /* Allocate memory for ADT:pkgmgr_client */
848         pc = calloc(1, sizeof(pkgmgr_client_t));
849         retvm_if(pc == NULL, NULL, "No memory");
850
851         /* Manage pc */
852         pc->ctype = ctype;
853         pc->status_type = PKGMGR_CLIENT_STATUS_ALL;
854         pc->tep_path = NULL;
855
856         if (pc->ctype == PC_REQUEST) {
857                 pc->info.request.cc = comm_client_new(PC_REQUEST);
858                 trym_if(pc->info.request.cc == NULL, "client creation failed");
859
860                 ret = comm_client_set_status_callback(PKGMGR_CLIENT_STATUS_ALL, pc->info.request.cc, __operation_callback, pc);
861                 trym_if(ret < 0L, "comm_client_set_status_callback() failed - %d", ret);
862         } else if (pc->ctype == PC_LISTENING) {
863                 pc->info.listening.cc = comm_client_new(PC_LISTENING);
864                 trym_if(pc->info.listening.cc == NULL, "client creation failed");
865
866                 ret = comm_client_set_status_callback(PKGMGR_CLIENT_STATUS_ALL, pc->info.listening.cc, __status_callback, pc);
867                 trym_if(ret < 0L, "comm_client_set_status_callback() failed - %d", ret);
868         }
869
870         return (pkgmgr_client *)pc;
871
872  catch:
873         if (pc)
874                 free(pc);
875         return NULL;
876 }
877
878 API int pkgmgr_client_free(pkgmgr_client *pc)
879 {
880         int ret = -1;
881         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
882         retvm_if(mpc == NULL, PKGMGR_R_EINVAL, "Invalid argument");
883
884         if (mpc->ctype == PC_REQUEST) {
885                 req_cb_info *tmp;
886                 req_cb_info *prev;
887                 for (tmp = mpc->info.request.rhead; tmp;) {
888                         prev = tmp;
889                         tmp = tmp->next;
890                         free(prev);
891                 }
892
893                 ret = comm_client_free(mpc->info.request.cc);
894                 tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "comm_client_free() failed");
895         } else if (mpc->ctype == PC_LISTENING) {
896                         listen_cb_info *tmp;
897                         listen_cb_info *prev;
898                         for (tmp = mpc->info.listening.lhead; tmp;) {
899                                 prev = tmp;
900                                 tmp = tmp->next;
901                                 free(prev);
902                         }
903
904                         ret = comm_client_free(mpc->info.listening.cc);
905                         tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "comm_client_free() failed");
906         } else if (mpc->ctype == PC_BROADCAST) {
907                 ret = 0;
908         } else {
909                 ERR("Invalid client type\n");
910                 return PKGMGR_R_EINVAL;
911         }
912
913         if (mpc->tep_path) {
914                 free(mpc->tep_path);
915                 mpc->tep_path = NULL;
916         }
917
918         free(mpc);
919         mpc = NULL;
920         return PKGMGR_R_OK;
921
922  catch:
923         if (mpc) {
924                 free(mpc);
925                 mpc = NULL;
926         }
927         return PKGMGR_R_ERROR;
928 }
929
930 static char *__get_type_from_path(const char *pkg_path)
931 {
932         int ret;
933         char mimetype[255] = { '\0', };
934         char extlist[256] = { '\0', };
935         char *pkg_type;
936
937         ret = _get_mime_from_file(pkg_path, mimetype, sizeof(mimetype));
938         if (ret) {
939                 ERR("_get_mime_from_file() failed - error code[%d]\n", ret);
940                 return NULL;
941         }
942
943         ret = _get_mime_extension(mimetype, extlist, sizeof(extlist));
944         if (ret) {
945                 ERR("_get_mime_extension() failed - error code[%d]\n", ret);
946                 return NULL;
947         }
948
949         if (strlen(extlist) == 0)
950                 return NULL;
951
952         if (strchr(extlist, ','))
953                 extlist[strlen(extlist) - strlen(strchr(extlist, ','))] = '\0';
954
955         pkg_type = strchr(extlist, '.') + 1;
956         return strdup(pkg_type);
957 }
958
959 static int __change_op_cb_for_enable_disable_splash_screen(pkgmgr_client *pc,
960                 bool is_enable)
961 {
962         int ret;
963         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
964         req_cb_info *tmp;
965         req_cb_info *prev;
966
967         if (mpc == NULL) {
968                 ERR("package mananger client pc is NULL");
969                 return PKGMGR_R_EINVAL;
970         }
971
972         for (tmp = mpc->info.request.rhead; tmp;) {
973                 prev = tmp;
974                 tmp = tmp->next;
975                 free(prev);
976         }
977
978         ret = comm_client_free(mpc->info.request.cc);
979         if (ret < 0) {
980                 ERR("comm_client_free() failed - %d", ret);
981                 return PKGMGR_R_ERROR;
982         }
983
984         mpc->ctype = PC_REQUEST;
985         if (is_enable)
986                 mpc->status_type = PKGMGR_CLIENT_STATUS_ENABLE_APP_SPLASH_SCREEN;
987         else
988                 mpc->status_type = PKGMGR_CLIENT_STATUS_DISABLE_APP_SPLASH_SCREEN;
989
990         mpc->info.request.cc = comm_client_new(PC_REQUEST);
991         if (mpc->info.request.cc == NULL) {
992                 ERR("client creation failed");
993                 return PKGMGR_R_ENOMEM;
994         }
995
996         ret = comm_client_set_status_callback(mpc->status_type,
997                         mpc->info.request.cc, __operation_callback, pc);
998         if (ret < 0) {
999                 ERR("set_status_callback() failed - %d", ret);
1000                 return PKGMGR_R_ERROR;
1001         }
1002
1003         return PKGMGR_R_OK;
1004 }
1005
1006 API int pkgmgr_client_set_tep_path(pkgmgr_client *pc, char *tep_path, bool tep_move)
1007 {
1008         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1009         retvm_if(tep_path == NULL, PKGMGR_R_EINVAL, "tep path is NULL");
1010         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1011
1012         if (mpc->tep_path)
1013                 free(mpc->tep_path);
1014
1015         mpc->tep_path = strdup(tep_path);
1016         mpc->tep_move = tep_move;
1017
1018         return PKGMGR_R_OK;
1019 }
1020
1021 API int pkgmgr_client_usr_install(pkgmgr_client *pc, const char *pkg_type,
1022                 const char *descriptor_path, const char *pkg_path,
1023                 const char *optional_data, pkgmgr_mode mode,
1024                 pkgmgr_handler event_cb, void *data, uid_t uid)
1025 {
1026         GVariant *result;
1027         int ret = PKGMGR_R_ECOMM;
1028         char *req_key = NULL;
1029         GVariantBuilder *builder = NULL;
1030         GVariant *args = NULL;
1031         int req_id;
1032         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1033         char *pkgtype;
1034
1035         if (pc == NULL || pkg_path == NULL) {
1036                 ERR("invalid parameter");
1037                 return PKGMGR_R_EINVAL;
1038         }
1039
1040         if (mpc->ctype != PC_REQUEST) {
1041                 ERR("mpc->ctype is not PC_REQUEST");
1042                 return PKGMGR_R_EINVAL;
1043         }
1044
1045         if (access(pkg_path, F_OK) != 0) {
1046                 ERR("failed to access: %s", pkg_path);
1047                 return PKGMGR_R_EINVAL;
1048         }
1049
1050         if (mpc->tep_path != NULL && access(mpc->tep_path, F_OK) != 0) {
1051                 ERR("failed to access: %s", mpc->tep_path);
1052                 return PKGMGR_R_EINVAL;
1053         }
1054
1055         /* TODO: check pkg's type on server-side */
1056         if (pkg_type == NULL)
1057                 pkgtype = __get_type_from_path(pkg_path);
1058         else
1059                 pkgtype = strdup(pkg_type);
1060
1061         /* build arguments */
1062         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1063         if (mpc->tep_path) {
1064                 g_variant_builder_add(builder, "s", "-e");
1065                 g_variant_builder_add(builder, "s", mpc->tep_path);
1066                 g_variant_builder_add(builder, "s", "-M");
1067                 /* TODO: revise tep_move */
1068                 g_variant_builder_add(builder, "s",
1069                                 mpc->tep_move ? "tep_move" : "tep_copy");
1070         }
1071
1072         args = g_variant_new("as", builder);
1073         g_variant_builder_unref(builder);
1074
1075         ret = comm_client_request(mpc->info.request.cc, "install",
1076                         g_variant_new("(uss@as)", uid, pkgtype, pkg_path, args),
1077                         &result);
1078         if (ret != PKGMGR_R_OK) {
1079                 ERR("request failed: %d", ret);
1080                 return ret;
1081         }
1082
1083         g_variant_get(result, "(i&s)", &ret, &req_key);
1084         if (req_key == NULL) {
1085                 g_variant_unref(result);
1086                 return PKGMGR_R_ECOMM;
1087         }
1088         if (ret != PKGMGR_R_OK) {
1089                 g_variant_unref(result);
1090                 return ret;
1091         }
1092
1093         req_id = _get_request_id();
1094         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1095
1096         g_variant_unref(result);
1097
1098         return req_id;
1099 }
1100
1101 API int pkgmgr_client_install(pkgmgr_client *pc, const char *pkg_type,
1102                 const char *descriptor_path, const char *pkg_path,
1103                 const char *optional_data, pkgmgr_mode mode,
1104                 pkgmgr_handler event_cb, void *data)
1105 {
1106         return pkgmgr_client_usr_install(pc, pkg_type, descriptor_path,
1107                         pkg_path, optional_data, mode, event_cb, data,
1108                         _getuid());
1109 }
1110
1111 API int pkgmgr_client_reinstall(pkgmgr_client *pc, const char *pkg_type,
1112                 const char *pkgid, const char *optional_data, pkgmgr_mode mode,
1113                 pkgmgr_handler event_cb, void *data)
1114 {
1115         return pkgmgr_client_usr_reinstall(pc, pkg_type, pkgid, optional_data,
1116                         mode, event_cb, data, _getuid());
1117 }
1118
1119 API int pkgmgr_client_usr_reinstall(pkgmgr_client *pc, const char *pkg_type,
1120                 const char *pkgid, const char *optional_data, pkgmgr_mode mode,
1121                 pkgmgr_handler event_cb, void *data, uid_t uid)
1122 {
1123         GVariant *result;
1124         int ret = PKGMGR_R_ECOMM;
1125         char *req_key = NULL;
1126         int req_id;
1127         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1128         char *pkgtype;
1129         pkgmgrinfo_pkginfo_h handle;
1130
1131         if (pc == NULL || pkgid == NULL) {
1132                 ERR("invalid parameter");
1133                 return PKGMGR_R_EINVAL;
1134         }
1135
1136         if (mpc->ctype != PC_REQUEST) {
1137                 ERR("mpc->ctype is not PC_REQUEST");
1138                 return PKGMGR_R_EINVAL;
1139         }
1140
1141         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
1142         if (ret < 0)
1143                 return PKGMGR_R_EINVAL;
1144
1145         ret = pkgmgrinfo_pkginfo_get_type(handle, &pkgtype);
1146         if (ret < 0) {
1147                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1148                 return PKGMGR_R_ERROR;
1149         }
1150
1151         ret = comm_client_request(mpc->info.request.cc, "reinstall",
1152                         g_variant_new("(uss)", uid, pkgtype, pkgid), &result);
1153         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1154         if (ret != PKGMGR_R_OK) {
1155                 ERR("request failed: %d", ret);
1156                 return ret;
1157         }
1158
1159         g_variant_get(result, "(i&s)", &ret, &req_key);
1160         if (req_key == NULL) {
1161                 g_variant_unref(result);
1162                 return PKGMGR_R_ECOMM;
1163         }
1164         if (ret != PKGMGR_R_OK) {
1165                 g_variant_unref(result);
1166                 return ret;
1167         }
1168
1169         req_id = _get_request_id();
1170         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1171
1172         g_variant_unref(result);
1173
1174         return req_id;
1175 }
1176
1177 API int pkgmgr_client_usr_mount_install(pkgmgr_client *pc, const char *pkg_type,
1178                 const char *descriptor_path, const char *pkg_path,
1179                 const char *optional_data, pkgmgr_mode mode,
1180                 pkgmgr_handler event_cb, void *data, uid_t uid)
1181 {
1182         GVariant *result;
1183         int ret = PKGMGR_R_ECOMM;
1184         char *req_key = NULL;
1185         GVariantBuilder *builder = NULL;
1186         GVariant *args = NULL;
1187         int req_id;
1188         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1189         char *pkgtype;
1190
1191         if (pc == NULL || pkg_path == NULL) {
1192                 ERR("invalid parameter");
1193                 return PKGMGR_R_EINVAL;
1194         }
1195
1196         if (mpc->ctype != PC_REQUEST) {
1197                 ERR("mpc->ctype is not PC_REQUEST");
1198                 return PKGMGR_R_EINVAL;
1199         }
1200
1201         if (access(pkg_path, F_OK) != 0) {
1202                 ERR("failed to access: %s", pkg_path);
1203                 return PKGMGR_R_EINVAL;
1204         }
1205
1206         if (mpc->tep_path != NULL && access(mpc->tep_path, F_OK) != 0) {
1207                 ERR("failed to access: %s", mpc->tep_path);
1208                 return PKGMGR_R_EINVAL;
1209         }
1210
1211         /* TODO: check pkg's type on server-side */
1212         if (pkg_type == NULL)
1213                 pkgtype = __get_type_from_path(pkg_path);
1214         else
1215                 pkgtype = strdup(pkg_type);
1216
1217         /* build arguments */
1218         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1219         if (mpc->tep_path) {
1220                 g_variant_builder_add(builder, "s", "-e");
1221                 g_variant_builder_add(builder, "s", mpc->tep_path);
1222                 g_variant_builder_add(builder, "s", "-M");
1223                 /* TODO: revise tep_move */
1224                 g_variant_builder_add(builder, "s",
1225                                 mpc->tep_move ? "tep_move" : "tep_copy");
1226         }
1227
1228         args = g_variant_new("as", builder);
1229         g_variant_builder_unref(builder);
1230
1231         ret = comm_client_request(mpc->info.request.cc, "mount_install",
1232                         g_variant_new("(uss@as)", uid, pkgtype, pkg_path, args),
1233                         &result);
1234         if (ret != PKGMGR_R_OK) {
1235                 ERR("request failed: %d", ret);
1236                 return ret;
1237         }
1238
1239         g_variant_get(result, "(i&s)", &ret, &req_key);
1240         if (req_key == NULL) {
1241                 g_variant_unref(result);
1242                 return PKGMGR_R_ECOMM;
1243         }
1244         if (ret != PKGMGR_R_OK) {
1245                 g_variant_unref(result);
1246                 return ret;
1247         }
1248
1249         req_id = _get_request_id();
1250         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1251
1252         g_variant_unref(result);
1253
1254         return req_id;
1255 }
1256
1257 API int pkgmgr_client_mount_install(pkgmgr_client *pc, const char *pkg_type,
1258                 const char *descriptor_path, const char *pkg_path,
1259                 const char *optional_data, pkgmgr_mode mode,
1260                 pkgmgr_handler event_cb, void *data)
1261 {
1262         return pkgmgr_client_usr_mount_install(pc, pkg_type, descriptor_path,
1263                         pkg_path, optional_data, mode, event_cb, data,
1264                         _getuid());
1265 }
1266
1267 API int pkgmgr_client_uninstall(pkgmgr_client *pc, const char *pkg_type,
1268                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
1269                 void *data)
1270 {
1271         return pkgmgr_client_usr_uninstall(pc, pkg_type, pkgid, mode, event_cb,
1272                         data, _getuid());
1273 }
1274
1275 API int pkgmgr_client_usr_uninstall(pkgmgr_client *pc, const char *pkg_type,
1276                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
1277                 void *data, uid_t uid)
1278 {
1279         GVariant *result;
1280         int ret = PKGMGR_R_ECOMM;
1281         char *req_key = NULL;
1282         int req_id;
1283         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1284         char *pkgtype;
1285         pkgmgrinfo_pkginfo_h handle;
1286
1287         if (pc == NULL || pkgid == NULL) {
1288                 ERR("invalid parameter");
1289                 return PKGMGR_R_EINVAL;
1290         }
1291
1292         if (mpc->ctype != PC_REQUEST) {
1293                 ERR("mpc->ctype is not PC_REQUEST");
1294                 return PKGMGR_R_EINVAL;
1295         }
1296
1297         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
1298         if (ret < 0)
1299                 return PKGMGR_R_EINVAL;
1300
1301         ret = pkgmgrinfo_pkginfo_get_type(handle, &pkgtype);
1302         if (ret < 0) {
1303                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1304                 return PKGMGR_R_ERROR;
1305         }
1306
1307         ret = comm_client_request(mpc->info.request.cc, "uninstall",
1308                         g_variant_new("(uss)", uid, pkgtype, pkgid), &result);
1309         if (ret != PKGMGR_R_OK) {
1310                 ERR("request failed: %d", ret);
1311                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1312                 return ret;
1313         }
1314
1315         g_variant_get(result, "(i&s)", &ret, &req_key);
1316         if (req_key == NULL) {
1317                 g_variant_unref(result);
1318                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1319                 return PKGMGR_R_ECOMM;
1320         }
1321         if (ret != PKGMGR_R_OK) {
1322                 g_variant_unref(result);
1323                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1324                 return ret;
1325         }
1326
1327         req_id = _get_request_id();
1328         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1329
1330         g_variant_unref(result);
1331         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1332
1333         return req_id;
1334 }
1335
1336 API int pkgmgr_client_move(pkgmgr_client *pc, const char *pkg_type,
1337                 const char *pkgid, pkgmgr_move_type move_type,
1338                 pkgmgr_handler event_cb, void *data)
1339 {
1340         return pkgmgr_client_usr_move(pc, pkg_type, pkgid, move_type,
1341                         event_cb, data, _getuid());
1342 }
1343 API int pkgmgr_client_usr_move(pkgmgr_client *pc, const char *pkg_type,
1344                 const char *pkgid, pkgmgr_move_type move_type,
1345                 pkgmgr_handler event_cb, void *data, uid_t uid)
1346 {
1347         GVariant *result;
1348         int ret = PKGMGR_R_ECOMM;
1349         int req_id;
1350         char *req_key = NULL;
1351         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1352
1353         if (pc == NULL || pkg_type == NULL || pkgid == NULL) {
1354                 ERR("invalid parameter");
1355                 return PKGMGR_R_EINVAL;
1356         }
1357
1358         if ((move_type < PM_MOVE_TO_INTERNAL) || (move_type > PM_MOVE_TO_SDCARD))
1359                 return PKGMGR_R_EINVAL;
1360
1361         if (mpc->ctype != PC_REQUEST) {
1362                 ERR("mpc->ctype is not PC_REQUEST");
1363                 return PKGMGR_R_EINVAL;
1364         }
1365
1366         ret = comm_client_request(mpc->info.request.cc, "move",
1367                         g_variant_new("(ussi)", uid, pkg_type, pkgid, move_type), &result);
1368         if (ret != PKGMGR_R_OK) {
1369                 ERR("request failed: %d", ret);
1370                 return ret;
1371         }
1372
1373         g_variant_get(result, "(i&s)", &ret, &req_key);
1374         if (req_key == NULL) {
1375                 g_variant_unref(result);
1376                 return PKGMGR_R_ECOMM;
1377         }
1378         if (ret != PKGMGR_R_OK) {
1379                 g_variant_unref(result);
1380                 return ret;
1381         }
1382
1383         req_id = _get_request_id();
1384         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1385         g_variant_unref(result);
1386
1387         return ret;
1388 }
1389
1390 API int pkgmgr_client_usr_activate(pkgmgr_client *pc, const char *pkg_type,
1391                 const char *pkgid, uid_t uid)
1392 {
1393         GVariant *result;
1394         int ret = PKGMGR_R_ECOMM;
1395         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1396
1397         if (pc == NULL || pkgid == NULL || pkg_type == NULL) {
1398                 ERR("invalid parameter");
1399                 return PKGMGR_R_EINVAL;
1400         }
1401
1402         ret = comm_client_request(mpc->info.request.cc, "enable_pkg",
1403                         g_variant_new("(uss)", uid, pkg_type, pkgid), &result);
1404         if (ret != PKGMGR_R_OK) {
1405                 ERR("request failed: %d", ret);
1406                 return ret;
1407         }
1408
1409         g_variant_get(result, "(i)", &ret);
1410         g_variant_unref(result);
1411
1412         return ret;
1413 }
1414
1415 API int pkgmgr_client_activate(pkgmgr_client *pc, const char *pkg_type,
1416                 const char *pkgid)
1417 {
1418         return pkgmgr_client_usr_activate(pc, pkg_type, pkgid, _getuid());
1419 }
1420
1421 API int pkgmgr_client_usr_deactivate(pkgmgr_client *pc, const char *pkg_type,
1422                                  const char *pkgid, uid_t uid)
1423 {
1424         GVariant *result;
1425         int ret = PKGMGR_R_ECOMM;
1426         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1427
1428         if (pc == NULL || pkgid == NULL || pkg_type == NULL) {
1429                 ERR("invalid parameter");
1430                 return PKGMGR_R_EINVAL;
1431         }
1432
1433         ret = comm_client_request(mpc->info.request.cc, "disable_pkg",
1434                         g_variant_new("(uss)", uid, pkg_type, pkgid), &result);
1435         if (ret != PKGMGR_R_OK) {
1436                 ERR("request failed: %d", ret);
1437                 return ret;
1438         }
1439
1440         g_variant_get(result, "(i)", &ret);
1441         g_variant_unref(result);
1442
1443         return ret;
1444 }
1445
1446 API int pkgmgr_client_deactivate(pkgmgr_client *pc, const char *pkg_type,
1447                                  const char *pkgid)
1448 {
1449         return pkgmgr_client_usr_deactivate(pc, pkg_type, pkgid, _getuid());
1450 }
1451
1452 API int pkgmgr_client_usr_activate_app(pkgmgr_client *pc, const char *appid,
1453                 pkgmgr_app_handler app_event_cb, uid_t uid)
1454 {
1455         GVariant *result;
1456         int ret = PKGMGR_R_ECOMM;
1457         int req_id;
1458         char *req_key = NULL;
1459         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1460
1461         if (pc == NULL || appid == NULL) {
1462                 ERR("invalid parameter");
1463                 return PKGMGR_R_EINVAL;
1464         }
1465
1466         if (__change_op_cb_for_enable_disable(mpc, false) < 0) {
1467                 ERR("__change_op_cb_for_enable_disable failed");
1468                 return PKGMGR_R_ESYSTEM;
1469         }
1470
1471         ret = comm_client_request(mpc->info.request.cc, "enable_app",
1472                         g_variant_new("(us)", uid, appid), &result);
1473         if (ret != PKGMGR_R_OK) {
1474                 ERR("request failed: %d", ret);
1475                 return ret;
1476         }
1477
1478         g_variant_get(result, "(i&s)", &ret, &req_key);
1479         if (req_key == NULL) {
1480                 g_variant_unref(result);
1481                 return PKGMGR_R_ECOMM;
1482         }
1483         if (ret != PKGMGR_R_OK) {
1484                 g_variant_unref(result);
1485                 return ret;
1486         }
1487
1488         req_id = _get_request_id();
1489         __add_op_app_cbinfo(pc, req_id, req_key, app_event_cb, NULL);
1490         g_variant_unref(result);
1491         return ret;
1492 }
1493
1494 API int pkgmgr_client_activate_app(pkgmgr_client *pc, const char *appid, pkgmgr_app_handler app_event_cb)
1495 {
1496         return pkgmgr_client_usr_activate_app(pc, appid, app_event_cb, _getuid());
1497 }
1498
1499 API int pkgmgr_client_activate_global_app_for_uid(pkgmgr_client *pc,
1500                                  const char *appid, pkgmgr_app_handler app_event_cb, uid_t uid)
1501 {
1502         GVariant *result;
1503         int ret = PKGMGR_R_ECOMM;
1504         int req_id;
1505         char *req_key = NULL;
1506         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1507
1508         if (pc == NULL || appid == NULL) {
1509                 ERR("invalid parameter");
1510                 return PKGMGR_R_EINVAL;
1511         }
1512
1513         if (__change_op_cb_for_enable_disable(mpc, false) < 0) {
1514                 ERR("__change_op_cb_for_enable_disable failed");
1515                 return PKGMGR_R_ESYSTEM;
1516         }
1517
1518         ret = comm_client_request(mpc->info.request.cc, "enable_global_app_for_uid",
1519                         g_variant_new("(us)", uid, appid), &result);
1520         if (ret != PKGMGR_R_OK) {
1521                 ERR("request failed: %d", ret);
1522                 return ret;
1523         }
1524
1525         g_variant_get(result, "(i&s)", &ret, &req_key);
1526         if (req_key == NULL) {
1527                 g_variant_unref(result);
1528                 return PKGMGR_R_ECOMM;
1529         }
1530         if (ret != PKGMGR_R_OK) {
1531                 g_variant_unref(result);
1532                 return ret;
1533         }
1534
1535         req_id = _get_request_id();
1536         __add_op_app_cbinfo(pc, req_id, req_key, app_event_cb, NULL);
1537
1538         return ret;
1539 }
1540
1541 API int pkgmgr_client_usr_deactivate_app(pkgmgr_client *pc, const char *appid,
1542                 pkgmgr_app_handler app_event_cb, uid_t uid)
1543 {
1544         GVariant *result;
1545         int ret = PKGMGR_R_ECOMM;
1546         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1547         int req_id;
1548         char *req_key = NULL;
1549
1550         if (pc == NULL || appid == NULL) {
1551                 ERR("invalid parameter");
1552                 return PKGMGR_R_EINVAL;
1553         }
1554
1555         /* FIXME */
1556         if (__change_op_cb_for_enable_disable(mpc, true) < 0) {
1557                 ERR("__change_op_cb_for_enable_disable failed");
1558                 return PKGMGR_R_ESYSTEM;
1559         }
1560
1561         ret = comm_client_request(mpc->info.request.cc, "disable_app",
1562                         g_variant_new("(us)", uid, appid), &result);
1563         if (ret != PKGMGR_R_OK) {
1564                 ERR("request failed: %d", ret);
1565                 return ret;
1566         }
1567
1568         g_variant_get(result, "(i&s)", &ret, &req_key);
1569         if (req_key == NULL) {
1570                 g_variant_unref(result);
1571                 return PKGMGR_R_ECOMM;
1572         }
1573         if (ret != PKGMGR_R_OK) {
1574                 g_variant_unref(result);
1575                 return ret;
1576         }
1577
1578         req_id = _get_request_id();
1579         __add_op_app_cbinfo(pc, req_id, req_key, app_event_cb, NULL);
1580
1581         g_variant_unref(result);
1582         return ret;
1583 }
1584
1585 API int pkgmgr_client_deactivate_app(pkgmgr_client *pc, const char *appid, pkgmgr_app_handler app_event_cb)
1586 {
1587         return pkgmgr_client_usr_deactivate_app(pc, appid, app_event_cb, _getuid());
1588 }
1589
1590 API int pkgmgr_client_deactivate_global_app_for_uid(pkgmgr_client *pc,
1591                                  const char *appid, pkgmgr_app_handler app_event_cb, uid_t uid)
1592 {
1593         GVariant *result;
1594         int ret = PKGMGR_R_ECOMM;
1595         int req_id;
1596         char *req_key = NULL;
1597         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1598
1599         if (pc == NULL || appid == NULL) {
1600                 ERR("invalid parameter");
1601                 return PKGMGR_R_EINVAL;
1602         }
1603
1604         if (__change_op_cb_for_enable_disable(mpc, true) < 0) {
1605                 ERR("__change_op_cb_for_enable_disable failed");
1606                 return PKGMGR_R_ESYSTEM;
1607         }
1608
1609         ret = comm_client_request(mpc->info.request.cc, "disable_global_app_for_uid",
1610                         g_variant_new("(us)", uid, appid), &result);
1611         if (ret != PKGMGR_R_OK) {
1612                 ERR("request failed: %d", ret);
1613                 return ret;
1614         }
1615
1616         g_variant_get(result, "(i&s)", &ret, &req_key);
1617         if (req_key == NULL) {
1618                 g_variant_unref(result);
1619                 return PKGMGR_R_ECOMM;
1620         }
1621         if (ret != PKGMGR_R_OK) {
1622                 g_variant_unref(result);
1623                 return ret;
1624         }
1625
1626         req_id = _get_request_id();
1627         __add_op_app_cbinfo(pc, req_id, req_key, app_event_cb, NULL);
1628         return ret;
1629 }
1630
1631 API int pkgmgr_client_usr_clear_user_data(pkgmgr_client *pc,
1632                 const char *pkg_type, const char *appid, pkgmgr_mode mode,
1633                 uid_t uid)
1634 {
1635         GVariant *result;
1636         int ret = PKGMGR_R_ECOMM;
1637         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1638
1639         if (pc == NULL || pkg_type == NULL || appid == NULL) {
1640                 ERR("invalid parameter");
1641                 return PKGMGR_R_EINVAL;
1642         }
1643
1644         if (mpc->ctype != PC_REQUEST) {
1645                 ERR("mpc->ctype is not PC_REQUEST");
1646                 return PKGMGR_R_EINVAL;
1647         }
1648
1649         ret = comm_client_request(mpc->info.request.cc, "cleardata",
1650                         g_variant_new("(uss)", uid, pkg_type, appid), &result);
1651         if (ret == PKGMGR_R_OK) {
1652                 ERR("request failed: %d", ret);
1653                 return ret;
1654         }
1655
1656         g_variant_get(result, "(i)", &ret);
1657         g_variant_unref(result);
1658
1659         return ret;
1660 }
1661
1662 API int pkgmgr_client_clear_user_data(pkgmgr_client *pc, const char *pkg_type,
1663                 const char *appid, pkgmgr_mode mode)
1664 {
1665         return pkgmgr_client_usr_clear_user_data(pc, pkg_type, appid, mode,
1666                         _getuid());
1667 }
1668
1669 API int pkgmgr_client_set_status_type(pkgmgr_client *pc, int status_type)
1670 {
1671         int ret = -1;
1672
1673         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1674         retvm_if(status_type == PKGMGR_CLIENT_STATUS_ALL, PKGMGR_R_OK, "status_type is PKGMGR_CLIENT_STATUS_ALL");
1675         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1676
1677         /*  free listening head */
1678         listen_cb_info *tmp = NULL;
1679         listen_cb_info *prev = NULL;
1680         for (tmp = mpc->info.listening.lhead; tmp;) {
1681                 prev = tmp;
1682                 tmp = tmp->next;
1683                 free(prev);
1684         }
1685
1686         /* free dbus connection */
1687         ret = comm_client_free(mpc->info.listening.cc);
1688         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
1689
1690         /* Manage pc for seperated event */
1691         mpc->ctype = PC_LISTENING;
1692         mpc->status_type = status_type;
1693
1694         mpc->info.listening.cc = comm_client_new(PC_LISTENING);
1695         retvm_if(mpc->info.listening.cc == NULL, PKGMGR_R_EINVAL, "client creation failed");
1696
1697         ret = comm_client_set_status_callback(status_type, mpc->info.listening.cc, __status_callback, pc);
1698         retvm_if(ret < 0, PKGMGR_R_ECOMM, "comm_client_set_status_callback failed - %d", ret);
1699
1700         return PKGMGR_R_OK;
1701 }
1702
1703 API int pkgmgr_client_listen_status(pkgmgr_client *pc, pkgmgr_handler event_cb,
1704                                     void *data)
1705 {
1706         int req_id;
1707         /* Check for NULL value of pc */
1708         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1709         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1710
1711         /* 0. check input */
1712         retvm_if(mpc->ctype != PC_LISTENING, PKGMGR_R_EINVAL, "ctype is not PC_LISTENING");
1713         retvm_if(event_cb == NULL, PKGMGR_R_EINVAL, "event_cb is NULL");
1714
1715         /* 1. get id */
1716         req_id = _get_request_id();
1717
1718         /* 2. add callback info to pkgmgr_client */
1719         __add_stat_cbinfo(mpc, req_id, event_cb, data);
1720         return req_id;
1721 }
1722
1723 API int pkgmgr_client_listen_app_status(pkgmgr_client *pc, pkgmgr_app_handler event_cb,
1724                                     void *data)
1725 {
1726         int req_id;
1727         /* Check for NULL value of pc */
1728         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1729         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1730
1731         /* 0. check input */
1732         retvm_if(mpc->ctype != PC_LISTENING, PKGMGR_R_EINVAL, "ctype is not PC_LISTENING");
1733         retvm_if(event_cb == NULL, PKGMGR_R_EINVAL, "event_cb is NULL");
1734
1735         /* 1. get id */
1736         req_id = _get_request_id();
1737
1738         /* 2. add app callback info to pkgmgr_client */
1739         __add_app_stat_cbinfo(mpc, req_id, event_cb, data);
1740         return req_id;
1741 }
1742
1743 API int pkgmgr_client_remove_listen_status(pkgmgr_client *pc)
1744 {
1745         int ret = -1;
1746
1747         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1748         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1749
1750         ret = __remove_stat_cbinfo(mpc);
1751         if (ret != 0) {
1752                 ERR("failed to remove status callback");
1753                 return PKGMGR_R_ERROR;
1754         }
1755
1756         return PKGMGR_R_OK;
1757 }
1758
1759 API int pkgmgr_client_broadcast_status(pkgmgr_client *pc, const char *pkg_type,
1760                                        const char *pkgid, const char *key,
1761                                        const char *val)
1762 {
1763         /* client cannot broadcast signal */
1764         return PKGMGR_R_OK;
1765 }
1766
1767 API int pkgmgr_client_request_service(pkgmgr_request_service_type service_type, int service_mode,
1768                                   pkgmgr_client *pc, const char *pkg_type, const char *pkgid,
1769                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1770 {
1771         return pkgmgr_client_usr_request_service(service_type, service_mode, pc, pkg_type, pkgid, _getuid(), custom_info, event_cb, data);
1772 }
1773
1774 API int pkgmgr_client_usr_request_service(pkgmgr_request_service_type service_type, int service_mode,
1775                                   pkgmgr_client *pc, const char *pkg_type, const char *pkgid, uid_t uid,
1776                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1777 {
1778         int ret = 0;
1779
1780         /* Check for NULL value of service type */
1781         retvm_if(service_type > PM_REQUEST_MAX, PKGMGR_R_EINVAL, "service type is not defined\n");
1782         retvm_if(service_type < 0, PKGMGR_R_EINVAL, "service type is error\n");
1783
1784         switch (service_type) {
1785         case PM_REQUEST_MOVE:
1786                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1787                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1788                 tryvm_if((service_mode < PM_MOVE_TO_INTERNAL) || (service_mode > PM_MOVE_TO_SDCARD), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1789
1790                 ret = __move_pkg_process(pc, pkgid, pkg_type, uid, (pkgmgr_move_type)service_mode, event_cb, data);
1791                 break;
1792
1793         case PM_REQUEST_GET_SIZE:
1794                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1795                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1796                 tryvm_if((service_mode < PM_GET_TOTAL_SIZE) || (service_mode >= PM_GET_MAX), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1797
1798                 ret = __get_size_process(pc, pkgid, uid, (pkgmgr_getsize_type)service_mode, event_cb, data);
1799                 break;
1800
1801         case PM_REQUEST_KILL_APP:
1802         case PM_REQUEST_CHECK_APP:
1803                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1804                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1805
1806                 ret = __check_app_process(service_type, pc, pkgid, uid, data);
1807                 if (ret < 0)
1808                         ERR("__check_app_process fail \n");
1809                 else
1810                         ret = PKGMGR_R_OK;
1811
1812                 break;
1813
1814         default:
1815                 ERR("Wrong Request\n");
1816                 ret = -1;
1817                 break;
1818         }
1819
1820 catch:
1821
1822         return ret;
1823 }
1824
1825
1826 API int pkgmgr_client_usr_request_size_info(uid_t uid)
1827 {
1828         int ret = 0;
1829         pkgmgr_client *pc = NULL;
1830
1831         pc = pkgmgr_client_new(PC_REQUEST);
1832         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "request pc is null\n");
1833
1834         ret = __request_size_info(pc, uid);
1835         if (ret < 0)
1836                 ERR("__request_size_info fail \n");
1837
1838         pkgmgr_client_free(pc);
1839         return ret;
1840 }
1841
1842 API int pkgmgr_client_request_size_info(void) /* get all package size (data, total) */
1843 {
1844         return pkgmgr_client_usr_request_size_info(_getuid());
1845 }
1846
1847 API int pkgmgr_client_usr_clear_cache_dir(const char *pkgid, uid_t uid)
1848 {
1849         GVariant *result;
1850         int ret = PKGMGR_R_ECOMM;
1851         pkgmgr_client_t *pc;
1852
1853         if (pkgid == NULL) {
1854                 ERR("invalid parameter");
1855                 return PKGMGR_R_EINVAL;
1856         }
1857
1858         pc = pkgmgr_client_new(PC_REQUEST);
1859         if (pc == NULL) {
1860                 ERR("out of memory");
1861                 return PKGMGR_R_ESYSTEM;
1862         }
1863
1864         ret = comm_client_request(pc->info.request.cc, "clearcache",
1865                         g_variant_new("(us)", uid, pkgid), &result);
1866         if (ret != PKGMGR_R_OK) {
1867                 ERR("request failed: %d", ret);
1868                 return ret;
1869         }
1870
1871         g_variant_get(result, "(i)", &ret);
1872         g_variant_unref(result);
1873
1874         return ret;
1875 }
1876
1877 API int pkgmgr_client_clear_cache_dir(const char *pkgid)
1878 {
1879         return pkgmgr_client_usr_clear_cache_dir(pkgid, _getuid());
1880 }
1881
1882 API int pkgmgr_client_clear_usr_all_cache_dir(uid_t uid)
1883 {
1884         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, uid);
1885 }
1886
1887 API int pkgmgr_client_clear_all_cache_dir(void)
1888 {
1889         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, _getuid());
1890 }
1891
1892 API int pkgmgr_client_get_size(pkgmgr_client *pc, const char *pkgid,
1893                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1894                 void *data)
1895 {
1896         return pkgmgr_client_usr_get_size(pc, pkgid, get_type, event_cb, data,
1897                         _getuid());
1898 }
1899
1900 API int pkgmgr_client_usr_get_size(pkgmgr_client *pc, const char *pkgid,
1901                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1902                 void *data, uid_t uid)
1903 {
1904         GVariant *result;
1905         int ret = PKGMGR_R_ECOMM;
1906         char *req_key = NULL;
1907         int req_id;
1908         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1909
1910         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1911                 ERR("invalid parameter");
1912                 return PKGMGR_R_EINVAL;
1913         }
1914
1915         if (mpc->ctype != PC_REQUEST) {
1916                 ERR("mpc->ctype is not PC_REQUEST");
1917                 return PKGMGR_R_EINVAL;
1918         }
1919
1920         /* FIXME */
1921         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1922                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1923         else
1924                 get_type = PM_GET_PKG_SIZE_INFO;
1925
1926         ret = comm_client_request(mpc->info.request.cc, "getsize",
1927                         g_variant_new("(usi)", uid, pkgid, get_type), &result);
1928         if (ret != PKGMGR_R_OK) {
1929                 ERR("request failed: %d", ret);
1930                 return ret;
1931         }
1932
1933         g_variant_get(result, "(i&s)", &ret, &req_key);
1934         if (req_key == NULL) {
1935                 g_variant_unref(result);
1936                 return PKGMGR_R_ECOMM;
1937         }
1938         if (ret != PKGMGR_R_OK) {
1939                 g_variant_unref(result);
1940                 return ret;
1941         }
1942
1943         req_id = _get_request_id();
1944         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1945
1946         g_variant_unref(result);
1947
1948         return PKGMGR_R_OK;
1949 }
1950
1951 API int pkgmgr_client_usr_get_package_size_info(pkgmgr_client *pc,
1952                 const char *pkgid, pkgmgr_pkg_size_info_receive_cb event_cb,
1953                 void *user_data, uid_t uid)
1954 {
1955         GVariant *result;
1956         int ret = PKGMGR_R_ECOMM;
1957         char *req_key = NULL;
1958         int req_id;
1959         int get_type;
1960         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1961
1962         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1963                 ERR("invalid parameter");
1964                 return PKGMGR_R_EINVAL;
1965         }
1966
1967         if (mpc->ctype != PC_REQUEST) {
1968                 ERR("mpc->ctype is not PC_REQUEST");
1969                 return PKGMGR_R_EINVAL;
1970         }
1971
1972         /* FIXME */
1973         if (__change_op_cb_for_getsize(mpc) < 0) {
1974                 ERR("__change_op_cb_for_getsize failed");
1975                 return PKGMGR_R_ESYSTEM;
1976         }
1977
1978         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1979                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1980         else
1981                 get_type = PM_GET_PKG_SIZE_INFO;
1982
1983         ret = comm_client_request(mpc->info.request.cc, "getsize",
1984                         g_variant_new("(usi)", uid, pkgid, get_type), &result);
1985         if (ret != PKGMGR_R_OK) {
1986                 ERR("request failed: %d", ret);
1987                 return ret;
1988         }
1989
1990         g_variant_get(result, "(i&s)", &ret, &req_key);
1991         if (req_key == NULL) {
1992                 g_variant_unref(result);
1993                 return PKGMGR_R_ECOMM;
1994         }
1995         if (ret != PKGMGR_R_OK) {
1996                 g_variant_unref(result);
1997                 return ret;
1998         }
1999
2000         req_id = _get_request_id();
2001         __add_op_cbinfo(mpc, req_id, req_key, __get_pkg_size_info_cb, event_cb,
2002                         user_data);
2003
2004         g_variant_unref(result);
2005
2006         return PKGMGR_R_OK;
2007 }
2008
2009 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)
2010 {
2011         return pkgmgr_client_usr_get_package_size_info(pc, pkgid, event_cb, user_data, _getuid());
2012 }
2013
2014 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)
2015 {       /* total package size info */
2016         return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, uid);
2017 }
2018
2019 API int pkgmgr_client_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb event_cb, void *user_data)
2020 {
2021         return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, _getuid());
2022 }
2023
2024 API int pkgmgr_client_generate_license_request(pkgmgr_client *pc,
2025                 const char *resp_data, char **req_data, char **license_url)
2026 {
2027         GVariant *result;
2028         int ret;
2029         char *data;
2030         char *url;
2031         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2032
2033         if (pc == NULL || resp_data == NULL || req_data == NULL ||
2034                         license_url == NULL) {
2035                 ERR("invalid parameter");
2036                 return PKGMGR_R_EINVAL;
2037         }
2038
2039         if (mpc->ctype != PC_REQUEST) {
2040                 ERR("mpc->ctype is not PC_REQUEST");
2041                 return PKGMGR_R_EINVAL;
2042         }
2043
2044         ret = comm_client_request(mpc->info.request.cc,
2045                         "generate_license_request",
2046                         g_variant_new("(s)", resp_data), &result);
2047         if (ret != PKGMGR_R_OK) {
2048                 ERR("request failed: %d", ret);
2049                 return ret;
2050         }
2051
2052         g_variant_get(result, "(i&s&s)", &ret, &data, &url);
2053         if (ret != PKGMGR_R_OK) {
2054                 ERR("generate_license_request failed: %d", ret);
2055                 g_variant_unref(result);
2056                 return ret;
2057         }
2058
2059         *req_data = strdup(data);
2060         *license_url = strdup(url);
2061
2062         g_variant_unref(result);
2063
2064         return PKGMGR_R_OK;
2065 }
2066
2067 API int pkgmgr_client_register_license(pkgmgr_client *pc, const char *resp_data)
2068 {
2069         GVariant *result;
2070         int ret;
2071         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2072
2073         if (pc == NULL || resp_data == NULL) {
2074                 ERR("invalid parameter");
2075                 return PKGMGR_R_EINVAL;
2076         }
2077
2078         if (mpc->ctype != PC_REQUEST) {
2079                 ERR("mpc->ctype is not PC_REQUEST");
2080                 return PKGMGR_R_EINVAL;
2081         }
2082
2083         ret = comm_client_request(mpc->info.request.cc,
2084                         "register_license", g_variant_new("(s)", resp_data),
2085                         &result);
2086         if (ret != PKGMGR_R_OK) {
2087                 ERR("request failed: %d", ret);
2088                 return ret;
2089         }
2090
2091         g_variant_get(result, "(i)", &ret);
2092         g_variant_unref(result);
2093         if (ret != PKGMGR_R_OK) {
2094                 ERR("register license failed: %d", ret);
2095                 return ret;
2096         }
2097
2098         return PKGMGR_R_OK;
2099 }
2100
2101 API int pkgmgr_client_decrypt_package(pkgmgr_client *pc,
2102                 const char *drm_file_path, const char *decrypted_file_path)
2103 {
2104         GVariant *result;
2105         int ret;
2106         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2107
2108         if (pc == NULL || drm_file_path == NULL ||
2109                         decrypted_file_path == NULL) {
2110                 ERR("invalid parameter");
2111                 return PKGMGR_R_EINVAL;
2112         }
2113
2114         if (mpc->ctype != PC_REQUEST) {
2115                 ERR("mpc->ctype is not PC_REQUEST");
2116                 return PKGMGR_R_EINVAL;
2117         }
2118
2119         ret = comm_client_request(mpc->info.request.cc,
2120                         "decrypt_package",
2121                         g_variant_new("(ss)", drm_file_path,
2122                                 decrypted_file_path),
2123                         &result);
2124         if (ret != PKGMGR_R_OK) {
2125                 ERR("request failed: %d", ret);
2126                 return ret;
2127         }
2128
2129         g_variant_get(result, "(i)", &ret);
2130         g_variant_unref(result);
2131         if (ret != PKGMGR_R_OK) {
2132                 ERR("decrypt_package failed: %d", ret);
2133                 return ret;
2134         }
2135
2136         return PKGMGR_R_OK;
2137 }
2138
2139 API int pkgmgr_client_enable_splash_screen(pkgmgr_client *pc, const char *appid)
2140 {
2141         return pkgmgr_client_usr_enable_splash_screen(pc, appid, _getuid());
2142 }
2143
2144 API int pkgmgr_client_usr_enable_splash_screen(pkgmgr_client *pc,
2145                 const char *appid, uid_t uid)
2146 {
2147         int ret;
2148         GVariant *result;
2149         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2150
2151         if (pc == NULL || appid == NULL) {
2152                 ERR("Invalid parameter");
2153                 return PKGMGR_R_EINVAL;
2154         }
2155
2156         ret = __change_op_cb_for_enable_disable_splash_screen(mpc, true);
2157         if (ret < 0) {
2158                 ERR("__change_op_cb_for_enable_disable_splash_screen failed");
2159                 return PKGMGR_R_ESYSTEM;
2160         }
2161
2162         ret = comm_client_request(mpc->info.request.cc,
2163                         "enable_app_splash_screen",
2164                         g_variant_new("(us)", uid, appid), &result);
2165         if (ret != PKGMGR_R_OK) {
2166                 ERR("request failed: %d", ret);
2167                 return ret;
2168         }
2169
2170         g_variant_get(result, "(i)", &ret);
2171         if (ret != PKGMGR_R_OK) {
2172                 g_variant_unref(result);
2173                 return ret;
2174         }
2175
2176         g_variant_unref(result);
2177
2178         return ret;
2179 }
2180
2181 API int pkgmgr_client_disable_splash_screen(pkgmgr_client *pc,
2182                 const char *appid)
2183 {
2184         return pkgmgr_client_usr_disable_splash_screen(pc, appid,
2185                         _getuid());
2186 }
2187
2188 API int pkgmgr_client_usr_disable_splash_screen(pkgmgr_client *pc,
2189                 const char *appid, uid_t uid)
2190 {
2191         int ret;
2192         GVariant *result;
2193         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2194
2195         if (pc == NULL || appid == NULL) {
2196                 ERR("Invalid parameter");
2197                 return PKGMGR_R_EINVAL;
2198         }
2199
2200         ret = __change_op_cb_for_enable_disable_splash_screen(mpc, false);
2201         if (ret < 0) {
2202                 ERR("__change_op_cb_for_enable_disable_splash_screen failed");
2203                 return ret;
2204         }
2205
2206         ret = comm_client_request(mpc->info.request.cc,
2207                         "disable_app_splash_screen",
2208                         g_variant_new("(us)", uid, appid), &result);
2209         if (ret != PKGMGR_R_OK) {
2210                 ERR("request failed: %d", ret);
2211                 return ret;
2212         }
2213
2214         g_variant_get(result, "(i)", &ret);
2215         if (ret != PKGMGR_R_OK) {
2216                 g_variant_unref(result);
2217                 return ret;
2218         }
2219
2220         g_variant_unref(result);
2221
2222         return ret;
2223 }
2224
2225 static int __set_pkg_restriction_mode(pkgmgr_client *pc, const char *pkgid, int mode, uid_t uid)
2226 {
2227         GVariant *result;
2228         int ret = PKGMGR_R_ECOMM;
2229         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2230
2231         if (pc == NULL || pkgid == NULL || strlen(pkgid) == 0 || mode <= 0) {
2232                 ERR("invalid parameter");
2233                 return PKGMGR_R_EINVAL;
2234         }
2235
2236         ret = comm_client_request(mpc->info.request.cc, "set_restriction_mode",
2237                         g_variant_new("(usi)", uid, pkgid, mode), &result);
2238         if (ret != PKGMGR_R_OK) {
2239                 ERR("request failed: %d", ret);
2240                 return ret;
2241         }
2242
2243         g_variant_get(result, "(i)", &ret);
2244         g_variant_unref(result);
2245
2246         return ret;
2247 }
2248
2249 API int pkgmgr_client_usr_set_pkg_restriction_mode(pkgmgr_client *pc, const char *pkgid, int mode, uid_t uid)
2250 {
2251         return __set_pkg_restriction_mode(pc, pkgid, mode, uid);
2252 }
2253
2254 API int pkgmgr_client_set_pkg_restriction_mode(pkgmgr_client *pc, const char *pkgid, int mode)
2255 {
2256         return pkgmgr_client_usr_set_pkg_restriction_mode(pc, pkgid, mode, _getuid());
2257 }
2258
2259 static int __unset_pkg_restriction_mode(pkgmgr_client *pc, const char *pkgid, int mode, uid_t uid)
2260 {
2261         GVariant *result;
2262         int ret = PKGMGR_R_ECOMM;
2263         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2264
2265         if (pc == NULL || pkgid == NULL || strlen(pkgid) == 0 || mode <= 0) {
2266                 ERR("invalid parameter");
2267                 return PKGMGR_R_EINVAL;
2268         }
2269
2270         ret = comm_client_request(mpc->info.request.cc,
2271                         "unset_restriction_mode",
2272                         g_variant_new("(usi)", uid, pkgid, mode), &result);
2273         if (ret != PKGMGR_R_OK) {
2274                 ERR("request failed: %d", ret);
2275                 return ret;
2276         }
2277
2278         g_variant_get(result, "(i)", &ret);
2279         g_variant_unref(result);
2280
2281         return ret;
2282
2283 }
2284
2285 API int pkgmgr_client_usr_unset_pkg_restriction_mode(pkgmgr_client *pc, const char *pkgid, int mode, uid_t uid)
2286 {
2287         return __unset_pkg_restriction_mode(pc, pkgid, mode, uid);
2288 }
2289
2290 API int pkgmgr_client_unset_pkg_restriction_mode(pkgmgr_client *pc, const char *pkgid, int mode)
2291 {
2292         return pkgmgr_client_usr_unset_pkg_restriction_mode(pc, pkgid, mode, _getuid());
2293 }
2294
2295 static int __get_pkg_restriction_mode(pkgmgr_client *pc, const char *pkgid, int *mode, uid_t uid)
2296 {
2297         GVariant *result;
2298         int ret = PKGMGR_R_ECOMM;
2299         gint m;
2300         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2301
2302         if (pc == NULL || pkgid == NULL || strlen(pkgid) == 0) {
2303                 ERR("invalid parameter");
2304                 return PKGMGR_R_EINVAL;
2305         }
2306
2307         ret = comm_client_request(mpc->info.request.cc,
2308                         "get_restriction_mode",
2309                         g_variant_new("(us)", uid, pkgid), &result);
2310         if (ret != PKGMGR_R_OK) {
2311                 ERR("request failed: %d", ret);
2312                 return ret;
2313         }
2314
2315         g_variant_get(result, "(ii)", &m, &ret);
2316         g_variant_unref(result);
2317         if (ret != PKGMGR_R_OK)
2318                 return ret;
2319
2320         *mode = m;
2321
2322         return PKGMGR_R_OK;
2323 }
2324
2325 API int pkgmgr_client_usr_get_pkg_restriction_mode(pkgmgr_client *pc, const char *pkgid, int *mode, uid_t uid)
2326 {
2327         return __get_pkg_restriction_mode(pc, pkgid, mode, uid);
2328 }
2329
2330 API int pkgmgr_client_get_pkg_restriction_mode(pkgmgr_client *pc, const char *pkgid, int *mode)
2331 {
2332         return pkgmgr_client_usr_get_pkg_restriction_mode(pc, pkgid, mode, _getuid());
2333 }
2334
2335 API int pkgmgr_client_usr_set_restriction_mode(pkgmgr_client *pc, int mode,
2336                 uid_t uid)
2337 {
2338         GVariant *result;
2339         int ret = PKGMGR_R_ECOMM;
2340         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2341
2342         if (pc == NULL) {
2343                 ERR("invalid parameter");
2344                 return PKGMGR_R_EINVAL;
2345         }
2346
2347         ret = comm_client_request(mpc->info.request.cc, "set_restriction_mode",
2348                         g_variant_new("(usi)", uid, "", mode), &result);
2349         if (ret != PKGMGR_R_OK) {
2350                 ERR("request failed: %d", ret);
2351                 return ret;
2352         }
2353
2354         g_variant_get(result, "(i)", &ret);
2355         g_variant_unref(result);
2356
2357         return ret;
2358 }
2359
2360 API int pkgmgr_client_set_restriction_mode(pkgmgr_client *pc, int mode)
2361 {
2362         return pkgmgr_client_usr_set_restriction_mode(pc, mode, _getuid());
2363 }
2364
2365 API int pkgmgr_client_usr_unset_restriction_mode(pkgmgr_client *pc, int mode,
2366                 uid_t uid)
2367 {
2368         GVariant *result;
2369         int ret = PKGMGR_R_ECOMM;
2370         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2371
2372         if (pc == NULL) {
2373                 ERR("invalid parameter");
2374                 return PKGMGR_R_EINVAL;
2375         }
2376
2377         ret = comm_client_request(mpc->info.request.cc,
2378                         "unset_restriction_mode",
2379                         g_variant_new("(usi)", uid, "", mode), &result);
2380         if (ret != PKGMGR_R_OK) {
2381                 ERR("request failed: %d", ret);
2382                 return ret;
2383         }
2384
2385         g_variant_get(result, "(i)", &ret);
2386         g_variant_unref(result);
2387
2388         return ret;
2389 }
2390
2391 API int pkgmgr_client_unset_restriction_mode(pkgmgr_client *pc, int mode)
2392 {
2393         return pkgmgr_client_usr_unset_restriction_mode(pc, mode, _getuid());
2394 }
2395
2396 API int pkgmgr_client_usr_get_restriction_mode(pkgmgr_client *pc,
2397                 int *mode, uid_t uid)
2398 {
2399         GVariant *result;
2400         int ret = PKGMGR_R_ECOMM;
2401         gint m;
2402         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2403
2404         if (pc == NULL) {
2405                 ERR("invalid parameter");
2406                 return PKGMGR_R_EINVAL;
2407         }
2408
2409         ret = comm_client_request(mpc->info.request.cc,
2410                         "get_restriction_mode",
2411                         g_variant_new("(us)", uid, ""), &result);
2412         if (ret != PKGMGR_R_OK) {
2413                 ERR("request failed: %d", ret);
2414                 return ret;
2415         }
2416
2417         g_variant_get(result, "(ii)", &m, &ret);
2418         g_variant_unref(result);
2419         if (ret != PKGMGR_R_OK)
2420                 return ret;
2421
2422         *mode = m;
2423
2424         return PKGMGR_R_OK;
2425 }
2426
2427 API int pkgmgr_client_get_restriction_mode(pkgmgr_client *pc,
2428                 int *mode)
2429 {
2430         return pkgmgr_client_usr_get_restriction_mode(pc, mode, _getuid());
2431 }