6 #include <dbus/dbus-glib-lowlevel.h>
8 #include "pkgmgrinfo_type.h"
9 #include "pkgmgrinfo_debug.h"
10 #include "pkgmgrinfo_private.h"
12 API pkgmgrinfo_client *pkgmgrinfo_client_new(pkgmgrinfo_client_type ctype)
17 pkgmgrinfo_client *(*__pkgmgr_client_new)(pkgmgrinfo_client_type ctype) = NULL;
19 handle = dlopen("libpkgmgr-client.so.0", RTLD_LAZY | RTLD_GLOBAL);
20 retvm_if(!handle, NULL, "dlopen() failed. [%s]", dlerror());
22 __pkgmgr_client_new = dlsym(handle, "pkgmgr_client_new");
24 trym_if((errmsg != NULL) || (__pkgmgr_client_new == NULL), "dlsym() failed. [%s]", errmsg);
26 pc = __pkgmgr_client_new(ctype);
27 trym_if(pc == NULL, "pkgmgr_client_new failed.");
31 return (pkgmgrinfo_client *) pc;
34 API int pkgmgrinfo_client_set_status_type(pkgmgrinfo_client *pc, int status_type)
39 int (*__pkgmgr_client_set_status_type)(pkgmgrinfo_client *pc, int status_type) = NULL;
41 handle = dlopen("libpkgmgr-client.so.0", RTLD_LAZY | RTLD_GLOBAL);
42 retvm_if(!handle, PMINFO_R_ERROR, "dlopen() failed. [%s]", dlerror());
44 __pkgmgr_client_set_status_type = dlsym(handle, "pkgmgr_client_set_status_type");
46 tryvm_if((errmsg != NULL) || (__pkgmgr_client_set_status_type == NULL), ret = PMINFO_R_ERROR, "dlsym() failed. [%s]", errmsg);
48 ret = __pkgmgr_client_set_status_type(pc, status_type);
49 tryvm_if(ret < 0, ret = PMINFO_R_ERROR, "pkgmgr_client_new failed.");
53 * Do not close libpkgmgr-client.so.0 to avoid munmap registered callback
55 * The lib dependency chain like below
56 * amd --> pkgmgr-info -- dlopen --> libpkgmgr-client --> libpkgmgr-installer-client
58 * And there is a function in libpkgmgr-installer-client named _on_signal_handle_filter()
59 * which will registered to dbus callback in amd though in fact amd doesn't direct depends
60 * on libpkgmgr-installer-client.
62 * So when the dlcose happen, then libpkgmgr-installer-client been closed too since no one
65 * However, when the libdbus call into the callback function, it suddenly fond that the
66 * function address is gone (unmapped), then we receive a SIGSEGV.
68 * I'm not sure why we're using dlopen/dlclose in this case, I think it's much simple and
69 * robust if we just link to the well-known lib.
71 * See https://bugs.tizen.org/jira/browse/PTREL-591
77 API int pkgmgrinfo_client_listen_status(pkgmgrinfo_client *pc, pkgmgrinfo_handler event_cb, void *data)
82 int (*__pkgmgr_client_listen_status)(pkgmgrinfo_client *pc, pkgmgrinfo_handler event_cb, void *data) = NULL;
84 handle = dlopen("libpkgmgr-client.so.0", RTLD_LAZY | RTLD_GLOBAL);
85 retvm_if(!handle, PMINFO_R_ERROR, "dlopen() failed. [%s]", dlerror());
87 __pkgmgr_client_listen_status = dlsym(handle, "pkgmgr_client_listen_status");
89 tryvm_if((errmsg != NULL) || (__pkgmgr_client_listen_status == NULL), ret = PMINFO_R_ERROR, "dlsym() failed. [%s]", errmsg);
91 ret = __pkgmgr_client_listen_status(pc, event_cb, data);
92 tryvm_if(ret < 0, ret = PMINFO_R_ERROR, "pkgmgr_client_new failed.");
95 /* same as pkgmgrinfo_client_new */
99 API int pkgmgrinfo_client_free(pkgmgrinfo_client *pc)
104 int (*__pkgmgr_client_free)(pkgmgrinfo_client *pc) = NULL;
106 handle = dlopen("libpkgmgr-client.so.0", RTLD_LAZY | RTLD_GLOBAL);
107 retvm_if(!handle, PMINFO_R_ERROR, "dlopen() failed. [%s]", dlerror());
109 __pkgmgr_client_free = dlsym(handle, "pkgmgr_client_free");
111 tryvm_if((errmsg != NULL) || (__pkgmgr_client_free == NULL), ret = PMINFO_R_ERROR, "dlsym() failed. [%s]", errmsg);
113 ret = __pkgmgr_client_free(pc);
114 tryvm_if(ret < 0, ret = PMINFO_R_ERROR, "pkgmgr_client_new failed.");
117 /* same as pkgmgrinfo_client_new */
121 static int __get_pkg_location(const char *pkgid)
123 retvm_if(pkgid == NULL, PMINFO_R_OK, "pkginfo handle is NULL");
126 char pkg_mmc_path[FILENAME_MAX] = { 0, };
127 snprintf(pkg_mmc_path, FILENAME_MAX, "%s%s", PKG_SD_PATH, pkgid);
129 /*check whether application is in external memory or not */
130 fp = fopen(pkg_mmc_path, "r");
134 return PMINFO_EXTERNAL_STORAGE;
137 return PMINFO_INTERNAL_STORAGE;
140 API int pkgmgrinfo_client_request_enable_external_pkg(char *pkgid)
143 DBusMessage *message = NULL;
144 DBusMessage *reply = NULL;
146 retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
148 if(__get_pkg_location(pkgid) != PMINFO_EXTERNAL_STORAGE)
151 bus = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
152 retvm_if(bus == NULL, PMINFO_R_EINVAL, "dbus_bus_get() failed.");
154 message = dbus_message_new_method_call (SERVICE_NAME, PATH_NAME, INTERFACE_NAME, METHOD_NAME);
155 trym_if(message == NULL, "dbus_message_new_method_call() failed.");
157 dbus_message_append_args(message, DBUS_TYPE_STRING, &pkgid, DBUS_TYPE_INVALID);
159 reply = dbus_connection_send_with_reply_and_block(bus, message, -1, NULL);
160 trym_if(reply == NULL, "connection_send dbus fail");
163 dbus_connection_flush(bus);
165 dbus_message_unref(message);
167 dbus_message_unref(reply);