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