2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <package-manager.h>
22 #include <package_manager.h>
23 #include <package_manager_private.h>
24 #include <pkgmgr-info.h>
31 #define LOG_TAG "CAPI_APPFW_PACKAGE_MANAGER"
33 #define _LOGE(fmt, arg...) LOGE(fmt,##arg)
34 #define _LOGD(fmt, arg...) LOGD(fmt, ##arg)
36 typedef struct _event_info {
38 package_manager_event_type_e event_type;
39 package_manager_event_state_e event_state;
40 struct _event_info *next;
43 struct package_manager_s {
49 package_manager_event_cb event_cb;
53 struct package_manager_request_s {
62 package_manager_request_event_cb event_cb;
66 static int package_manager_request_new_id()
68 static int request_handle_id = 0;
69 return request_handle_id++;
72 static int package_manager_new_id()
74 static int manager_handle_id = 0;
75 return manager_handle_id++;
78 static const char *package_manager_error_to_string(package_manager_error_e
82 case PACKAGE_MANAGER_ERROR_NONE:
85 case PACKAGE_MANAGER_ERROR_INVALID_PARAMETER:
86 return "INVALID_PARAMETER";
88 case PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY:
89 return "OUT_OF_MEMORY";
91 case PACKAGE_MANAGER_ERROR_IO_ERROR:
98 int package_manager_error(package_manager_error_e error,
99 const char *function, const char *description)
102 _LOGE("[%s] %s(0x%08x) : %s", function,
103 package_manager_error_to_string(error), error,
106 _LOGE("[%s] %s(0x%08x)", function,
107 package_manager_error_to_string(error), error);
113 int package_manager_request_create(package_manager_request_h * request)
115 struct package_manager_request_s *package_manager_request;
117 if (request == NULL) {
119 package_manager_error
120 (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
124 package_manager_request =
125 calloc(1, sizeof(struct package_manager_request_s));
126 if (package_manager_request == NULL) {
128 package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
130 "failed to create a package_manager handle");
133 package_manager_request->ctype = PC_REQUEST;
134 package_manager_request->pc = pkgmgr_client_new(PC_REQUEST);
135 if (package_manager_request->pc == NULL) {
136 free(package_manager_request);
138 package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
140 "failed to create a package_manager client");
143 package_manager_request->handle_id = package_manager_request_new_id();
145 *request = package_manager_request;
147 return PACKAGE_MANAGER_ERROR_NONE;
150 static int package_manager_client_valiate_handle(package_manager_request_h
153 if (request == NULL || request->pc == NULL) {
154 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
157 return PACKAGE_MANAGER_ERROR_NONE;
160 int package_manager_client_destroy(package_manager_request_h request)
162 if (package_manager_client_valiate_handle(request)) {
164 package_manager_error
165 (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
169 pkgmgr_client_free(request->pc);
173 return PACKAGE_MANAGER_ERROR_NONE;
176 int package_manager_request_set_event_cb(package_manager_request_h request,
177 package_manager_request_event_cb
178 callback, void *user_data)
180 if (package_manager_client_valiate_handle(request)) {
182 package_manager_error
183 (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
187 request->event_cb = callback;
188 request->user_data = user_data;
190 return PACKAGE_MANAGER_ERROR_NONE;
193 int package_manager_request_unset_event_cb(package_manager_request_h request)
195 // TODO: Please implement this function.
196 return PACKAGE_MANAGER_ERROR_NONE;
200 int package_manager_request_set_type(package_manager_request_h request,
201 const char *pkg_type)
203 if (package_manager_client_valiate_handle(request)) {
205 package_manager_error
206 (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
210 request->pkg_type = pkg_type;
212 return PACKAGE_MANAGER_ERROR_NONE;
215 int package_manager_request_set_mode(package_manager_request_h request,
216 package_manager_request_mode_e mode)
218 if (package_manager_client_valiate_handle(request)) {
220 package_manager_error
221 (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
225 if (mode == PACAKGE_MANAGER_REQUEST_MODE_QUIET)
226 request->mode = PM_QUIET;
228 request->mode = PM_DEFAULT;
230 return PACKAGE_MANAGER_ERROR_NONE;
233 static int package_manager_get_event_type(const char *key,
234 package_manager_event_type_e *
238 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
240 if (strcasecmp(key, "install") == 0)
241 *event_type = PACAKGE_MANAGER_EVENT_TYPE_INSTALL;
242 else if (strcasecmp(key, "uninstall") == 0)
243 *event_type = PACAKGE_MANAGER_EVENT_TYPE_UNINSTALL;
244 else if (strcasecmp(key, "undate") == 0)
245 *event_type = PACAKGE_MANAGER_EVENT_TYPE_UPDATE;
247 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
249 return PACKAGE_MANAGER_ERROR_NONE;
252 static int __add_event_info(event_info ** head, int req_id,
253 package_manager_event_type_e event_type,
254 package_manager_event_state_e event_state)
256 event_info *evt_info;
260 evt_info = (event_info *) calloc(1, sizeof(event_info));
261 if (evt_info == NULL) {
262 _LOGD("calloc failed");
265 evt_info->req_id = req_id;
266 evt_info->event_type = event_type;
267 evt_info->next = NULL;
272 current = prev = *head;
275 current = current->next;
278 prev->next = evt_info;
284 static int __find_event_info(event_info ** head, int req_id,
285 package_manager_event_type_e * event_type,
286 package_manager_event_state_e * event_state)
293 _LOGE("tmp is NULL");
297 _LOGD("tmp->req_id %d, event_type %d", tmp->req_id, event_type);
300 if (tmp->req_id == req_id) {
301 *event_type = tmp->event_type;
309 static int __update_event_info(event_info ** head, int req_id,
310 package_manager_event_type_e event_type,
311 package_manager_event_state_e event_state)
313 package_manager_event_type_e evt_type;
314 package_manager_event_state_e evt_state;
317 if (__find_event_info(head, req_id, &evt_type, &evt_state) != 0)
318 __add_event_info(head, req_id, event_type, event_state);
323 _LOGE("tmp is NULL");
328 if (tmp->req_id == req_id) {
329 tmp->event_type = event_type;
340 static int __remove_event_info(event_info **head request, int req_id)
351 if (current->next->req_id == req_id) {
353 current->next = current->next->next;
365 static int request_event_handler(int req_id, const char *pkg_type,
366 const char *pkg_name, const char *key,
367 const char *val, const void *pmsg, void *data)
370 package_manager_event_type_e event_type = -1;
371 package_manager_event_state_e event_state = -1;
373 _LOGD("request_event_handler is called");
375 package_manager_request_h request = data;
377 if (strcasecmp(key, "start") == 0) {
378 ret = package_manager_get_event_type(val, &event_type);
379 if (ret != PACKAGE_MANAGER_ERROR_NONE)
380 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
382 __add_event_info(&(request->head), req_id, event_type,
383 PACAKGE_MANAGER_EVENT_STATE_STARTED);
385 if (request->event_cb)
386 request->event_cb(req_id, pkg_type, pkg_name,
388 PACAKGE_MANAGER_EVENT_STATE_STARTED,
389 0, PACKAGE_MANAGER_ERROR_NONE, request->user_data);
391 } else if (strcasecmp(key, "install_percent") == 0
392 || strcasecmp(key, "progress_percent") == 0) {
393 if (__find_event_info
394 (&(request->head), req_id, &event_type,
395 &event_state) == 0) {
396 __update_event_info(&(request->head), req_id,
398 PACAKGE_MANAGER_EVENT_STATE_PROCESSING);
399 if (request->event_cb)
400 request->event_cb(req_id, pkg_type, pkg_name,
402 PACAKGE_MANAGER_EVENT_STATE_PROCESSING,
404 PACKAGE_MANAGER_ERROR_NONE,
408 } else if (strcasecmp(key, "error") == 0) {
409 if (strcasecmp(key, "0") != 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,
415 PACAKGE_MANAGER_EVENT_STATE_FAILED);
418 if (request->event_cb)
419 request->event_cb(req_id, pkg_type,
420 pkg_name, event_type,
421 PACAKGE_MANAGER_EVENT_STATE_FAILED,
423 PACKAGE_MANAGER_ERROR_NONE,
427 } else if (strcasecmp(key, "end") == 0) {
428 if (__find_event_info
429 (&(request->head), req_id, &event_type,
430 &event_state) == 0) {
431 if (event_state != PACAKGE_MANAGER_EVENT_STATE_FAILED) {
432 if (request->event_cb)
433 request->event_cb(req_id, pkg_type,
434 pkg_name, event_type,
435 PACAKGE_MANAGER_EVENT_STATE_COMPLETED,
437 PACKAGE_MANAGER_ERROR_NONE,
441 if (strcasecmp(key, "ok") != 0)
442 if (request->event_cb)
443 request->event_cb(req_id, pkg_type,
444 pkg_name, event_type,
445 PACAKGE_MANAGER_EVENT_STATE_FAILED,
447 PACKAGE_MANAGER_ERROR_NONE,
452 return PACKAGE_MANAGER_ERROR_NONE;
455 int package_manager_request_install(package_manager_request_h request,
456 const char *path, int *id)
459 request->pkg_path = path;
460 request_id = pkgmgr_client_install(request->pc, request->pkg_type, NULL,
461 request->pkg_path, NULL,
462 request->mode, request_event_handler,
466 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
470 return PACKAGE_MANAGER_ERROR_NONE;
473 int package_manager_request_uninstall(package_manager_request_h request,
474 const char *name, int *id)
477 request->pkg_name = name;
478 request_id = pkgmgr_client_uninstall(request->pc, request->pkg_type,
479 request->pkg_name, PM_DEFAULT,
480 request_event_handler, request);
483 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
487 return PACKAGE_MANAGER_ERROR_NONE;
490 int package_manager_request_move(package_manager_request_h request,
491 const char *name, package_manager_move_type_e move_type)
494 request->pkg_name = name;
495 ret = pkgmgr_client_move(request->pc, request->pkg_type, request->pkg_name,
496 move_type, request->mode);
500 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
504 return PACKAGE_MANAGER_ERROR_NONE;
507 int package_manager_create(package_manager_h * manager)
509 struct package_manager_s *package_manager = NULL;
511 if (manager == NULL) {
513 package_manager_error
514 (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
518 package_manager = calloc(1, sizeof(struct package_manager_s));
519 if (package_manager == NULL) {
521 package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
523 "failed to create a package_manager handle");
526 package_manager->ctype = PC_LISTENING;
527 package_manager->pc = pkgmgr_client_new(PC_LISTENING);
528 if (package_manager->pc == NULL) {
529 free(package_manager);
531 package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY,
533 "failed to create a package_manager client");
536 package_manager->handle_id = package_manager_new_id();
538 *manager = package_manager;
540 return PACKAGE_MANAGER_ERROR_NONE;
543 static int package_manager_valiate_handle(package_manager_h manager)
545 if (manager == NULL || manager->pc == NULL) {
546 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
549 return PACKAGE_MANAGER_ERROR_NONE;
552 int package_manager_destroy(package_manager_h manager)
554 if (package_manager_valiate_handle(manager)) {
556 package_manager_error
557 (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
561 pkgmgr_client_free(manager->pc);
565 return PACKAGE_MANAGER_ERROR_NONE;
568 static int global_event_handler(int req_id, const char *pkg_type,
569 const char *pkg_name, const char *key,
570 const char *val, const void *pmsg, void *data)
573 package_manager_event_type_e event_type = -1;
574 package_manager_event_state_e event_state = -1;
576 _LOGD("global_event_handler is called");
578 package_manager_h manager = data;
580 if (strcasecmp(key, "start") == 0) {
581 ret = package_manager_get_event_type(val, &event_type);
582 if (ret != PACKAGE_MANAGER_ERROR_NONE)
583 return PACKAGE_MANAGER_ERROR_INVALID_PARAMETER;
585 __add_event_info(&(manager->head), req_id, event_type,
586 PACAKGE_MANAGER_EVENT_STATE_STARTED);
588 if (manager->event_cb)
589 manager->event_cb(pkg_type, pkg_name,
591 PACAKGE_MANAGER_EVENT_STATE_STARTED,
592 0, PACKAGE_MANAGER_ERROR_NONE, manager->user_data);
594 } else if (strcasecmp(key, "install_percent") == 0
595 || strcasecmp(key, "progress_percent") == 0) {
596 if (__find_event_info
597 (&(manager->head), req_id, &event_type,
598 &event_state) == 0) {
599 __update_event_info(&(manager->head), req_id,
601 PACAKGE_MANAGER_EVENT_STATE_PROCESSING);
602 if (manager->event_cb)
603 manager->event_cb(pkg_type, pkg_name,
605 PACAKGE_MANAGER_EVENT_STATE_PROCESSING,
607 PACKAGE_MANAGER_ERROR_NONE,
611 } else if (strcasecmp(key, "error") == 0) {
612 if (strcasecmp(key, "0") != 0) {
613 if (__find_event_info
614 (&(manager->head), req_id, &event_type,
615 &event_state) == 0) {
616 __update_event_info(&(manager->head), req_id,
618 PACAKGE_MANAGER_EVENT_STATE_FAILED);
621 if (manager->event_cb)
622 manager->event_cb(pkg_type,
623 pkg_name, event_type,
624 PACAKGE_MANAGER_EVENT_STATE_FAILED,
626 PACKAGE_MANAGER_ERROR_NONE,
630 } else if (strcasecmp(key, "end") == 0) {
631 if (__find_event_info
632 (&(manager->head), req_id, &event_type,
633 &event_state) == 0) {
634 if (event_state != PACAKGE_MANAGER_EVENT_STATE_FAILED) {
635 if (manager->event_cb)
636 manager->event_cb(pkg_type,
637 pkg_name, event_type,
638 PACAKGE_MANAGER_EVENT_STATE_COMPLETED,
640 PACKAGE_MANAGER_ERROR_NONE,
644 if (strcasecmp(key, "ok") != 0)
645 if (manager->event_cb)
646 manager->event_cb(pkg_type,
647 pkg_name, event_type,
648 PACAKGE_MANAGER_EVENT_STATE_FAILED,
650 PACKAGE_MANAGER_ERROR_NONE,
655 return PACKAGE_MANAGER_ERROR_NONE;
658 int package_manager_set_event_cb(package_manager_h manager,
659 package_manager_event_cb callback,
663 if (package_manager_valiate_handle(manager)) {
665 package_manager_error
666 (PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__,
670 manager->event_cb = callback;
671 manager->user_data = user_data;
674 pkgmgr_client_listen_status(manager->pc, global_event_handler,
677 return PACKAGE_MANAGER_ERROR_NONE;
680 int package_manager_unset_event_cb(package_manager_h manager)
682 // TODO: Please implement this function.
683 return PACKAGE_MANAGER_ERROR_NONE;
686 int package_manager_get_package_id_by_app_id(const char *app_id, char **package_id)
688 pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo;
691 char *pkg_id_dup = NULL;
693 if (pkgmgrinfo_appinfo_get_appinfo(app_id, &pkgmgrinfo_appinfo) != PMINFO_R_OK)
695 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
698 retval = pkgmgrinfo_appinfo_get_pkgname(pkgmgrinfo_appinfo, &pkg_id);
699 if (retval != PMINFO_R_OK)
701 return package_manager_error(PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE, __FUNCTION__, NULL);
704 pkg_id_dup = strdup(pkg_id);
705 if (pkg_id_dup == NULL)
707 pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
708 return package_manager_error(PACKAGE_MANAGER_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL);
711 *package_id = pkg_id_dup;
713 pkgmgrinfo_appinfo_destroy_appinfo(pkgmgrinfo_appinfo);
715 return PACKAGE_MANAGER_ERROR_NONE;
718 int package_manager_get_package_info(const char *package_id, package_info_h *package_info)
722 retval = package_info_get_package_info(package_id, package_info);
724 if (retval != PACKAGE_MANAGER_ERROR_NONE)
726 return package_manager_error(retval, __FUNCTION__, NULL);
730 return PACKAGE_MANAGER_ERROR_NONE;
734 int package_manager_foreach_package_info(package_manager_package_info_cb callback,
739 retval = package_info_foreach_package_info(callback, user_data);
741 if (retval != PACKAGE_MANAGER_ERROR_NONE)
743 return package_manager_error(retval, __FUNCTION__, NULL);
747 return PACKAGE_MANAGER_ERROR_NONE;
750 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)
752 pkgmgrinfo_cert_compare_result_type_e result;
754 if (lhs_package_id == NULL || rhs_package_id == NULL || compare_result == NULL)
756 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
759 if (pkgmgrinfo_pkginfo_compare_pkg_cert_info(lhs_package_id, rhs_package_id, &result) != PKGMGR_R_OK)
761 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
764 *compare_result = (package_manager_compare_result_type_e)result;
766 return PACKAGE_MANAGER_ERROR_NONE;
769 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)
771 pkgmgrinfo_cert_compare_result_type_e result;
773 if (lhs_app_id == NULL || rhs_app_id == NULL || compare_result == NULL)
775 return package_manager_error(PACKAGE_MANAGER_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL);
778 if (pkgmgrinfo_pkginfo_compare_app_cert_info(lhs_app_id, rhs_app_id, &result) != PKGMGR_R_OK)
780 return package_manager_error(PACKAGE_MANAGER_ERROR_IO_ERROR, __FUNCTION__, NULL);
783 *compare_result = (package_manager_compare_result_type_e)result;
785 return PACKAGE_MANAGER_ERROR_NONE;