Merge "Add new api clearing user-data directories" into tizen
[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 static GHashTable *__request_cb_table = NULL;
32
33 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
34 typedef struct _event_info {
35         int req_id;
36         package_manager_event_type_e event_type;
37         package_manager_event_state_e event_state;
38         struct _event_info *next;
39 } event_info;
40
41 struct package_manager_s {
42         int handle_id;
43         pkgmgr_client_type ctype;
44         pkgmgr_client *pc;
45         pkgmgr_mode mode;
46         event_info *head;
47         package_manager_event_cb event_cb;
48         void *user_data;
49 };
50
51 struct package_manager_request_s {
52         int handle_id;
53         pkgmgr_client_type ctype;
54         pkgmgr_client *pc;
55         char *pkg_type;
56         pkgmgr_mode mode;
57         event_info *head;
58         package_manager_request_event_cb event_cb;
59         void *user_data;
60 };
61
62 struct package_manager_request_cb_info {
63         int req_id;
64         package_manager_request_event_cb callback;
65         void *user_data;
66 };
67
68 typedef struct package_size_info {
69         long long data_size;
70         long long cache_size;
71         long long app_size;
72
73         long long external_data_size;
74         long long external_cache_size;
75         long long external_app_size;
76 } package_size_info_t;
77
78 struct package_manager_filter_s {
79         pkgmgrinfo_pkginfo_filter_h pkgmgrinfo_pkginfo_filter;
80 };
81
82 static int package_manager_request_new_id()
83 {
84         static int request_handle_id = 0;
85         return request_handle_id++;
86 }
87
88 static int package_manager_new_id()
89 {
90         static int manager_handle_id = 0;
91         return manager_handle_id++;
92 }
93
94 static void __free_request_cb_info(gpointer data)
95 {
96         struct package_manager_request_cb_info *cb_info =
97                         (struct package_manager_request_cb_info *)data;
98
99         free(cb_info);
100         cb_info = NULL;
101
102         _LOGD("request callback info removed");
103 }
104
105 static void __initialize_request_cb_table(void)
106 {
107         __request_cb_table =
108                 g_hash_table_new_full(g_int_hash, g_int_equal, __free_request_cb_info, NULL);
109 }
110
111 static int __insert_request_cb_info(int req_id, package_manager_request_event_cb callback, void *user_data)
112 {
113         struct package_manager_request_cb_info *cb_info;
114
115         cb_info = calloc(1, sizeof(struct package_manager_request_cb_info));
116         if (cb_info == NULL)
117                 return -1;
118         cb_info->req_id = req_id;
119         cb_info->callback = callback;
120         cb_info->user_data = user_data;
121         g_hash_table_insert(__request_cb_table, &cb_info->req_id, cb_info);
122
123         return 0;
124 }
125
126 static void __clean_all_event_info(event_info *head)
127 {
128         event_info *current = head;
129         event_info *prev;
130
131         if (current == NULL)
132                 return;
133
134         while (current) {
135                 prev = current;
136                 current = current->next;
137                 free(prev);
138                 prev = NULL;
139         }
140 }
141
142 API int package_manager_request_create(package_manager_request_h *request)
143 {
144         struct package_manager_request_s *package_manager_request;
145
146         if (request == NULL) {
147                 return
148                     package_manager_error
149                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
150                      NULL);
151         }
152
153         package_manager_request =
154             calloc(1, sizeof(struct package_manager_request_s));
155         if (package_manager_request == NULL) {
156                 return
157                     package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
158                                           __FUNCTION__,
159                                           "failed to create a package_manager handle");
160         }
161
162         package_manager_request->ctype = PC_REQUEST;
163         package_manager_request->pc = pkgmgr_client_new(PC_REQUEST);
164         if (package_manager_request->pc == NULL) {
165                 free(package_manager_request);
166                 return
167                     package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
168                                           __FUNCTION__,
169                                           "failed to create a package_manager client");
170         }
171
172         package_manager_request->handle_id = package_manager_request_new_id();
173
174         *request = package_manager_request;
175
176         return PACKAGE_MANAGER_ERROR_NONE;
177 }
178
179 static int package_manager_client_validate_handle(package_manager_request_h
180                                                  request)
181 {
182         if (request == NULL || request->pc == NULL)
183                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
184
185         return PACKAGE_MANAGER_ERROR_NONE;
186 }
187
188 API int package_manager_request_destroy(package_manager_request_h request)
189 {
190         if (package_manager_client_validate_handle(request)) {
191                 return
192                     package_manager_error
193                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
194                      NULL);
195         }
196
197         pkgmgr_client_free(request->pc);
198         request->pc = NULL;
199         free(request->pkg_type);
200         __clean_all_event_info(request->head);
201         free(request);
202         g_hash_table_destroy(__request_cb_table);
203         __request_cb_table = NULL;
204
205         return PACKAGE_MANAGER_ERROR_NONE;
206 }
207
208 static int __reset_user_request_callback(package_manager_request_h request,
209                         package_manager_request_event_cb callback, void *user_data)
210 {
211         if (package_manager_client_validate_handle(request))
212                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
213
214         request->event_cb = callback;
215         request->user_data = user_data;
216
217         return PACKAGE_MANAGER_ERROR_NONE;
218 }
219
220 API int package_manager_request_set_event_cb(package_manager_request_h request,
221                                          package_manager_request_event_cb
222                                          callback, void *user_data)
223 {
224         int ret;
225
226         ret = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
227         if (ret != PACKAGE_MANAGER_ERROR_NONE)
228                 return ret;
229
230         return __reset_user_request_callback(request, callback, user_data);
231 }
232
233 API int package_manager_request_unset_event_cb(package_manager_request_h request)
234 {
235         if (package_manager_client_validate_handle(request))
236                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
237
238         request->event_cb = NULL;
239         request->user_data = NULL;
240
241         return PACKAGE_MANAGER_ERROR_NONE;
242 }
243
244 API int package_manager_request_set_type(package_manager_request_h request,
245                                      const char *pkg_type)
246 {
247         if (package_manager_client_validate_handle(request)) {
248                 return
249                     package_manager_error
250                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
251                      NULL);
252         }
253
254         request->pkg_type = strdup(pkg_type);
255
256         return PACKAGE_MANAGER_ERROR_NONE;
257 }
258
259 API int package_manager_request_set_mode(package_manager_request_h request,
260                                      package_manager_request_mode_e mode)
261 {
262         if (package_manager_client_validate_handle(request)) {
263                 return
264                     package_manager_error
265                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
266                      NULL);
267         }
268
269         /* request mode is not used anymore */
270
271         return PACKAGE_MANAGER_ERROR_NONE;
272 }
273
274 API int package_manager_request_set_tep(package_manager_request_h request,
275                                      const char *tep_path)
276 {
277         int retval = 0;
278
279         if (package_manager_client_validate_handle(request) || tep_path == NULL) {
280                 return
281                         package_manager_error
282                         (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
283                          NULL);
284         }
285
286         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
287         if (retval != PACKAGE_MANAGER_ERROR_NONE)
288                 return retval;
289
290         if (pkgmgr_client_set_tep_path(request->pc, tep_path, true))
291                 return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
292
293         return PACKAGE_MANAGER_ERROR_NONE;
294 }
295
296 static int package_manager_get_event_type(const char *key,
297                                           package_manager_event_type_e *
298                                           event_type)
299 {
300         if (key == NULL)
301                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
302
303         if (strcasecmp(key, PKGMGR_INSTALLER_INSTALL_EVENT_STR) == 0)
304                 *event_type = PACKAGE_MANAGER_EVENT_TYPE_INSTALL;
305         else if (strcasecmp(key, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR) == 0)
306                 *event_type = PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL;
307         else if (strcasecmp(key, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
308                 *event_type = PACKAGE_MANAGER_EVENT_TYPE_UPDATE;
309         else if (strcasecmp(key, PKGMGR_INSTALLER_MOVE_EVENT_STR) == 0)
310                 *event_type = PACKAGE_MANAGER_EVENT_TYPE_MOVE;
311         else if (strcasecmp(key, PKGMGR_INSTALLER_CLEAR_EVENT_STR) == 0)
312                 *event_type = PACKAGE_MANAGER_EVENT_TYPE_CLEAR;
313         else
314                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
315
316         return PACKAGE_MANAGER_ERROR_NONE;
317 }
318
319 static int __add_event_info(event_info **head, int req_id,
320                             package_manager_event_type_e event_type,
321                             package_manager_event_state_e event_state)
322 {
323         event_info *evt_info;
324         event_info *current;
325         event_info *prev;
326
327         evt_info = (event_info *) calloc(1, sizeof(event_info));
328         if (evt_info == NULL) {
329                 _LOGD("calloc failed");
330                 return -1;
331         }
332         evt_info->req_id = req_id;
333         evt_info->event_type = event_type;
334         evt_info->next = NULL;
335
336         if (*head == NULL)
337                 *head = evt_info;
338         else {
339                 current = prev = *head;
340                 while (current) {
341                         prev = current;
342                         current = current->next;
343                 }
344
345                 prev->next = evt_info;
346         }
347
348         return 0;
349 }
350
351 static int __find_event_info(event_info **head, int req_id,
352                              package_manager_event_type_e *event_type,
353                              package_manager_event_state_e *event_state)
354 {
355         event_info *tmp;
356
357         tmp = *head;
358
359         if (tmp == NULL) {
360                 _LOGE("tmp is NULL");
361                 return -1;
362         }
363
364         while (tmp) {
365                 if (tmp->req_id == req_id) {
366                         *event_type = tmp->event_type;
367                         return 0;
368                 }
369                 tmp = tmp->next;
370         }
371         return -1;
372 }
373
374 static int __update_event_info(event_info **head, int req_id,
375                                package_manager_event_type_e event_type,
376                                package_manager_event_state_e event_state)
377 {
378         package_manager_event_type_e evt_type;
379         package_manager_event_state_e evt_state;
380         event_info *tmp;
381
382         if (__find_event_info(head, req_id, &evt_type, &evt_state) != 0)
383                 __add_event_info(head, req_id, event_type, event_state);
384         else {
385                 tmp = *head;
386
387                 if (tmp == NULL) {
388                         _LOGE("tmp is NULL");
389                         return -1;
390                 }
391
392                 while (tmp) {
393                         if (tmp->req_id == req_id) {
394                                 tmp->event_type = event_type;
395                                 return 0;
396                         }
397                         tmp = tmp->next;
398                 }
399         }
400
401         return -1;
402 }
403
404 /*
405 static int __remove_event_info(event_info **head request, int req_id)
406 {
407         event_info *current;
408         event_info *tmp;
409
410         if (* == NULL)
411                 return -1;
412
413         current = *head;
414         while (current) {
415                 if (current->next) {
416                         if (current->next->req_id == req_id) {
417                                 tmp = current->next;
418                                 current->next = current->next->next;
419                                 free(tmp);
420                                 return 0;
421                         }
422                 }
423                 tmp = tmp->next;
424         }
425
426         return -1;
427 }
428 */
429
430 static int request_event_handler(uid_t target_uid, int req_id, const char *pkg_type,
431                                  const char *pkg_name, const char *key,
432                                  const char *val, const void *pmsg, void *data)
433 {
434         int ret = -1;
435         package_manager_event_type_e event_type = -1;
436         package_manager_event_state_e event_state = -1;
437
438         package_manager_request_h request = data;
439
440         if (strcasecmp(key, "start") == 0) {
441                 ret = package_manager_get_event_type(val, &event_type);
442                 if (ret != PACKAGE_MANAGER_ERROR_NONE)
443                         return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
444
445                 __add_event_info(&(request->head), req_id, event_type,
446                                  PACKAGE_MANAGER_EVENT_STATE_STARTED);
447
448                 if (request->event_cb)
449                         request->event_cb(req_id, pkg_type, pkg_name,
450                                           event_type,
451                                           PACKAGE_MANAGER_EVENT_STATE_STARTED,
452                                           0, PACKAGE_MANAGER_ERROR_NONE, request->user_data);
453
454         } else if (strcasecmp(key, "install_percent") == 0
455                    || strcasecmp(key, "progress_percent") == 0) {
456                 if (__find_event_info
457                     (&(request->head), req_id, &event_type,
458                      &event_state) == 0) {
459                         __update_event_info(&(request->head), req_id,
460                                             event_type,
461                                             PACKAGE_MANAGER_EVENT_STATE_PROCESSING);
462                         if (request->event_cb)
463                                 request->event_cb(req_id, pkg_type, pkg_name,
464                                                   event_type,
465                                                   PACKAGE_MANAGER_EVENT_STATE_PROCESSING,
466                                                   atoi(val),
467                                                   PACKAGE_MANAGER_ERROR_NONE,
468                                                   request->user_data);
469                 }
470
471         } else if (strcasecmp(key, "error") == 0) {
472                 if (strcasecmp(key, "0") != 0) {
473                         if (__find_event_info
474                             (&(request->head), req_id, &event_type,
475                              &event_state) == 0) {
476                                 __update_event_info(&(request->head), req_id,
477                                                     event_type,
478                                                     PACKAGE_MANAGER_EVENT_STATE_FAILED);
479                         }
480
481                         if (request->event_cb)
482                                 request->event_cb(req_id, pkg_type,
483                                                   pkg_name, event_type,
484                                                   PACKAGE_MANAGER_EVENT_STATE_FAILED,
485                                                   0,
486                                                   PACKAGE_MANAGER_ERROR_NONE,
487                                                   request->user_data);
488
489                 }
490         } else if (strcasecmp(key, "end") == 0) {
491                 if (__find_event_info
492                     (&(request->head), req_id, &event_type,
493                      &event_state) == 0) {
494                         if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) {
495                                 if (request->event_cb)
496                                         request->event_cb(req_id, pkg_type,
497                                                           pkg_name, event_type,
498                                                           PACKAGE_MANAGER_EVENT_STATE_COMPLETED,
499                                                           100,
500                                                           PACKAGE_MANAGER_ERROR_NONE,
501                                                           request->user_data);
502                         }
503                 } else {
504                         if (strcasecmp(key, "ok") != 0)
505                                 if (request->event_cb)
506                                         request->event_cb(req_id, pkg_type,
507                                                           pkg_name, event_type,
508                                                           PACKAGE_MANAGER_EVENT_STATE_FAILED,
509                                                           0,
510                                                           PACKAGE_MANAGER_ERROR_NONE,
511                                                           request->user_data);
512                 }
513         }
514
515         return PACKAGE_MANAGER_ERROR_NONE;
516 }
517
518 static int internal_request_callback(uid_t target_uid, int req_id, const char *pkg_type,
519                                 const char *pkg_name, const char *key,
520                                 const char *val, const void *pmsg, void *data)
521 {
522         int ret;
523         package_manager_event_type_e event_type = -1;
524         package_manager_event_state_e event_state = -1;
525         struct package_manager_request_cb_info *cb_info;
526         package_manager_request_event_cb event_cb;
527         void *user_data = NULL;
528
529         _LOGD("request callback called, req_id[%d]", req_id);
530
531         package_manager_request_h request = data;
532         cb_info = g_hash_table_lookup(__request_cb_table, &req_id);
533         if (!cb_info || (cb_info && !cb_info->callback)) {
534                 _LOGE("no callback info");
535                 return 0;
536         }
537
538         if (cb_info->req_id != req_id) {
539                 _LOGE("not matched request id");
540                 return 0;
541         }
542
543         event_cb = cb_info->callback;
544         user_data = cb_info->user_data;
545
546         if (strcasecmp(key, "start") == 0) {
547                 ret = package_manager_get_event_type(val, &event_type);
548                 if (ret != PACKAGE_MANAGER_ERROR_NONE)
549                         return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
550
551                 __add_event_info(&request->head, req_id, event_type,
552                                  PACKAGE_MANAGER_EVENT_STATE_STARTED);
553
554                 event_cb(req_id, pkg_type, pkg_name,
555                         event_type,
556                         PACKAGE_MANAGER_EVENT_STATE_STARTED,
557                         0, PACKAGE_MANAGER_ERROR_NONE, user_data);
558         } else if (strcasecmp(key, "install_percent") == 0) {
559                 if (__find_event_info(&request->head, req_id, &event_type,
560                                 &event_state) == 0) {
561                         __update_event_info(&request->head, req_id,
562                                         event_type,
563                                         PACKAGE_MANAGER_EVENT_STATE_PROCESSING);
564                         event_cb(req_id, pkg_type, pkg_name,
565                                 event_type,
566                                 PACKAGE_MANAGER_EVENT_STATE_PROCESSING,
567                                 atoi(val),
568                                 PACKAGE_MANAGER_ERROR_NONE,
569                                 user_data);
570                 }
571         } else if (strcasecmp(key, "error") == 0) {
572                 if (__find_event_info(&request->head, req_id, &event_type,
573                                 &event_state) == 0) {
574                         __update_event_info(&request->head, req_id,
575                                         event_type,
576                                         PACKAGE_MANAGER_EVENT_STATE_FAILED);
577                         event_cb(req_id, pkg_type,
578                                 pkg_name, event_type,
579                                 PACKAGE_MANAGER_EVENT_STATE_FAILED,
580                                 0,
581                                 PACKAGE_MANAGER_ERROR_NONE,
582                                 user_data);
583                 }
584         } else if (strcasecmp(key, "end") == 0) {
585                 if (__find_event_info(&request->head, req_id, &event_type,
586                                 &event_state) == 0) {
587                         if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) {
588                                 if (strcasecmp(val, "ok") == 0) {
589                                         event_cb(req_id, pkg_type,
590                                                 pkg_name, event_type,
591                                                 PACKAGE_MANAGER_EVENT_STATE_COMPLETED,
592                                                 100,
593                                                 PACKAGE_MANAGER_ERROR_NONE,
594                                                 user_data);
595                                 } else {
596                                         event_cb(req_id, pkg_type,
597                                                 pkg_name, event_type,
598                                                 PACKAGE_MANAGER_EVENT_STATE_FAILED,
599                                                 0,
600                                                 PACKAGE_MANAGER_ERROR_NONE,
601                                                 user_data);
602                                 }
603                         }
604                 } else {
605                         _LOGE("unexpected end event");
606                 }
607                 g_hash_table_remove(__request_cb_table, &req_id);
608         }
609
610         return 0;
611 }
612
613 static int __request_install(package_manager_request_h request,
614                 const char *path, pkgmgr_handler event_cb, int *id)
615 {
616         int retval;
617         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
618         if (retval != PACKAGE_MANAGER_ERROR_NONE)
619                 return retval;
620
621         if (package_manager_client_validate_handle(request))
622                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
623
624         if (path == NULL)
625                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
626
627         int request_id = 0;
628         request_id = pkgmgr_client_install(request->pc, request->pkg_type, NULL,
629                         path, NULL, request->mode, event_cb ? event_cb : request_event_handler, request);
630
631         if (request_id == PKGMGR_R_EINVAL)
632                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
633         else if (request_id == PKGMGR_R_ENOPKG)
634                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
635         else if (request_id == PKGMGR_R_ENOMEM)
636                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
637         else if (request_id == PKGMGR_R_EIO)
638                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
639         else if (request_id == PKGMGR_R_EPRIV)
640                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
641         else if (request_id == PKGMGR_R_ESYSTEM || request_id == PKGMGR_R_ECOMM || request_id == PKGMGR_R_ERROR)
642                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
643
644         if (id)
645                 *id = request_id;
646
647         return PACKAGE_MANAGER_ERROR_NONE;
648 }
649
650 static int __request_uninstall(package_manager_request_h request,
651                 const char *name, pkgmgr_handler event_cb, int *id)
652 {
653         int retval;
654         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
655         if (retval != PACKAGE_MANAGER_ERROR_NONE)
656                 return retval;
657
658         if (package_manager_client_validate_handle(request))
659                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
660
661         if (name == NULL)
662                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
663
664         int request_id = 0;
665         request_id = pkgmgr_client_uninstall(request->pc, request->pkg_type,
666                         name, request->mode, event_cb ? event_cb : request_event_handler, request);
667
668         if (request_id == PKGMGR_R_EINVAL)
669                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
670         else if (request_id == PKGMGR_R_ENOPKG)
671                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
672         else if (request_id == PKGMGR_R_ENOMEM)
673                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
674         else if (request_id == PKGMGR_R_EIO)
675                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
676         else if (request_id == PKGMGR_R_EPRIV)
677                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
678         else if (request_id == PKGMGR_R_ESYSTEM || request_id == PKGMGR_R_ECOMM || request_id == PKGMGR_R_ERROR)
679                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
680
681         if (id)
682                 *id = request_id;
683
684         return PACKAGE_MANAGER_ERROR_NONE;
685 }
686
687 static int __request_move(package_manager_request_h request,
688                 const char *name, package_manager_move_type_e move_type,
689                 pkgmgr_handler event_cb, int *id)
690 {
691         int retval;
692         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
693         if (retval != PACKAGE_MANAGER_ERROR_NONE)
694                 return retval;
695
696         if (package_manager_client_validate_handle(request))
697                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
698
699         if (name == NULL)
700                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
701
702         int request_id = 0;
703         request_id = pkgmgr_client_request_service(PM_REQUEST_MOVE, move_type,
704                         request->pc, request->pkg_type, name,
705                         NULL, event_cb ? event_cb : request_event_handler, request);
706
707         if (request_id == PKGMGR_R_EINVAL)
708                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
709         else if (request_id == PKGMGR_R_ENOPKG)
710                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
711         else if (request_id == PKGMGR_R_ENOMEM)
712                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
713         else if (request_id == PKGMGR_R_EIO)
714                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
715         else if (request_id == PKGMGR_R_EPRIV)
716                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
717         else if (request_id == PKGMGR_R_ESYSTEM || request_id == PKGMGR_R_ECOMM || request_id == PKGMGR_R_ERROR)
718                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
719
720         if (id)
721                 *id = request_id;
722
723         return PACKAGE_MANAGER_ERROR_NONE;
724 }
725
726 API int package_manager_request_install(package_manager_request_h request,
727                                 const char *path, int *id)
728 {
729         return __request_install(request, path, NULL, id);
730 }
731
732 API int package_manager_request_install_with_cb(package_manager_request_h request,
733                         const char *path, package_manager_request_event_cb callback,
734                         void *user_data, int *id)
735 {
736         int ret;
737         int req_id = 0;
738
739         if (__request_cb_table == NULL)
740                 __initialize_request_cb_table();
741
742         ret = __request_install(request, path, internal_request_callback, &req_id);
743
744         if (req_id > 0) {
745                 ret = __insert_request_cb_info(req_id, callback, user_data);
746                 if (ret < 0)
747                         return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
748                                         __FUNCTION__, "failed to create request cb info");
749                 if (id)
750                         *id = req_id;
751         }
752
753         return ret;
754 }
755
756 API int package_manager_request_uninstall(package_manager_request_h request,
757                 const char *name, int *id)
758 {
759         return __request_uninstall(request, name, NULL, id);
760 }
761
762 API int package_manager_request_uninstall_with_cb(package_manager_request_h request,
763                         const char *name, package_manager_request_event_cb callback,
764                         void *user_data, int *id)
765 {
766         int ret;
767         int req_id = 0;
768
769         if (__request_cb_table == NULL)
770                 __initialize_request_cb_table();
771
772         ret = __request_uninstall(request, name, internal_request_callback, &req_id);
773
774         if (req_id > 0) {
775                 ret = __insert_request_cb_info(req_id, callback, user_data);
776                 if (ret < 0)
777                         return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
778                                         __FUNCTION__, "failed to create request cb info");
779                 if (id)
780                         *id = req_id;
781         }
782
783         return ret;
784 }
785
786 API int package_manager_request_move(package_manager_request_h request,
787                 const char *name, package_manager_move_type_e move_type)
788 {
789         return __request_move(request, name, move_type, NULL, NULL);
790 }
791
792 API int package_manager_request_move_with_cb(package_manager_request_h request,
793                 const char *name, package_manager_move_type_e move_type,
794                 package_manager_request_event_cb callback, void *user_data, int *id)
795 {
796         int ret;
797         int req_id = 0;
798
799         if (__request_cb_table == NULL)
800                 __initialize_request_cb_table();
801
802         ret = __request_move(request, name, move_type, internal_request_callback, &req_id);
803
804         if (req_id > 0) {
805                 ret = __insert_request_cb_info(req_id, callback, user_data);
806                 if (ret < 0)
807                         return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
808                                         __FUNCTION__, "failed to create request cb info");
809                 if (id)
810                         *id = req_id;
811         }
812
813         return ret;
814 }
815
816 API int package_manager_create(package_manager_h *manager)
817 {
818         int retval;
819         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
820         if (retval != PACKAGE_MANAGER_ERROR_NONE)
821                 return retval;
822
823         struct package_manager_s *package_manager = NULL;
824
825         if (manager == NULL) {
826                 return
827                     package_manager_error
828                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
829                      NULL);
830         }
831
832         package_manager = calloc(1, sizeof(struct package_manager_s));
833         if (package_manager == NULL) {
834                 return
835                     package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
836                                           __FUNCTION__,
837                                           "failed to create a package_manager handle");
838         }
839
840         package_manager->ctype = PC_LISTENING;
841         package_manager->pc = pkgmgr_client_new(PC_LISTENING);
842         if (package_manager->pc == NULL) {
843                 free(package_manager);
844                 return
845                     package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
846                                           __FUNCTION__,
847                                           "failed to create a package_manager client");
848         }
849
850         package_manager->handle_id = package_manager_new_id();
851
852         *manager = package_manager;
853
854         return PACKAGE_MANAGER_ERROR_NONE;
855 }
856
857 static int package_manager_validate_handle(package_manager_h manager)
858 {
859         if (manager == NULL || manager->pc == NULL)
860                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
861
862         return PACKAGE_MANAGER_ERROR_NONE;
863 }
864
865 API int package_manager_destroy(package_manager_h manager)
866 {
867         if (package_manager_validate_handle(manager)) {
868                 return
869                     package_manager_error
870                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
871                      NULL);
872         }
873
874         pkgmgr_client_free(manager->pc);
875         manager->pc = NULL;
876         __clean_all_event_info(manager->head);
877         free(manager);
878
879         return PACKAGE_MANAGER_ERROR_NONE;
880 }
881
882 static int __add_event(event_info **head, int req_id,
883                             package_manager_event_type_e event_type,
884                             package_manager_event_state_e event_state)
885 {
886         event_info *evt_info;
887
888         evt_info = (event_info *) calloc(1, sizeof(event_info));
889         if (evt_info == NULL) {
890                 _LOGD("calloc failed");
891                 return -1;
892         }
893         evt_info->req_id = req_id;
894         evt_info->event_type = event_type;
895         evt_info->event_state = event_state;
896         evt_info->next = NULL;
897
898         *head = evt_info;
899
900         return 0;
901 }
902
903 static int __find_event(event_info **head, int req_id,
904                              package_manager_event_type_e *event_type,
905                              package_manager_event_state_e *event_state)
906 {
907         event_info *tmp;
908
909         tmp = *head;
910
911         if (tmp == NULL) {
912                 _LOGE("tmp is NULL");
913                 return -1;
914         }
915
916         *event_type = tmp->event_type;
917         *event_state = tmp->event_state;
918         return 0;
919 }
920
921 static int __update_event(event_info **head, int req_id,
922                                package_manager_event_type_e event_type,
923                                package_manager_event_state_e event_state)
924 {
925         package_manager_event_type_e evt_type;
926         package_manager_event_state_e evt_state;
927         event_info *tmp;
928
929         if (__find_event_info(head, req_id, &evt_type, &evt_state) != 0)
930                 __add_event_info(head, req_id, event_type, event_state);
931         else {
932                 tmp = *head;
933
934                 if (tmp == NULL) {
935                         _LOGE("tmp is NULL");
936                         return -1;
937                 }
938
939                 tmp->event_type = event_type;
940                 tmp->event_state = event_state;
941                 return 0;
942         }
943
944         return -1;
945 }
946
947 /* App Event Listening Policy:
948  * +----------------+------------+---------------+------------------+
949  * |Listener \ Type |Global Event|My User's Event|Other user's Event|
950  * +----------------+------------+---------------+------------------+
951  * |User Process App|   Grant    |     Grant     |      Deny        |
952  * +----------------+------------+---------------+------------------+
953  * |Platform module |   Grant    |     Grant     |      Grant       |
954  * +----------------+------------+---------------+------------------+
955  * UID assignment policy:
956  * https://wiki.tizen.org/wiki/Security/User_and_group_ID_assignment_policy
957  */
958 #define REGULAR_USER 5000
959 static int __validate_event_signal(uid_t target_uid)
960 {
961         uid_t self = getuid();
962
963         if (self == target_uid)
964                 return 0;
965
966         if (self < REGULAR_USER)
967                 return 0;
968
969         return -1;
970 }
971
972 static int global_event_handler(uid_t target_uid, int req_id, const char *pkg_type,
973                                 const char *pkg_name, const char *key,
974                                 const char *val, const void *pmsg, void *data)
975 {
976         int ret = -1;
977         package_manager_event_type_e event_type = -1;
978         package_manager_event_state_e event_state = -1;
979         uid_t uid = target_uid;
980
981         package_manager_h manager = data;
982
983         if (target_uid == GLOBAL_USER)
984                 uid = getuid();
985
986         if (__validate_event_signal(uid))
987                 return PACKAGE_MANAGER_ERROR_NONE;
988
989         if (strcasecmp(key, "start") == 0) {
990                 ret = package_manager_get_event_type(val, &event_type);
991                 if (ret != PACKAGE_MANAGER_ERROR_NONE)
992                         return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
993
994                 __add_event(&(manager->head), req_id, event_type,
995                                  PACKAGE_MANAGER_EVENT_STATE_STARTED);
996
997                 if (manager->event_cb && getuid() == uid)
998                         manager->event_cb(pkg_type, pkg_name,
999                                           event_type,
1000                                           PACKAGE_MANAGER_EVENT_STATE_STARTED,
1001                                           0, PACKAGE_MANAGER_ERROR_NONE, manager->user_data);
1002         } else if (strcasecmp(key, "install_percent") == 0
1003                    || strcasecmp(key, "progress_percent") == 0) {
1004                 if (__find_event
1005                     (&(manager->head), req_id, &event_type,
1006                      &event_state) == 0) {
1007                         __update_event(&(manager->head), req_id,
1008                                             event_type,
1009                                             PACKAGE_MANAGER_EVENT_STATE_PROCESSING);
1010                         if (manager->event_cb && getuid() == uid)
1011                                 manager->event_cb(pkg_type, pkg_name,
1012                                                   event_type,
1013                                                   PACKAGE_MANAGER_EVENT_STATE_PROCESSING,
1014                                                   atoi(val),
1015                                                   PACKAGE_MANAGER_ERROR_NONE,
1016                                                   manager->user_data);
1017                 }
1018
1019         } else if (strcasecmp(key, "error") == 0) {
1020                 if (strcasecmp(key, "0") != 0) {
1021                         if (__find_event
1022                             (&(manager->head), req_id, &event_type,
1023                              &event_state) == 0) {
1024                                 __update_event(&(manager->head), req_id,
1025                                                     event_type,
1026                                                     PACKAGE_MANAGER_EVENT_STATE_FAILED);
1027                         }
1028
1029                         if (manager->event_cb && getuid() == uid)
1030                                 manager->event_cb(pkg_type,
1031                                                   pkg_name, event_type,
1032                                                   PACKAGE_MANAGER_EVENT_STATE_FAILED,
1033                                                   0,
1034                                                   PACKAGE_MANAGER_ERROR_NONE,
1035                                                   manager->user_data);
1036                 }
1037         } else if (strcasecmp(key, "end") == 0) {
1038                 if (__find_event
1039                     (&(manager->head), req_id, &event_type,
1040                      &event_state) == 0) {
1041                         if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) {
1042                                 if (manager->event_cb && getuid() == uid)
1043                                         manager->event_cb(pkg_type,
1044                                                           pkg_name, event_type,
1045                                                           PACKAGE_MANAGER_EVENT_STATE_COMPLETED,
1046                                                           100,
1047                                                           PACKAGE_MANAGER_ERROR_NONE,
1048                                                           manager->user_data);
1049                         }
1050                 } else {
1051                         if (strcasecmp(key, "ok") != 0) {
1052                                 if (manager->event_cb && getuid() == uid)
1053                                         manager->event_cb(pkg_type,
1054                                                           pkg_name, event_type,
1055                                                           PACKAGE_MANAGER_EVENT_STATE_FAILED,
1056                                                           0,
1057                                                           PACKAGE_MANAGER_ERROR_NONE,
1058                                                           manager->user_data);
1059                         }
1060                 }
1061         }
1062
1063         return PACKAGE_MANAGER_ERROR_NONE;
1064 }
1065
1066 static int __convert_status_type(package_manager_status_type_e status_type)
1067 {
1068         int type = 0;
1069
1070         if (status_type == PACKAGE_MANAGER_STATUS_TYPE_ALL)
1071                 return PKGMGR_CLIENT_STATUS_ALL;
1072
1073         if (status_type & PACKAGE_MANAGER_STATUS_TYPE_INSTALL)
1074                 type |= PKGMGR_CLIENT_STATUS_INSTALL;
1075         if (status_type & PACKAGE_MANAGER_STATUS_TYPE_UNINSTALL)
1076                 type |= PKGMGR_CLIENT_STATUS_UNINSTALL;
1077         if (status_type & PACKAGE_MANAGER_STATUS_TYPE_UPGRADE)
1078                 type |= PKGMGR_CLIENT_STATUS_UPGRADE;
1079         if (status_type & PACKAGE_MANAGER_STATUS_TYPE_MOVE)
1080                 type |= PKGMGR_CLIENT_STATUS_MOVE;
1081         if (status_type & PACKAGE_MANAGER_STATUS_TYPE_CLEAR_DATA)
1082                 type |= PKGMGR_CLIENT_STATUS_CLEAR_DATA;
1083         if (status_type & PACKAGE_MANAGER_STATUS_TYPE_INSTALL_PROGRESS)
1084                 type |= PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS;
1085         if (status_type & PACKAGE_MANAGER_STATUS_TYPE_GET_SIZE)
1086                 type |= PKGMGR_CLIENT_STATUS_GET_SIZE;
1087
1088         return type;
1089 }
1090
1091 API int package_manager_set_event_status(package_manager_h manager, int status_type)
1092 {
1093         int retval;
1094         int type;
1095         int type_all = PACKAGE_MANAGER_STATUS_TYPE_INSTALL |
1096                 PACKAGE_MANAGER_STATUS_TYPE_UNINSTALL |
1097                 PACKAGE_MANAGER_STATUS_TYPE_UPGRADE |
1098                 PACKAGE_MANAGER_STATUS_TYPE_MOVE |
1099                 PACKAGE_MANAGER_STATUS_TYPE_CLEAR_DATA |
1100                 PACKAGE_MANAGER_STATUS_TYPE_INSTALL_PROGRESS |
1101                 PACKAGE_MANAGER_STATUS_TYPE_GET_SIZE;
1102
1103         if (manager == NULL)
1104                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1105
1106         if (status_type < 0 || status_type > type_all)
1107                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1108
1109         type = __convert_status_type(status_type);
1110         retval = pkgmgr_client_set_status_type(manager->pc, type);
1111
1112         if (retval < 0)
1113                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1114
1115         return PACKAGE_MANAGER_ERROR_NONE;
1116 }
1117
1118 API int package_manager_set_event_cb(package_manager_h manager,
1119                                  package_manager_event_cb callback,
1120                                  void *user_data)
1121 {
1122
1123         int retval;
1124         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1125         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1126                 return retval;
1127
1128         if (package_manager_validate_handle(manager)) {
1129                 return
1130                     package_manager_error
1131                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
1132                      NULL);
1133         }
1134
1135         manager->event_cb = callback;
1136         manager->user_data = user_data;
1137
1138         pkgmgr_client_listen_status(manager->pc, global_event_handler, manager);
1139
1140         return PACKAGE_MANAGER_ERROR_NONE;
1141 }
1142
1143 API int package_manager_unset_event_cb(package_manager_h manager)
1144 {
1145         if (manager == NULL) {
1146                 return
1147                     package_manager_error
1148                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
1149                      NULL);
1150         }
1151
1152         int retval;
1153         manager->event_cb = NULL;
1154         manager->user_data = NULL;
1155
1156         retval = pkgmgr_client_remove_listen_status(manager->pc);
1157         if (retval == PKGMGR_R_EINVAL)
1158                 return
1159                          package_manager_error
1160                          (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
1161                           NULL);
1162         else if (retval == PKGMGR_R_ERROR)
1163                 return
1164                          package_manager_error
1165                          (PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__,
1166                           NULL);
1167
1168         return PACKAGE_MANAGER_ERROR_NONE;
1169 }
1170
1171 API int package_manager_get_package_id_by_app_id(const char *app_id, char **package_id)
1172 {
1173         pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo;
1174         int retval;
1175         char *pkg_id = NULL;
1176         char *pkg_id_dup = NULL;
1177
1178         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1179         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1180                 return retval;
1181
1182         if (app_id == NULL || package_id == NULL)
1183                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1184
1185         if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
1186                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1187         retval = pkgmgrinfo_appinfo_get_pkgname(pkgmgrinfo_appinfo, &pkg_id);
1188         if (retval != PMINFO_R_OK)
1189                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1190
1191         pkg_id_dup = strdup(pkg_id);
1192         if (pkg_id_dup == NULL) {
1193                 pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1194                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1195         }
1196
1197         *package_id = pkg_id_dup;
1198
1199         pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1200
1201         return PACKAGE_MANAGER_ERROR_NONE;
1202 }
1203
1204 API int package_manager_get_package_info(const char *package_id, package_info_h *package_info)
1205 {
1206         int retval;
1207         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1208         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1209                 return retval;
1210
1211         retval = package_info_get_package_info(package_id, package_info);
1212
1213         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1214                 return package_manager_error(retval, __FUNCTION__, NULL);
1215         else
1216                 return PACKAGE_MANAGER_ERROR_NONE;
1217 }
1218
1219 API int package_manager_foreach_package_info(package_manager_package_info_cb callback,
1220                                         void *user_data)
1221 {
1222
1223         int retval;
1224         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1225         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1226                 return retval;
1227
1228         retval = package_info_foreach_package_info(callback, user_data);
1229
1230         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1231                 return package_manager_error(retval, __FUNCTION__, NULL);
1232         else
1233                 return PACKAGE_MANAGER_ERROR_NONE;
1234 }
1235
1236 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)
1237 {
1238         pkgmgrinfo_cert_compare_result_type_e result;
1239
1240         if (lhs_package_id == NULL || rhs_package_id == NULL || compare_result == NULL)
1241                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1242         if (pkgmgrinfo_pkginfo_compare_pkg_cert_info(lhs_package_id, rhs_package_id, &result) != PKGMGR_R_OK)
1243                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1244         *compare_result = (package_manager_compare_result_type_e)result;
1245
1246         return PACKAGE_MANAGER_ERROR_NONE;
1247 }
1248
1249 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)
1250 {
1251         pkgmgrinfo_cert_compare_result_type_e result;
1252
1253         if (lhs_app_id == NULL || rhs_app_id == NULL || compare_result == NULL)
1254                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1255         if (pkgmgrinfo_pkginfo_compare_app_cert_info(lhs_app_id, rhs_app_id, &result) != PKGMGR_R_OK)
1256                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1257
1258         *compare_result = (package_manager_compare_result_type_e)result;
1259
1260         return PACKAGE_MANAGER_ERROR_NONE;
1261 }
1262
1263 API int package_manager_is_preload_package_by_app_id(const char *app_id, bool *preload)
1264 {
1265
1266         int retval;
1267         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1268         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1269                 return retval;
1270
1271         pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo = NULL;
1272         pkgmgrinfo_pkginfo_h pkgmgrinfo_pkginfo = NULL;
1273
1274         char *pkg_id = NULL;
1275         bool is_preload = 0;
1276         if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
1277                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1278
1279         retval = pkgmgrinfo_appinfo_get_pkgname(pkgmgrinfo_appinfo, &pkg_id);
1280         if (retval != PMINFO_R_OK) {
1281                 pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1282                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1283         }
1284         if (pkgmgrinfo_pkginfo_get_pkginfo(pkg_id, &pkgmgrinfo_pkginfo) != PMINFO_R_OK) {
1285                 pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1286                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo);
1287                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1288         }
1289         if (pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo, &is_preload) != PMINFO_R_OK) {
1290                 pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1291                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo);
1292                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1293         }
1294
1295         if (is_preload)
1296                 *preload = 1;
1297         else
1298                 *preload = 0;
1299
1300         pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1301         pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo);
1302
1303         return PACKAGE_MANAGER_ERROR_NONE;
1304 }
1305
1306 API int package_manager_get_permission_type(const char *app_id, package_manager_permission_type_e *permission_type)
1307 {
1308
1309         int retval;
1310         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1311         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1312                 return retval;
1313
1314         pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo = NULL;
1315         pkgmgrinfo_permission_type permission = 0;
1316         if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
1317                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1318         retval = pkgmgrinfo_appinfo_get_permission_type(pkgmgrinfo_appinfo, &permission);
1319         if (retval != PMINFO_R_OK)
1320                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1321
1322         if (permission == PMINFO_PERMISSION_NORMAL)
1323                 *permission_type = PACKAGE_MANAGER_PERMISSION_NORMAL;
1324         else if (permission == PMINFO_PERMISSION_SIGNATURE)
1325                 *permission_type = PACKAGE_MANAGER_PERMISSION_SIGNATURE;
1326         else if (permission == PMINFO_PERMISSION_PRIVILEGE)
1327                 *permission_type = PACKAGE_MANAGER_PERMISSION_PRIVILEGE;
1328         else
1329                 *permission_type = PACKAGE_MANAGER_PERMISSION_NORMAL;
1330
1331         pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
1332         return PACKAGE_MANAGER_ERROR_NONE;
1333 }
1334
1335 API int package_manager_clear_cache_dir(const char *package_id)
1336 {
1337
1338         int retval;
1339         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_CACHE);
1340         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1341                 return retval;
1342
1343         int res = pkgmgr_client_clear_cache_dir(package_id);
1344         if (res == PKGMGR_R_EINVAL) {
1345                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1346         } else if (res == PKGMGR_R_ENOPKG) {
1347                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1348         } else if (res == PKGMGR_R_ENOMEM) {
1349                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1350         } else if (res == PKGMGR_R_EIO) {
1351                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1352         } else if (res == PKGMGR_R_EPRIV) {
1353                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
1354         } else if (res == PKGMGR_R_ESYSTEM || res == PKGMGR_R_ECOMM || res == PKGMGR_R_ERROR) {
1355                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1356         } else if (res != PKGMGR_R_OK) {
1357                 _LOGE("Unexpected error");
1358                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1359         }
1360
1361         return PACKAGE_MANAGER_ERROR_NONE;
1362 }
1363
1364 API int package_manager_clear_data_dir(const char *package_id)
1365 {
1366         int retval;
1367         pkgmgr_client *pc = NULL;
1368         char *pkg_type = NULL;
1369         pkgmgrinfo_pkginfo_h pkginfo = NULL;
1370
1371         if (package_id == NULL)
1372                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
1373
1374         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
1375         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1376                 return retval;
1377
1378         retval = pkgmgrinfo_pkginfo_get_pkginfo(package_id, &pkginfo);
1379         if (retval == PMINFO_R_ENOENT)
1380                 return PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE;
1381         else if (retval != PMINFO_R_OK || pkginfo == NULL)
1382                 return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
1383
1384         retval = pkgmgrinfo_pkginfo_get_type(pkginfo, &pkg_type);
1385         if (retval != PMINFO_R_OK || pkg_type == NULL) {
1386                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
1387                 return PACKAGE_MANAGER_ERROR_SYSTEM_ERROR;
1388         }
1389
1390         pc = pkgmgr_client_new(PC_REQUEST);
1391         if (pc == NULL) {
1392                 _LOGE("Out of memory");
1393                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
1394                 return PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY;
1395         }
1396
1397         retval = pkgmgr_client_clear_user_data(pc, pkg_type, package_id, PM_QUIET);
1398         pkgmgr_client_free(pc);
1399         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
1400
1401         if (retval == PKGMGR_R_EINVAL) {
1402                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1403         } else if (retval == PKGMGR_R_ENOPKG) {
1404                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1405         } else if (retval == PKGMGR_R_ENOMEM) {
1406                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1407         } else if (retval == PKGMGR_R_EIO) {
1408                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1409         } else if (retval == PKGMGR_R_EPRIV) {
1410                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
1411         } else if (retval == PKGMGR_R_ESYSTEM || retval == PKGMGR_R_ECOMM || retval == PKGMGR_R_ERROR) {
1412                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1413         } else if (retval != PKGMGR_R_OK) {
1414                 _LOGE("Unexpected error");
1415                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1416         }
1417
1418         return PACKAGE_MANAGER_ERROR_NONE;
1419 }
1420
1421 API int package_manager_clear_all_cache_dir(void)
1422 {
1423
1424         int retval;
1425         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
1426         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1427                 return retval;
1428
1429         return package_manager_clear_cache_dir(PKG_CLEAR_ALL_CACHE);
1430 }
1431
1432 static void __free_client(gpointer data)
1433 {
1434         pkgmgr_client *pc = (pkgmgr_client *)data;
1435         pkgmgr_client_free(pc);
1436 }
1437
1438 static void __initialize_cb_table(void)
1439 {
1440         __cb_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, __free_client, NULL);
1441 }
1442
1443 static void __result_cb(pkgmgr_client *pc, const char *pkgid, const pkg_size_info_t *result, void *user_data)
1444 {
1445         package_manager_size_info_receive_cb callback = g_hash_table_lookup(__cb_table, pc);
1446         if (callback == NULL) {
1447                 _LOGE("callback is null.");
1448                 g_hash_table_remove(__cb_table, pc);
1449                 return;
1450         }
1451
1452         package_size_info_t size_info;
1453         size_info.data_size  = result->data_size;
1454         size_info.cache_size = result->cache_size;
1455         size_info.app_size   = result->app_size;
1456         size_info.external_data_size  = result->ext_data_size;
1457         size_info.external_cache_size = result->ext_cache_size;
1458         size_info.external_app_size   = result->ext_app_size;
1459
1460         callback(pkgid, (package_size_info_h)&size_info, user_data);
1461
1462         g_hash_table_remove(__cb_table, pc);
1463 }
1464
1465 static void __total_result_cb(pkgmgr_client *pc, const pkg_size_info_t *result, void *user_data)
1466 {
1467         package_manager_total_size_info_receive_cb callback = g_hash_table_lookup(__cb_table, pc);
1468         if (callback == NULL) {
1469                 _LOGE("callback is null.");
1470                 g_hash_table_remove(__cb_table, pc);
1471                 return;
1472         }
1473
1474         package_size_info_t size_info;
1475         size_info.data_size  = result->data_size;
1476         size_info.cache_size = result->cache_size;
1477         size_info.app_size   = result->app_size;
1478         size_info.external_data_size  = result->ext_data_size;
1479         size_info.external_cache_size = result->ext_cache_size;
1480         size_info.external_app_size   = result->ext_app_size;
1481
1482         callback((package_size_info_h)&size_info, user_data);
1483
1484         g_hash_table_remove(__cb_table, pc);
1485 }
1486
1487 static int _get_pkg_size_info(const char *package_id, void *callback, void *user_data)
1488 {
1489         if (package_id == NULL || callback == NULL)
1490                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1491
1492         if (__cb_table == NULL)
1493                 __initialize_cb_table();
1494
1495         pkgmgr_client *pc = pkgmgr_client_new(PC_REQUEST);
1496         if (pc == NULL)
1497                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1498
1499         int res = 0;
1500         if (strcmp(package_id, PKG_SIZE_INFO_TOTAL) != 0)
1501                 res = pkgmgr_client_get_package_size_info(pc, package_id, __result_cb, user_data);
1502         else
1503                 res = pkgmgr_client_get_total_package_size_info(pc, __total_result_cb, user_data);
1504
1505         if (res == PKGMGR_R_EINVAL) {
1506                 pkgmgr_client_free(pc);
1507                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1508         } else if (res == PKGMGR_R_ENOPKG) {
1509                 pkgmgr_client_free(pc);
1510                 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
1511         } else if (res == PKGMGR_R_ENOMEM) {
1512                 pkgmgr_client_free(pc);
1513                 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
1514         } else if (res == PKGMGR_R_EIO) {
1515                 pkgmgr_client_free(pc);
1516                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1517         } else if (res == PKGMGR_R_EPRIV) {
1518                 pkgmgr_client_free(pc);
1519                 return package_manager_error(PACKAGE_MANAGER_ERROR_PERMISSION_DENIED, __FUNCTION__, NULL);
1520         } else if (res == PKGMGR_R_ESYSTEM || res == PKGMGR_R_ECOMM || res == PKGMGR_R_ERROR) {
1521                 pkgmgr_client_free(pc);
1522                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1523         } else if (res != PKGMGR_R_OK) {
1524                 _LOGE("Unexpected error");
1525                 pkgmgr_client_free(pc);
1526                 return package_manager_error(PACKAGE_MANAGER_ERROR_SYSTEM_ERROR, __FUNCTION__, NULL);
1527         }
1528
1529         g_hash_table_insert(__cb_table, pc, callback);
1530
1531         return PACKAGE_MANAGER_ERROR_NONE;
1532 }
1533
1534 API int package_manager_get_package_size_info(const char *package_id, package_manager_size_info_receive_cb callback, void *user_data)
1535 {
1536         return _get_pkg_size_info(package_id, (void *)callback, user_data);
1537 }
1538
1539 API int package_manager_get_total_package_size_info(package_manager_total_size_info_receive_cb callback, void *user_data)
1540 {
1541         return _get_pkg_size_info(PKG_SIZE_INFO_TOTAL, (void *)callback, user_data);
1542 }
1543
1544 API int package_manager_filter_create(package_manager_filter_h *handle)
1545 {
1546         int retval;
1547         pkgmgrinfo_pkginfo_filter_h pkgmgr_filter = NULL;
1548
1549         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1550         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1551                 return retval;
1552
1553         if (handle == NULL) {
1554                 return
1555                     package_manager_error
1556                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
1557                      NULL);
1558         }
1559
1560         retval = pkgmgrinfo_pkginfo_filter_create(&pkgmgr_filter);
1561         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1562                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1563
1564         *handle = pkgmgr_filter;
1565
1566         return PACKAGE_MANAGER_ERROR_NONE;
1567 }
1568
1569 API int package_manager_filter_destroy(package_manager_filter_h handle)
1570 {
1571         int retval;
1572
1573         if (handle == NULL) {
1574                 return
1575                     package_manager_error
1576                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
1577                      NULL);
1578         }
1579
1580         retval = pkgmgrinfo_pkginfo_filter_destroy(handle);
1581         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1582                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1583
1584         return PACKAGE_MANAGER_ERROR_NONE;
1585 }
1586
1587 API int package_manager_filter_add_bool(package_manager_filter_h handle,
1588                 const char *property, const bool value)
1589 {
1590         int retval;
1591
1592         if ((handle == NULL) || (property == NULL)) {
1593                 return
1594                     package_manager_error
1595                     (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
1596                      NULL);
1597         }
1598
1599         retval = pkgmgrinfo_pkginfo_filter_add_bool(handle, property, value);
1600         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1601                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1602
1603         return PACKAGE_MANAGER_ERROR_NONE;
1604 }
1605
1606 API int package_manager_filter_count(package_manager_filter_h handle, int *count)
1607 {
1608
1609         int retval;
1610         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1611         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1612                 return retval;
1613
1614         if ((handle == NULL) || (count == NULL))
1615                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1616
1617         retval = pkgmgrinfo_pkginfo_filter_count(handle, count);
1618         if (retval < 0)
1619                 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
1620
1621         return PACKAGE_MANAGER_ERROR_NONE;
1622 }
1623
1624 API int package_manager_filter_foreach_package_info(package_manager_filter_h handle,
1625                 package_manager_package_info_cb callback, void *user_data)
1626 {
1627
1628         int retval;
1629         retval = check_privilege(PRIVILEGE_PACKAGE_MANAGER_INFO);
1630         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1631                 return retval;
1632
1633         retval = package_info_filter_foreach_package_info(handle, callback, user_data);
1634
1635         if (retval != PACKAGE_MANAGER_ERROR_NONE)
1636                 return package_manager_error(retval, __FUNCTION__, NULL);
1637         else
1638                 return PACKAGE_MANAGER_ERROR_NONE;
1639 }
1640
1641 API int package_size_info_get_data_size(package_size_info_h handle, long long *data_size)
1642 {
1643         if (handle == NULL)
1644                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1645
1646         package_size_info_t *size_info = (package_size_info_t *)handle;
1647
1648         *data_size = (long long)size_info->data_size;
1649         return PACKAGE_MANAGER_ERROR_NONE;
1650 }
1651
1652 API int package_size_info_get_cache_size(package_size_info_h handle, long long *cache_size)
1653 {
1654         if (handle == NULL)
1655                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1656
1657         package_size_info_t *size_info = (package_size_info_t *)handle;
1658
1659         *cache_size = size_info->cache_size;
1660         return PACKAGE_MANAGER_ERROR_NONE;
1661 }
1662
1663 API int package_size_info_get_app_size(package_size_info_h handle, long long *app_size)
1664 {
1665         if (handle == NULL)
1666                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1667
1668         package_size_info_t *size_info = (package_size_info_t *)handle;
1669         *app_size = size_info->app_size;
1670         return PACKAGE_MANAGER_ERROR_NONE;
1671 }
1672
1673 API int package_size_info_get_external_data_size(package_size_info_h handle, long long *ext_data_size)
1674 {
1675         if (handle == NULL)
1676                 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
1677
1678         package_size_info_t *size_info = (package_size_info_t *)handle;
1679         *ext_data_size = size_info->external_data_size;
1680         return PACKAGE_MANAGER_ERROR_NONE;
1681 }
1682
1683 API int package_size_info_get_external_cache_size(package_size_info_h handle, long long *ext_cache_size)
1684 {
1685         if (handle == NULL)
1686                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1687
1688         package_size_info_t *size_info = (package_size_info_t *)handle;
1689         *ext_cache_size = size_info->external_cache_size;
1690         return PACKAGE_MANAGER_ERROR_NONE;
1691 }
1692
1693 API int package_size_info_get_external_app_size(package_size_info_h handle, long long *ext_app_size)
1694 {
1695         if (handle == NULL)
1696                 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
1697
1698         package_size_info_t *size_info = (package_size_info_t *)handle;
1699         *ext_app_size = size_info->external_app_size;
1700         return PACKAGE_MANAGER_ERROR_NONE;
1701 }