Fix a memory leak
[platform/core/api/package-manager.git] / src / package_manager.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include <glib.h>
20 #include <unistd.h>
21
22 #include <package-manager.h>
23 #include <pkgmgr_installer.h>
24 #include <pkgmgr-info.h>
25 #include <tzplatform_config.h>
26
27 #include "package_manager.h"
28 #include "package_manager_internal.h"
29
30 static GHashTable *__cb_table = NULL;
31
32 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
33 typedef struct _event_info {
34         int req_id;
35         package_manager_event_type_e event_type;
36         package_manager_event_state_e event_state;
37         struct _event_info *next;
38 } event_info;
39
40 struct package_manager_s {
41         int handle_id;
42         client_type ctype;
43         pkgmgr_client *pc;
44         pkgmgr_mode mode;
45         event_info *head;
46         package_manager_event_cb event_cb;
47         void *user_data;
48 };
49
50 struct package_manager_request_s {
51         int handle_id;
52         client_type ctype;
53         pkgmgr_client *pc;
54         const char *pkg_type;
55         const char *pkg_path;
56         const char *pkg_name;
57         const char *tep_path;
58         pkgmgr_mode mode;
59         event_info *head;
60         package_manager_request_event_cb event_cb;
61         bool tep_move;
62         void *user_data;
63 };
64
65 typedef struct package_size_info {
66         long long data_size;
67         long long cache_size;
68         long long app_size;
69
70         long long external_data_size;
71         long long external_cache_size;
72         long long external_app_size;
73 } package_size_info_t;
74
75 struct package_manager_filter_s {
76         pkgmgrinfo_pkginfo_filter_h pkgmgrinfo_pkginfo_filter;
77 };
78
79 static int package_manager_request_new_id()
80 {
81         static int request_handle_id = 0;
82         return request_handle_id++;
83 }
84
85 static int package_manager_new_id()
86 {
87         static int manager_handle_id = 0;
88         return manager_handle_id++;
89 }
90
91 API int package_manager_request_create(package_manager_request_h *request)
92 {
93         struct package_manager_request_s *package_manager_request;
94
95         if (request == NULL) {
96                 return
97                     package_manager_error
98                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
99                      NULL);
100         }
101
102         package_manager_request =
103             calloc(1, sizeof(struct package_manager_request_s));
104         if (package_manager_request == NULL) {
105                 return
106                     package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
107                                           __FUNCTION__,
108                                           "failed to create a package_manager handle");
109         }
110
111         package_manager_request->ctype = PC_REQUEST;
112         package_manager_request->pc = pkgmgr_client_new(PC_REQUEST);
113         if (package_manager_request->pc == NULL) {
114                 free(package_manager_request);
115                 return
116                     package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
117                                           __FUNCTION__,
118                                           "failed to create a package_manager client");
119         }
120
121         package_manager_request->handle_id = package_manager_request_new_id();
122
123         *request = package_manager_request;
124
125         return PACKAGE_MANAGER_ERROR_NONE;
126 }
127
128 static int package_manager_client_validate_handle(package_manager_request_h
129                                                  request)
130 {
131         if (request == NULL || request->pc == NULL)
132                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
133
134         return PACKAGE_MANAGER_ERROR_NONE;
135 }
136
137 API int package_manager_request_destroy(package_manager_request_h request)
138 {
139         if (package_manager_client_validate_handle(request)) {
140                 return
141                     package_manager_error
142                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
143                      NULL);
144         }
145
146         pkgmgr_client_free(request->pc);
147         request->pc = NULL;
148         free(request->tep_path);
149         free(request);
150
151         return PACKAGE_MANAGER_ERROR_NONE;
152 }
153
154 API int package_manager_request_set_event_cb(package_manager_request_h request,
155                                          package_manager_request_event_cb
156                                          callback, void *user_data)
157 {
158
159         int retval;
160         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
161         if (retval != PACKAGE_MANAGER_ERROR_NONE)
162                 return retval;
163
164         if (package_manager_client_validate_handle(request)) {
165                 return
166                     package_manager_error
167                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
168                      NULL);
169         }
170
171         request->event_cb = callback;
172         request->user_data = user_data;
173
174         return PACKAGE_MANAGER_ERROR_NONE;
175 }
176
177 API int package_manager_request_unset_event_cb(package_manager_request_h request)
178 {
179         if (package_manager_client_validate_handle(request))
180                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
181
182         request->event_cb = NULL;
183         request->user_data = NULL;
184
185         return PACKAGE_MANAGER_ERROR_NONE;
186 }
187
188 API int package_manager_request_set_type(package_manager_request_h request,
189                                      const char *pkg_type)
190 {
191         if (package_manager_client_validate_handle(request)) {
192                 return
193                     package_manager_error
194                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
195                      NULL);
196         }
197
198         request->pkg_type = pkg_type;
199
200         return PACKAGE_MANAGER_ERROR_NONE;
201 }
202
203 API int package_manager_request_set_mode(package_manager_request_h request,
204                                      package_manager_request_mode_e mode)
205 {
206         if (package_manager_client_validate_handle(request)) {
207                 return
208                     package_manager_error
209                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
210                      NULL);
211         }
212
213         if (mode == PACKAGE_MANAGER_REQUEST_MODE_QUIET)
214                 request->mode = PM_QUIET;
215         else
216                 request->mode = PM_DEFAULT;
217
218         return PACKAGE_MANAGER_ERROR_NONE;
219 }
220
221 API int package_manager_request_set_tep(package_manager_request_h request,
222                                      const char *tep_path)
223 {
224         int retval = 0;
225
226         if (package_manager_client_validate_handle(request) || tep_path == NULL) {
227                 return
228                         package_manager_error
229                         (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
230                          NULL);
231         }
232
233         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
234         if (retval != PACKAGE_MANAGER_ERROR_NONE)
235                 return retval;
236
237         if (request->tep_path)
238                 free((void *)request->tep_path);
239
240         request->tep_path = strdup(tep_path);
241         request->tep_move = true;
242
243         if (request->tep_path == NULL)
244                 return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
245
246         return PACKAGE_MANAGER_ERROR_NONE;
247 }
248
249 static int package_manager_get_event_type(const char *key,
250                                           package_manager_event_type_e *
251                                           event_type)
252 {
253         if (key == NULL)
254                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
255
256         if (strcasecmp(key, PKGMGR_INSTALLER_INSTALL_EVENT_STR) == 0)
257                 *event_type = PACKAGE_MANAGER_EVENT_TYPE_INSTALL;
258         else if (strcasecmp(key, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR) == 0)
259                 *event_type = PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL;
260         else if (strcasecmp(key, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
261                 *event_type = PACKAGE_MANAGER_EVENT_TYPE_UPDATE;
262         else
263                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
264
265         return PACKAGE_MANAGER_ERROR_NONE;
266 }
267
268 static int __add_event_info(event_info **head, int req_id,
269                             package_manager_event_type_e event_type,
270                             package_manager_event_state_e event_state)
271 {
272         event_info *evt_info;
273         event_info *current;
274         event_info *prev;
275
276         evt_info = (event_info *) calloc(1, sizeof(event_info));
277         if (evt_info == NULL) {
278                 _LOGD("calloc failed");
279                 return -1;
280         }
281         evt_info->req_id = req_id;
282         evt_info->event_type = event_type;
283         evt_info->next = NULL;
284
285         if (*head == NULL)
286                 *head = evt_info;
287         else {
288                 current = prev = *head;
289                 while (current) {
290                         prev = current;
291                         current = current->next;
292                 }
293
294                 prev->next = evt_info;
295         }
296
297         return 0;
298 }
299
300 static int __find_event_info(event_info **head, int req_id,
301                              package_manager_event_type_e *event_type,
302                              package_manager_event_state_e *event_state)
303 {
304         event_info *tmp;
305
306         tmp = *head;
307
308         if (tmp == NULL) {
309                 _LOGE("tmp is NULL");
310                 return -1;
311         }
312
313         _LOGD("tmp->req_id %d, event_type %d", tmp->req_id, event_type);
314
315         while (tmp) {
316                 if (tmp->req_id == req_id) {
317                         *event_type = tmp->event_type;
318                         return 0;
319                 }
320                 tmp = tmp->next;
321         }
322         return -1;
323 }
324
325 static int __update_event_info(event_info **head, int req_id,
326                                package_manager_event_type_e event_type,
327                                package_manager_event_state_e event_state)
328 {
329         package_manager_event_type_e evt_type;
330         package_manager_event_state_e evt_state;
331         event_info *tmp;
332
333         if (__find_event_info(head, req_id, &evt_type, &evt_state) != 0)
334                 __add_event_info(head, req_id, event_type, event_state);
335         else {
336                 tmp = *head;
337
338                 if (tmp == NULL) {
339                         _LOGE("tmp is NULL");
340                         return -1;
341                 }
342
343                 while (tmp) {
344                         if (tmp->req_id == req_id) {
345                                 tmp->event_type = event_type;
346                                 return 0;
347                         }
348                         tmp = tmp->next;
349                 }
350         }
351
352         return -1;
353 }
354
355 /*
356 static int __remove_event_info(event_info **head request, int req_id)
357 {
358         event_info *current;
359         event_info *tmp;
360
361         if (* == NULL)
362                 return -1;
363
364         current = *head;
365         while (current) {
366                 if (current->next) {
367                         if (current->next->req_id == req_id) {
368                                 tmp = current->next;
369                                 current->next = current->next->next;
370                                 free(tmp);
371                                 return 0;
372                         }
373                 }
374                 tmp = tmp->next;
375         }
376
377         return -1;
378 }
379 */
380
381 static int request_event_handler(uid_t target_uid, int req_id, const char *pkg_type,
382                                  const char *pkg_name, const char *key,
383                                  const char *val, const void *pmsg, void *data)
384 {
385         int ret = -1;
386         package_manager_event_type_e event_type = -1;
387         package_manager_event_state_e event_state = -1;
388
389         _LOGD("request_event_handler is called");
390
391         package_manager_request_h request = data;
392
393         if (strcasecmp(key, "start") == 0) {
394                 ret = package_manager_get_event_type(val, &event_type);
395                 if (ret != PACKAGE_MANAGER_ERROR_NONE)
396                         return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
397
398                 __add_event_info(&(request->head), req_id, event_type,
399                                  PACKAGE_MANAGER_EVENT_STATE_STARTED);
400
401                 if (request->event_cb)
402                         request->event_cb(req_id, pkg_type, pkg_name,
403                                           event_type,
404                                           PACKAGE_MANAGER_EVENT_STATE_STARTED,
405                                           0, PACKAGE_MANAGER_ERROR_NONE, request->user_data);
406
407         } else if (strcasecmp(key, "install_percent") == 0
408                    || strcasecmp(key, "progress_percent") == 0) {
409                 if (__find_event_info
410                     (&(request->head), req_id, &event_type,
411                      &event_state) == 0) {
412                         __update_event_info(&(request->head), req_id,
413                                             event_type,
414                                             PACKAGE_MANAGER_EVENT_STATE_PROCESSING);
415                         if (request->event_cb)
416                                 request->event_cb(req_id, pkg_type, pkg_name,
417                                                   event_type,
418                                                   PACKAGE_MANAGER_EVENT_STATE_PROCESSING,
419                                                   atoi(val),
420                                                   PACKAGE_MANAGER_ERROR_NONE,
421                                                   request->user_data);
422                 }
423
424         } else if (strcasecmp(key, "error") == 0) {
425                 if (strcasecmp(key, "0") != 0) {
426                         if (__find_event_info
427                             (&(request->head), req_id, &event_type,
428                              &event_state) == 0) {
429                                 __update_event_info(&(request->head), req_id,
430                                                     event_type,
431                                                     PACKAGE_MANAGER_EVENT_STATE_FAILED);
432                         }
433
434                         if (request->event_cb)
435                                 request->event_cb(req_id, pkg_type,
436                                                   pkg_name, event_type,
437                                                   PACKAGE_MANAGER_EVENT_STATE_FAILED,
438                                                   0,
439                                                   PACKAGE_MANAGER_ERROR_NONE,
440                                                   request->user_data);
441
442                 }
443         } else if (strcasecmp(key, "end") == 0) {
444                 if (__find_event_info
445                     (&(request->head), req_id, &event_type,
446                      &event_state) == 0) {
447                         if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) {
448                                 if (request->event_cb)
449                                         request->event_cb(req_id, pkg_type,
450                                                           pkg_name, event_type,
451                                                           PACKAGE_MANAGER_EVENT_STATE_COMPLETED,
452                                                           100,
453                                                           PACKAGE_MANAGER_ERROR_NONE,
454                                                           request->user_data);
455                         }
456                 } else {
457                         if (strcasecmp(key, "ok") != 0)
458                                 if (request->event_cb)
459                                         request->event_cb(req_id, pkg_type,
460                                                           pkg_name, event_type,
461                                                           PACKAGE_MANAGER_EVENT_STATE_FAILED,
462                                                           0,
463                                                           PACKAGE_MANAGER_ERROR_NONE,
464                                                           request->user_data);
465                 }
466         }
467
468         return PACKAGE_MANAGER_ERROR_NONE;
469 }
470
471 API int package_manager_request_install(package_manager_request_h request,
472                                     const char *path, int *id)
473 {
474
475         int retval;
476         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
477         if (retval != PACKAGE_MANAGER_ERROR_NONE)
478                 return retval;
479
480         if (package_manager_client_validate_handle(request))
481                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
482
483         if (path == NULL)
484                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
485
486         int request_id = 0;
487         request->pkg_path = path;
488         uid_t uid = getuid();
489         if (uid != GLOBAL_USER)
490                 request_id = pkgmgr_client_usr_install(request->pc, request->pkg_type, NULL,
491                                                         request->pkg_path, NULL,
492                                                         request->mode, request_event_handler,
493                                                         request,
494                                                         uid);
495         else
496                 request_id = pkgmgr_client_install(request->pc, request->pkg_type, NULL,
497                                                         request->pkg_path, NULL,
498                                                         request->mode, request_event_handler,
499                                                         request);
500
501         if (request_id == PKGMGR_R_EINVAL)
502                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
503         else if (request_id == PKGMGR_R_ENOPKG)
504                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
505         else if (request_id == PKGMGR_R_ENOMEM)
506                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
507         else if (request_id == PKGMGR_R_EIO)
508                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
509         else if (request_id == PKGMGR_R_EPRIV)
510                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
511         else if (request_id == PKGMGR_R_ESYSTEM || request_id == PKGMGR_R_ECOMM || request_id == PKGMGR_R_ERROR)
512                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
513
514         *id = request_id;
515
516         return PACKAGE_MANAGER_ERROR_NONE;
517 }
518
519 API int package_manager_request_uninstall(package_manager_request_h request,
520                                       const char *name, int *id)
521 {
522
523         int retval;
524         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
525         if (retval != PACKAGE_MANAGER_ERROR_NONE)
526                 return retval;
527
528         if (package_manager_client_validate_handle(request))
529                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
530
531         if (name == NULL)
532                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
533
534         int request_id = 0;
535         request->pkg_name = name;
536         uid_t uid = getuid();
537         if (uid != GLOBAL_USER)
538                 request_id = pkgmgr_client_usr_uninstall(request->pc, request->pkg_type,
539                                                                 request->pkg_name, request->mode,
540                                                                 request_event_handler, request, uid);
541         else
542                 request_id = pkgmgr_client_uninstall(request->pc, request->pkg_type,
543                                                                 request->pkg_name, request->mode,
544                                                                 request_event_handler, request);
545
546         if (request_id == PKGMGR_R_EINVAL)
547                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
548         else if (request_id == PKGMGR_R_ENOPKG)
549                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
550         else if (request_id == PKGMGR_R_ENOMEM)
551                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
552         else if (request_id == PKGMGR_R_EIO)
553                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
554         else if (request_id == PKGMGR_R_EPRIV)
555                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
556         else if (request_id == PKGMGR_R_ESYSTEM || request_id == PKGMGR_R_ECOMM || request_id == PKGMGR_R_ERROR)
557                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
558
559         *id = request_id;
560
561         return PACKAGE_MANAGER_ERROR_NONE;
562 }
563
564 API int package_manager_request_move(package_manager_request_h request,
565                                     const char *name, package_manager_move_type_e move_type)
566 {
567
568         int retval;
569         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
570         if (retval != PACKAGE_MANAGER_ERROR_NONE)
571                 return retval;
572
573         if (package_manager_client_validate_handle(request))
574                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
575
576         if (name == NULL)
577                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
578
579         int ret = 0;
580         request->pkg_name = name;
581         uid_t uid = getuid();
582         if (uid != GLOBAL_USER)
583                 ret = pkgmgr_client_usr_request_service(PM_REQUEST_MOVE, move_type,
584                                 request->pc, request->pkg_type, request->pkg_name,
585                                 uid, NULL, request_event_handler, NULL);
586         else
587                 ret = pkgmgr_client_request_service(PM_REQUEST_MOVE, move_type,
588                                 request->pc, request->pkg_type, request->pkg_name,
589                                 NULL, request_event_handler, NULL);
590
591         if (ret == PKGMGR_R_EINVAL)
592                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
593         else if (ret == PKGMGR_R_ENOPKG)
594                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
595         else if (ret == PKGMGR_R_ENOMEM)
596                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
597         else if (ret == PKGMGR_R_EIO)
598                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
599         else if (ret == PKGMGR_R_EPRIV)
600                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
601         else if (ret == PKGMGR_R_ESYSTEM || ret == PKGMGR_R_ECOMM || ret == PKGMGR_R_ERROR)
602                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
603
604         return PACKAGE_MANAGER_ERROR_NONE;
605 }
606
607 API int package_manager_create(package_manager_h *manager)
608 {
609
610         int retval;
611         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
612         if (retval != PACKAGE_MANAGER_ERROR_NONE)
613                 return retval;
614
615         struct package_manager_s *package_manager = NULL;
616
617         if (manager == NULL) {
618                 return
619                     package_manager_error
620                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
621                      NULL);
622         }
623
624         package_manager = calloc(1, sizeof(struct package_manager_s));
625         if (package_manager == NULL) {
626                 return
627                     package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
628                                           __FUNCTION__,
629                                           "failed to create a package_manager handle");
630         }
631
632         package_manager->ctype = PC_LISTENING;
633         package_manager->pc = pkgmgr_client_new(PC_LISTENING);
634         if (package_manager->pc == NULL) {
635                 free(package_manager);
636                 return
637                     package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
638                                           __FUNCTION__,
639                                           "failed to create a package_manager client");
640         }
641
642         package_manager->handle_id = package_manager_new_id();
643
644         *manager = package_manager;
645
646         return PACKAGE_MANAGER_ERROR_NONE;
647 }
648
649 static int package_manager_validate_handle(package_manager_h manager)
650 {
651         if (manager == NULL || manager->pc == NULL)
652                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
653
654         return PACKAGE_MANAGER_ERROR_NONE;
655 }
656
657 API int package_manager_destroy(package_manager_h manager)
658 {
659         if (package_manager_validate_handle(manager)) {
660                 return
661                     package_manager_error
662                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
663                      NULL);
664         }
665
666         pkgmgr_client_free(manager->pc);
667         manager->pc = NULL;
668         free(manager);
669
670         return PACKAGE_MANAGER_ERROR_NONE;
671 }
672
673 static int __add_event(event_info **head, int req_id,
674                             package_manager_event_type_e event_type,
675                             package_manager_event_state_e event_state)
676 {
677         event_info *evt_info;
678
679         evt_info = (event_info *) calloc(1, sizeof(event_info));
680         if (evt_info == NULL) {
681                 _LOGD("calloc failed");
682                 return -1;
683         }
684         evt_info->req_id = req_id;
685         evt_info->event_type = event_type;
686         evt_info->next = NULL;
687
688         *head = evt_info;
689
690         return 0;
691 }
692
693 static int __find_event(event_info **head, int req_id,
694                              package_manager_event_type_e *event_type,
695                              package_manager_event_state_e *event_state)
696 {
697         event_info *tmp;
698
699         tmp = *head;
700
701         if (tmp == NULL) {
702                 _LOGE("tmp is NULL");
703                 return -1;
704         }
705
706         *event_type = tmp->event_type;
707         return 0;
708 }
709
710 static int __update_event(event_info **head, int req_id,
711                                package_manager_event_type_e event_type,
712                                package_manager_event_state_e event_state)
713 {
714         package_manager_event_type_e evt_type;
715         package_manager_event_state_e evt_state;
716         event_info *tmp;
717
718         if (__find_event_info(head, req_id, &evt_type, &evt_state) != 0)
719                 __add_event_info(head, req_id, event_type, event_state);
720         else {
721                 tmp = *head;
722
723                 if (tmp == NULL) {
724                         _LOGE("tmp is NULL");
725                         return -1;
726                 }
727
728                 tmp->event_type = event_type;
729                 return 0;
730         }
731
732         return -1;
733 }
734
735 /* App Event Listening Policy:
736  * +----------------+------------+---------------+------------------+
737  * |Listener \ Type |Global Event|My User's Event|Other user's Event|
738  * +----------------+------------+---------------+------------------+
739  * |User Process App|   Grant    |     Grant     |      Deny        |
740  * +----------------+------------+---------------+------------------+
741  * |Platform module |   Grant    |     Grant     |      Grant       |
742  * +----------------+------------+---------------+------------------+
743  * UID assignment policy:
744  * https://wiki.tizen.org/wiki/Security/User_and_group_ID_assignment_policy
745  */
746 #define REGULAR_USER 5000
747 static int __validate_event_signal(uid_t target_uid)
748 {
749         uid_t self = getuid();
750
751         if (self == target_uid)
752                 return 0;
753
754         if (self < REGULAR_USER)
755                 return 0;
756
757         return -1;
758 }
759
760 static int global_event_handler(uid_t target_uid, int req_id, const char *pkg_type,
761                                 const char *pkg_name, const char *key,
762                                 const char *val, const void *pmsg, void *data)
763 {
764         int ret = -1;
765         package_manager_event_type_e event_type = -1;
766         package_manager_event_state_e event_state = -1;
767         uid_t uid = target_uid;
768
769         _LOGD("global_event_handler is called");
770
771         package_manager_h manager = data;
772
773         if (target_uid == GLOBAL_USER)
774                 uid = getuid();
775
776         if (__validate_event_signal(uid))
777                 return PACKAGE_MANAGER_ERROR_NONE;
778
779         if (strcasecmp(key, "start") == 0) {
780                 ret = package_manager_get_event_type(val, &event_type);
781                 if (ret != PACKAGE_MANAGER_ERROR_NONE)
782                         return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
783
784                 __add_event(&(manager->head), req_id, event_type,
785                                  PACKAGE_MANAGER_EVENT_STATE_STARTED);
786
787                 if (manager->event_cb && getuid() == uid)
788                         manager->event_cb(pkg_type, pkg_name,
789                                           event_type,
790                                           PACKAGE_MANAGER_EVENT_STATE_STARTED,
791                                           0, PACKAGE_MANAGER_ERROR_NONE, manager->user_data);
792         } else if (strcasecmp(key, "install_percent") == 0
793                    || strcasecmp(key, "progress_percent") == 0) {
794                 if (__find_event
795                     (&(manager->head), req_id, &event_type,
796                      &event_state) == 0) {
797                         __update_event(&(manager->head), req_id,
798                                             event_type,
799                                             PACKAGE_MANAGER_EVENT_STATE_PROCESSING);
800                         if (manager->event_cb && getuid() == uid)
801                                 manager->event_cb(pkg_type, pkg_name,
802                                                   event_type,
803                                                   PACKAGE_MANAGER_EVENT_STATE_PROCESSING,
804                                                   atoi(val),
805                                                   PACKAGE_MANAGER_ERROR_NONE,
806                                                   manager->user_data);
807                 }
808
809         } else if (strcasecmp(key, "error") == 0) {
810                 if (strcasecmp(key, "0") != 0) {
811                         if (__find_event
812                             (&(manager->head), req_id, &event_type,
813                              &event_state) == 0) {
814                                 __update_event(&(manager->head), req_id,
815                                                     event_type,
816                                                     PACKAGE_MANAGER_EVENT_STATE_FAILED);
817                         }
818
819                         if (manager->event_cb && getuid() == uid)
820                                 manager->event_cb(pkg_type,
821                                                   pkg_name, event_type,
822                                                   PACKAGE_MANAGER_EVENT_STATE_FAILED,
823                                                   0,
824                                                   PACKAGE_MANAGER_ERROR_NONE,
825                                                   manager->user_data);
826                 }
827         } else if (strcasecmp(key, "end") == 0) {
828                 if (__find_event
829                     (&(manager->head), req_id, &event_type,
830                      &event_state) == 0) {
831                         if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) {
832                                 if (manager->event_cb && getuid() == uid)
833                                         manager->event_cb(pkg_type,
834                                                           pkg_name, event_type,
835                                                           PACKAGE_MANAGER_EVENT_STATE_COMPLETED,
836                                                           100,
837                                                           PACKAGE_MANAGER_ERROR_NONE,
838                                                           manager->user_data);
839                         }
840                 } else {
841                         if (strcasecmp(key, "ok") != 0) {
842                                 if (manager->event_cb && getuid() == uid)
843                                         manager->event_cb(pkg_type,
844                                                           pkg_name, event_type,
845                                                           PACKAGE_MANAGER_EVENT_STATE_FAILED,
846                                                           0,
847                                                           PACKAGE_MANAGER_ERROR_NONE,
848                                                           manager->user_data);
849                         }
850                 }
851         }
852
853         return PACKAGE_MANAGER_ERROR_NONE;
854 }
855
856 API int package_manager_set_event_status(package_manager_h manager, int status_type)
857 {
858         int retval;
859
860         if (manager == NULL)
861                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
862
863         retval = pkgmgrinfo_client_set_status_type(manager->pc, status_type);
864
865         if (retval < 0)
866                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
867
868         return PACKAGE_MANAGER_ERROR_NONE;
869 }
870
871 API int package_manager_set_event_cb(package_manager_h manager,
872                                  package_manager_event_cb callback,
873                                  void *user_data)
874 {
875
876         int retval;
877         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
878         if (retval != PACKAGE_MANAGER_ERROR_NONE)
879                 return retval;
880
881         if (package_manager_validate_handle(manager)) {
882                 return
883                     package_manager_error
884                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
885                      NULL);
886         }
887
888         manager->event_cb = callback;
889         manager->user_data = user_data;
890
891         pkgmgr_client_listen_status(manager->pc, global_event_handler, manager);
892
893         return PACKAGE_MANAGER_ERROR_NONE;
894 }
895
896 API int package_manager_unset_event_cb(package_manager_h manager)
897 {
898         if (manager == NULL) {
899                 return
900                     package_manager_error
901                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
902                      NULL);
903         }
904
905         int retval;
906         manager->event_cb = NULL;
907         manager->user_data = NULL;
908
909         retval = pkgmgr_client_remove_listen_status(manager->pc);
910         if (retval == PKGMGR_R_EINVAL)
911                 return
912                          package_manager_error
913                          (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
914                           NULL);
915         else if (retval == PKGMGR_R_ERROR)
916                 return
917                          package_manager_error
918                          (PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__,
919                           NULL);
920
921         return PACKAGE_MANAGER_ERROR_NONE;
922 }
923
924 API int package_manager_get_package_id_by_app_id(const char *app_id, char **package_id)
925 {
926         pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo;
927         int retval;
928         char *pkg_id = NULL;
929         char *pkg_id_dup = NULL;
930
931         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
932         if (retval != PACKAGE_MANAGER_ERROR_NONE)
933                 return retval;
934
935         if (app_id == NULL || package_id == NULL)
936                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
937
938         uid_t uid = getuid();
939         if (uid != GLOBAL_USER) {
940                 if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
941                         return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
942         } else {
943                 if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
944                         return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
945         }
946         retval = pkgmgrinfo_appinfo_get_pkgname(pkgmgrinfo_appinfo, &pkg_id);
947         if (retval != PMINFO_R_OK)
948                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
949
950         pkg_id_dup = strdup(pkg_id);
951         if (pkg_id_dup == NULL) {
952                 pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
953                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
954         }
955
956         *package_id = pkg_id_dup;
957
958         pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
959
960         return PACKAGE_MANAGER_ERROR_NONE;
961 }
962
963 API int package_manager_get_package_info(const char *package_id, package_info_h *package_info)
964 {
965         int retval;
966         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
967         if (retval != PACKAGE_MANAGER_ERROR_NONE)
968                 return retval;
969
970         retval = package_info_get_package_info(package_id, package_info);
971
972         if (retval != PACKAGE_MANAGER_ERROR_NONE)
973                 return package_manager_error(retval, __FUNCTION__, NULL);
974         else
975                 return PACKAGE_MANAGER_ERROR_NONE;
976 }
977
978 API int package_manager_foreach_package_info(package_manager_package_info_cb callback,
979                                         void *user_data)
980 {
981
982         int retval;
983         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
984         if (retval != PACKAGE_MANAGER_ERROR_NONE)
985                 return retval;
986
987         retval = package_info_foreach_package_info(callback, user_data);
988
989         if (retval != PACKAGE_MANAGER_ERROR_NONE)
990                 return package_manager_error(retval, __FUNCTION__, NULL);
991         else
992                 return PACKAGE_MANAGER_ERROR_NONE;
993 }
994
995 API int package_manager_compare_package_cert_info(const char *lhs_package_id, const char *rhs_package_id, package_manager_compare_result_type_e *compare_result)
996 {
997         pkgmgrinfo_cert_compare_result_type_e result;
998         uid_t uid = getuid();
999
1000         if (lhs_package_id == NULL || rhs_package_id == NULL || compare_result == NULL)
1001                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1002         if (uid != GLOBAL_USER) {
1003                 if (pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(lhs_package_id, rhs_package_id, uid, &result) != PKGMGR_R_OK)
1004                         return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1005         } else {
1006                 if (pkgmgrinfo_pkginfo_compare_pkg_cert_info(lhs_package_id, rhs_package_id, &result) != PKGMGR_R_OK)
1007                         return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1008         }
1009         *compare_result = (package_manager_compare_result_type_e)result;
1010
1011         return PACKAGE_MANAGER_ERROR_NONE;
1012 }
1013
1014 API int package_manager_compare_app_cert_info(const char *lhs_app_id, const char *rhs_app_id, package_manager_compare_result_type_e *compare_result)
1015 {
1016         pkgmgrinfo_cert_compare_result_type_e result;
1017         uid_t uid = getuid();
1018
1019         if (lhs_app_id == NULL || rhs_app_id == NULL || compare_result == NULL)
1020                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1021         if (uid != GLOBAL_USER) {
1022                 if (pkgmgrinfo_pkginfo_compare_usr_app_cert_info(lhs_app_id, rhs_app_id, uid, &result) != PKGMGR_R_OK)
1023                         return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1024         } else {
1025                 if (pkgmgrinfo_pkginfo_compare_app_cert_info(lhs_app_id, rhs_app_id, &result) != PKGMGR_R_OK)
1026                         return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1027         }
1028
1029         *compare_result = (package_manager_compare_result_type_e)result;
1030
1031         return PACKAGE_MANAGER_ERROR_NONE;
1032 }
1033
1034 API int package_manager_is_preload_package_by_app_id(const char *app_id, bool *preload)
1035 {
1036
1037         int retval;
1038         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1039         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1040                 return retval;
1041
1042         pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo = NULL;
1043         pkgmgrinfo_pkginfo_h pkgmgrinfo_pkginfo = NULL;
1044
1045         char *pkg_id = NULL;
1046         bool is_preload = 0;
1047         uid_t uid = getuid();
1048         if (uid != GLOBAL_USER) {
1049                 if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
1050                         return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1051         } else {
1052                 if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
1053                         return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1054         }
1055
1056         retval = pkgmgrinfo_appinfo_get_pkgname(pkgmgrinfo_appinfo, &pkg_id);
1057         if (retval != PMINFO_R_OK) {
1058                 pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1059                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1060         }
1061         if (uid != GLOBAL_USER) {
1062                 if (pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id, uid, &pkgmgrinfo_pkginfo) != PMINFO_R_OK) {
1063                         pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1064                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo);
1065                         return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1066                 }
1067         } else {
1068                 if (pkgmgrinfo_pkginfo_get_pkginfo(pkg_id, &pkgmgrinfo_pkginfo) != PMINFO_R_OK) {
1069                         pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1070                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo);
1071                         return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1072                 }
1073         }
1074         if (pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo, &is_preload) != PMINFO_R_OK) {
1075                 pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1076                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo);
1077                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1078         }
1079
1080         if (is_preload)
1081                 *preload = 1;
1082         else
1083                 *preload = 0;
1084
1085         pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1086         pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo);
1087
1088         return PACKAGE_MANAGER_ERROR_NONE;
1089 }
1090
1091 API int package_manager_get_permission_type(const char *app_id, package_manager_permission_type_e *permission_type)
1092 {
1093
1094         int retval;
1095         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1096         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1097                 return retval;
1098
1099         pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo = NULL;
1100         pkgmgrinfo_permission_type permission = 0;
1101         uid_t uid = getuid();
1102         if (uid != GLOBAL_USER) {
1103                 if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
1104                         return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1105         } else {
1106                 if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
1107                         return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1108         }
1109         retval = pkgmgrinfo_appinfo_get_permission_type(pkgmgrinfo_appinfo, &permission);
1110         if (retval != PMINFO_R_OK)
1111                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1112
1113         if (permission == PMINFO_PERMISSION_NORMAL)
1114                 *permission_type = PACKAGE_MANAGER_PERMISSION_NORMAL;
1115         else if (permission == PMINFO_PERMISSION_SIGNATURE)
1116                 *permission_type = PACKAGE_MANAGER_PERMISSION_SIGNATURE;
1117         else if (permission == PMINFO_PERMISSION_PRIVILEGE)
1118                 *permission_type = PACKAGE_MANAGER_PERMISSION_PRIVILEGE;
1119         else
1120                 *permission_type = PACKAGE_MANAGER_PERMISSION_NORMAL;
1121
1122         pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1123         return PACKAGE_MANAGER_ERROR_NONE;
1124 }
1125
1126 API int package_manager_clear_cache_dir(const char *package_id)
1127 {
1128
1129         int retval;
1130         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_CACHE);
1131         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1132                 return retval;
1133
1134         int res = pkgmgr_client_usr_clear_cache_dir(package_id, getuid());
1135         if (res == PKGMGR_R_EINVAL) {
1136                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1137         } else if (res == PKGMGR_R_ENOPKG) {
1138                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1139         } else if (res == PKGMGR_R_ENOMEM) {
1140                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1141         } else if (res == PKGMGR_R_EIO) {
1142                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1143         } else if (res == PKGMGR_R_EPRIV) {
1144                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
1145         } else if (res == PKGMGR_R_ESYSTEM || res == PKGMGR_R_ECOMM || res == PKGMGR_R_ERROR) {
1146                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1147         } else if (res != PKGMGR_R_OK) {
1148                 _LOGE("Unexpected error");
1149                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1150         }
1151
1152         return PACKAGE_MANAGER_ERROR_NONE;
1153 }
1154
1155 API int package_manager_clear_all_cache_dir(void)
1156 {
1157
1158         int retval;
1159         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
1160         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1161                 return retval;
1162
1163         return package_manager_clear_cache_dir(PKG_CLEAR_ALL_CACHE);
1164 }
1165
1166 static void __free_client(gpointer data)
1167 {
1168         pkgmgr_client *pc = (pkgmgr_client *)data;
1169         pkgmgr_client_free(pc);
1170 }
1171
1172 static void __initialize_cb_table(void)
1173 {
1174         __cb_table = g_hash_table_new_full(g_int_hash, g_int_equal, __free_client, NULL);
1175 }
1176
1177 static void __result_cb(pkgmgr_client *pc, const char *pkgid, const pkg_size_info_t *result, void *user_data)
1178 {
1179         package_manager_size_info_receive_cb callback = g_hash_table_lookup(__cb_table, pc);
1180         if (callback == NULL) {
1181                 _LOGE("callback is null.");
1182                 g_hash_table_remove(__cb_table, pc);
1183                 return;
1184         }
1185
1186         package_size_info_t size_info;
1187         size_info.data_size  = result->data_size;
1188         size_info.cache_size = result->cache_size;
1189         size_info.app_size   = result->app_size;
1190         size_info.external_data_size  = result->ext_data_size;
1191         size_info.external_cache_size = result->ext_cache_size;
1192         size_info.external_app_size   = result->ext_app_size;
1193
1194         callback(pkgid, (package_size_info_h)&size_info, user_data);
1195
1196         g_hash_table_remove(__cb_table, pc);
1197 }
1198
1199 static void __total_result_cb(pkgmgr_client *pc, const pkg_size_info_t *result, void *user_data)
1200 {
1201         package_manager_total_size_info_receive_cb callback = g_hash_table_lookup(__cb_table, pc);
1202         if (callback == NULL) {
1203                 _LOGE("callback is null.");
1204                 g_hash_table_remove(__cb_table, pc);
1205                 return;
1206         }
1207
1208         package_size_info_t size_info;
1209         size_info.data_size  = result->data_size;
1210         size_info.cache_size = result->cache_size;
1211         size_info.app_size   = result->app_size;
1212         size_info.external_data_size  = result->ext_data_size;
1213         size_info.external_cache_size = result->ext_cache_size;
1214         size_info.external_app_size   = result->ext_app_size;
1215
1216         callback((package_size_info_h)&size_info, user_data);
1217
1218         g_hash_table_remove(__cb_table, pc);
1219 }
1220
1221 static int _get_pkg_size_info(const char *package_id, void *callback, void *user_data)
1222 {
1223         if (package_id == NULL || callback == NULL)
1224                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1225
1226         if (__cb_table == NULL)
1227                 __initialize_cb_table();
1228
1229         pkgmgr_client *pc = pkgmgr_client_new(PC_REQUEST);
1230         if (pc == NULL)
1231                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1232
1233         int res = 0;
1234         if (strcmp(package_id, PKG_SIZE_INFO_TOTAL) != 0)
1235                 res = pkgmgr_client_usr_get_package_size_info(pc, package_id, __result_cb, user_data, getuid());
1236         else
1237                 res = pkgmgr_client_usr_get_total_package_size_info(pc, __total_result_cb, user_data, getuid());
1238
1239         if (res == PKGMGR_R_EINVAL) {
1240                 pkgmgr_client_free(pc);
1241                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1242         } else if (res == PKGMGR_R_ENOPKG) {
1243                 pkgmgr_client_free(pc);
1244                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1245         } else if (res == PKGMGR_R_ENOMEM) {
1246                 pkgmgr_client_free(pc);
1247                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1248         } else if (res == PKGMGR_R_EIO) {
1249                 pkgmgr_client_free(pc);
1250                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1251         } else if (res == PKGMGR_R_EPRIV) {
1252                 pkgmgr_client_free(pc);
1253                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
1254         } else if (res == PKGMGR_R_ESYSTEM || res == PKGMGR_R_ECOMM || res == PKGMGR_R_ERROR) {
1255                 pkgmgr_client_free(pc);
1256                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1257         } else if (res != PKGMGR_R_OK) {
1258                 _LOGE("Unexpected error");
1259                 pkgmgr_client_free(pc);
1260                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1261         }
1262
1263         g_hash_table_insert(__cb_table, pc, callback);
1264
1265         _LOGD("Successful");
1266         return PACKAGE_MANAGER_ERROR_NONE;
1267 }
1268
1269 API int package_manager_get_package_size_info(const char *package_id, package_manager_size_info_receive_cb callback, void *user_data)
1270 {
1271         return _get_pkg_size_info(package_id, (void *)callback, user_data);
1272 }
1273
1274 API int package_manager_get_total_package_size_info(package_manager_total_size_info_receive_cb callback, void *user_data)
1275 {
1276         return _get_pkg_size_info(PKG_SIZE_INFO_TOTAL, (void *)callback, user_data);
1277 }
1278
1279 API int package_manager_filter_create(package_manager_filter_h *handle)
1280 {
1281         int retval;
1282         pkgmgrinfo_pkginfo_filter_h pkgmgr_filter = NULL;
1283
1284         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1285         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1286                 return retval;
1287
1288         if (handle == NULL) {
1289                 return
1290                     package_manager_error
1291                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
1292                      NULL);
1293         }
1294
1295         retval = pkgmgrinfo_pkginfo_filter_create(&pkgmgr_filter);
1296         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1297                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1298
1299         *handle = pkgmgr_filter;
1300
1301         return PACKAGE_MANAGER_ERROR_NONE;
1302 }
1303
1304 API int package_manager_filter_destroy(package_manager_filter_h handle)
1305 {
1306         int retval;
1307
1308         if (handle == NULL) {
1309                 return
1310                     package_manager_error
1311                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
1312                      NULL);
1313         }
1314
1315         retval = pkgmgrinfo_pkginfo_filter_destroy(handle);
1316         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1317                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1318
1319         return PACKAGE_MANAGER_ERROR_NONE;
1320 }
1321
1322 API int package_manager_filter_add_bool(package_manager_filter_h handle,
1323                 const char *property, const bool value)
1324 {
1325         int retval;
1326
1327         if ((handle == NULL) || (property == NULL)) {
1328                 return
1329                     package_manager_error
1330                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
1331                      NULL);
1332         }
1333
1334         retval = pkgmgrinfo_pkginfo_filter_add_bool(handle, property, value);
1335         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1336                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1337
1338         return PACKAGE_MANAGER_ERROR_NONE;
1339 }
1340
1341 API int package_manager_filter_count(package_manager_filter_h handle, int *count)
1342 {
1343
1344         int retval;
1345         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1346         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1347                 return retval;
1348
1349         if ((handle == NULL) || (count == NULL))
1350                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1351
1352         retval = pkgmgrinfo_pkginfo_filter_count(handle, count);
1353         if (retval < 0)
1354                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1355
1356         return PACKAGE_MANAGER_ERROR_NONE;
1357 }
1358
1359 API int package_manager_filter_foreach_package_info(package_manager_filter_h handle,
1360                 package_manager_package_info_cb callback, void *user_data)
1361 {
1362
1363         int retval;
1364         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1365         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1366                 return retval;
1367
1368         retval = package_info_filter_foreach_package_info(handle, callback, user_data);
1369
1370         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1371                 return package_manager_error(retval, __FUNCTION__, NULL);
1372         else
1373                 return PACKAGE_MANAGER_ERROR_NONE;
1374 }
1375
1376 API int package_size_info_get_data_size(package_size_info_h handle, long long *data_size)
1377 {
1378         if (handle == NULL)
1379                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1380
1381         package_size_info_t *size_info = (package_size_info_t *)handle;
1382
1383         *data_size = (long long)size_info->data_size;
1384         return PACKAGE_MANAGER_ERROR_NONE;
1385 }
1386
1387 API int package_size_info_get_cache_size(package_size_info_h handle, long long *cache_size)
1388 {
1389         if (handle == NULL)
1390                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1391
1392         package_size_info_t *size_info = (package_size_info_t *)handle;
1393
1394         *cache_size = size_info->cache_size;
1395         return PACKAGE_MANAGER_ERROR_NONE;
1396 }
1397
1398 API int package_size_info_get_app_size(package_size_info_h handle, long long *app_size)
1399 {
1400         if (handle == NULL)
1401                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1402
1403         package_size_info_t *size_info = (package_size_info_t *)handle;
1404         *app_size = size_info->app_size;
1405         return PACKAGE_MANAGER_ERROR_NONE;
1406 }
1407
1408 API int package_size_info_get_external_data_size(package_size_info_h handle, long long *ext_data_size)
1409 {
1410         if (handle == NULL)
1411                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
1412
1413         package_size_info_t *size_info = (package_size_info_t *)handle;
1414         *ext_data_size = size_info->external_data_size;
1415         return PACKAGE_MANAGER_ERROR_NONE;
1416 }
1417
1418 API int package_size_info_get_external_cache_size(package_size_info_h handle, long long *ext_cache_size)
1419 {
1420         if (handle == NULL)
1421                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1422
1423         package_size_info_t *size_info = (package_size_info_t *)handle;
1424         *ext_cache_size = size_info->external_cache_size;
1425         return PACKAGE_MANAGER_ERROR_NONE;
1426 }
1427
1428 API int package_size_info_get_external_app_size(package_size_info_h handle, long long *ext_app_size)
1429 {
1430         if (handle == NULL)
1431                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1432
1433         package_size_info_t *size_info = (package_size_info_t *)handle;
1434         *ext_app_size = size_info->external_app_size;
1435         return PACKAGE_MANAGER_ERROR_NONE;
1436 }