2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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.
22 #include <package-manager.h>
34 enum pkgmgr_event_type type;
35 enum pkgmgr_status status;
39 pkgmgr_client *listen_pc;
42 Eina_List *install_event;
43 Eina_List *uninstall_event;
44 Eina_List *update_event;
45 Eina_List *download_event;
46 Eina_List *recover_event;
51 .install_event = NULL,
52 .uninstall_event = NULL,
54 .download_event = NULL,
55 .recover_event = NULL,
59 int (*cb)(const char *pkgname, enum pkgmgr_status status, double value, void *data);
63 static inline void invoke_install_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
66 struct event_item *item;
68 EINA_LIST_FOREACH(s_info.install_event, l, item) {
70 item->cb(pkgname, status, value, item->data);
74 static inline void invoke_uninstall_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
77 struct event_item *item;
79 EINA_LIST_FOREACH(s_info.uninstall_event, l, item) {
81 item->cb(pkgname, status, value, item->data);
85 static inline void invoke_update_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
88 struct event_item *item;
90 EINA_LIST_FOREACH(s_info.update_event, l, item) {
92 item->cb(pkgname, status, value, item->data);
96 static inline void invoke_download_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
99 struct event_item *item;
101 EINA_LIST_FOREACH(s_info.download_event, l, item) {
103 item->cb(pkgname, status, value, item->data);
107 static inline void invoke_recover_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
110 struct event_item *item;
112 EINA_LIST_FOREACH(s_info.recover_event, l, item) {
114 item->cb(pkgname, status, value, item->data);
118 static inline void invoke_callback(const char *pkgname, struct item *item, double value)
120 switch (item->type) {
121 case PKGMGR_EVENT_DOWNLOAD:
122 invoke_download_event_handler(pkgname, item->status, value);
124 case PKGMGR_EVENT_UNINSTALL:
125 invoke_uninstall_event_handler(pkgname, item->status, value);
127 case PKGMGR_EVENT_INSTALL:
128 invoke_install_event_handler(pkgname, item->status, value);
130 case PKGMGR_EVENT_UPDATE:
131 invoke_update_event_handler(pkgname, item->status, value);
133 case PKGMGR_EVENT_RECOVER:
134 invoke_recover_event_handler(pkgname, item->status, value);
137 ErrPrint("Unknown type: %d\n", item->type);
142 static inline int is_valid_status(struct item *item, const char *status)
144 const char *expected_status;
146 switch (item->type) {
147 case PKGMGR_EVENT_DOWNLOAD:
148 expected_status = "download";
150 case PKGMGR_EVENT_UNINSTALL:
151 expected_status = "uninstall";
153 case PKGMGR_EVENT_INSTALL:
154 expected_status = "install";
156 case PKGMGR_EVENT_UPDATE:
157 expected_status = "update";
159 case PKGMGR_EVENT_RECOVER:
160 expected_status = "recover";
166 return !strcasecmp(status, expected_status);
169 static struct item *find_item(const char *pkgname)
175 ErrPrint("Package name is not valid\n");
179 EINA_LIST_FOREACH(s_info.item_list, l, item) {
180 if (strcmp(item->pkgname, pkgname))
186 DbgPrint("Package %s is not found\n", pkgname);
190 static int start_cb(const char *pkgname, const char *val, void *data)
194 DbgPrint("[%s] %s\n", pkgname, val);
196 item = calloc(1, sizeof(*item));
198 ErrPrint("Heap: %s\n", strerror(errno));
202 item->pkgname = strdup(pkgname);
203 if (!item->pkgname) {
204 ErrPrint("Heap: %s\n", strerror(errno));
209 item->status = PKGMGR_STATUS_START;
210 s_info.item_list = eina_list_append(s_info.item_list, item);
212 if (!strcasecmp(val, "download")) {
213 item->type = PKGMGR_EVENT_DOWNLOAD;
214 } else if (!strcasecmp(val, "uninstall")) {
215 item->type = PKGMGR_EVENT_UNINSTALL;
216 } else if (!strcasecmp(val, "install")) {
217 item->type = PKGMGR_EVENT_INSTALL;
218 } else if (!strcasecmp(val, "update")) {
219 item->type = PKGMGR_EVENT_UPDATE;
220 } else if (!strcasecmp(val, "recover")) {
221 item->type = PKGMGR_EVENT_RECOVER;
223 DbgFree(item->pkgname);
225 ErrPrint("Invalid val: %s\n", val);
229 invoke_callback(pkgname, item, 0.0f);
233 static int icon_path_cb(const char *pkgname, const char *val, void *data)
237 DbgPrint("[%s] %s\n", pkgname, val);
239 item = find_item(pkgname);
246 item->icon = strdup(val);
248 ErrPrint("Heap: %s\n", strerror(errno));
255 static int command_cb(const char *pkgname, const char *val, void *data)
259 DbgPrint("[%s] %s\n", pkgname, val);
261 item = find_item(pkgname);
265 if (!is_valid_status(item, val)) {
266 DbgPrint("Invalid status: %d, %s\n", item->type, val);
270 item->status = PKGMGR_STATUS_COMMAND;
271 invoke_callback(pkgname, item, 0.0f);
275 static int error_cb(const char *pkgname, const char *val, void *data)
280 DbgPrint("[%s] %s\n", pkgname, val);
282 item = find_item(pkgname);
286 item->status = PKGMGR_STATUS_ERROR;
287 invoke_callback(pkgname, item, 0.0f);
291 static int change_pkgname_cb(const char *pkgname, const char *val, void *data)
296 DbgPrint("[%s] %s\n", pkgname, val);
298 item = find_item(pkgname);
302 new_pkgname = strdup(val);
304 ErrPrint("Heap: %s\n", strerror(errno));
308 DbgFree(item->pkgname);
309 item->pkgname = new_pkgname;
313 static int download_cb(const char *pkgname, const char *val, void *data)
319 DbgPrint("[%s] %s\n", pkgname, val);
321 item = find_item(pkgname);
323 DbgPrint("ITEM is not started from the start_cb\n");
327 if (item->type != PKGMGR_EVENT_DOWNLOAD) {
328 DbgPrint("TYPE is not \"download\" : %d\n", item->type);
329 item->type = PKGMGR_EVENT_DOWNLOAD;
332 switch (item->status) {
333 case PKGMGR_STATUS_START:
334 case PKGMGR_STATUS_COMMAND:
335 item->status = PKGMGR_STATUS_PROCESSING;
336 case PKGMGR_STATUS_PROCESSING:
339 ErrPrint("Invalid state [%s, %s]\n", pkgname, val);
344 if (sscanf(val, "%lf", &value) != 1)
345 value = (double)-EINVAL;
347 value = (double)-EINVAL;
350 invoke_download_event_handler(pkgname, item->status, value);
354 static int progress_cb(const char *pkgname, const char *val, void *data)
360 DbgPrint("[%s] %s\n", pkgname, val);
362 item = find_item(pkgname);
364 ErrPrint("ITEM is not started from the start_cb\n");
368 switch (item->status) {
369 case PKGMGR_STATUS_START:
370 case PKGMGR_STATUS_COMMAND:
371 item->status = PKGMGR_STATUS_PROCESSING;
372 case PKGMGR_STATUS_PROCESSING:
375 ErrPrint("Invalid state [%s, %s]\n", pkgname, val);
380 if (sscanf(val, "%lf", &value) != 1)
381 value = (double)-EINVAL;
383 value = (double)-EINVAL;
386 invoke_callback(pkgname, item, value);
390 static int end_cb(const char *pkgname, const char *val, void *data)
394 DbgPrint("[%s] %s\n", pkgname, val);
396 item = find_item(pkgname);
400 item->status = !strcasecmp(val, "ok") ? PKGMGR_STATUS_END : PKGMGR_STATUS_ERROR;
402 invoke_callback(pkgname, item, 0.0f);
404 s_info.item_list = eina_list_remove(s_info.item_list, item);
406 DbgFree(item->pkgname);
411 static struct pkgmgr_handler {
413 int (*func)(const char *package, const char *val, void *data);
415 { "install_percent", progress_cb },
416 { "download_percent", download_cb },
417 { "start", start_cb },
419 { "change_pkg_name", change_pkgname_cb },
420 { "icon_path", icon_path_cb },
421 { "command", command_cb },
422 { "error", error_cb },
426 static int pkgmgr_cb(int req_id, const char *type, const char *pkgname, const char *key, const char *val, const void *pmsg, void *data)
431 for (i = 0; handler[i].key; i++) {
432 if (strcasecmp(key, handler[i].key))
435 ret = handler[i].func(pkgname, val, data);
436 DbgPrint("REQ[%d] pkgname[%s], type[%s], key[%s], val[%s], ret = %d\n",
437 req_id, pkgname, type, key, val, ret);
443 HAPI int pkgmgr_init(void)
445 if (s_info.listen_pc)
448 s_info.listen_pc = pkgmgr_client_new(PC_LISTENING);
449 if (!s_info.listen_pc)
452 if (pkgmgr_client_listen_status(s_info.listen_pc, pkgmgr_cb, NULL) != PKGMGR_R_OK)
458 HAPI int pkgmgr_fini(void)
460 struct event_item *item;
463 if (!s_info.listen_pc)
466 if (pkgmgr_client_free(s_info.listen_pc) != PKGMGR_R_OK)
469 s_info.listen_pc = NULL;
471 EINA_LIST_FREE(s_info.download_event, item) {
475 EINA_LIST_FREE(s_info.uninstall_event, item) {
479 EINA_LIST_FREE(s_info.install_event, item) {
483 EINA_LIST_FREE(s_info.update_event, item) {
487 EINA_LIST_FREE(s_info.recover_event, item) {
491 EINA_LIST_FREE(s_info.item_list, ctx) {
492 DbgFree(ctx->pkgname);
500 HAPI int pkgmgr_add_event_callback(enum pkgmgr_event_type type, int (*cb)(const char *pkgname, enum pkgmgr_status status, double value, void *data), void *data)
502 struct event_item *item;
504 item = calloc(1, sizeof(*item));
506 ErrPrint("Heap: %s\n", strerror(errno));
514 case PKGMGR_EVENT_DOWNLOAD:
515 s_info.download_event = eina_list_prepend(s_info.download_event, item);
517 case PKGMGR_EVENT_UNINSTALL:
518 s_info.uninstall_event = eina_list_prepend(s_info.uninstall_event, item);
520 case PKGMGR_EVENT_INSTALL:
521 s_info.install_event = eina_list_prepend(s_info.install_event, item);
523 case PKGMGR_EVENT_UPDATE:
524 s_info.update_event = eina_list_prepend(s_info.update_event, item);
526 case PKGMGR_EVENT_RECOVER:
527 s_info.recover_event = eina_list_prepend(s_info.recover_event, item);
537 HAPI void *pkgmgr_del_event_callback(enum pkgmgr_event_type type, int (*cb)(const char *pkgname, enum pkgmgr_status status, double value, void *data), void *data)
539 struct event_item *item;
544 case PKGMGR_EVENT_DOWNLOAD:
545 EINA_LIST_FOREACH(s_info.download_event, l, item) {
546 if (item->cb == cb && item->data == data) {
547 s_info.download_event = eina_list_remove(s_info.download_event, item);
554 case PKGMGR_EVENT_UNINSTALL:
555 EINA_LIST_FOREACH(s_info.uninstall_event, l, item) {
556 if (item->cb == cb && item->data == data) {
557 s_info.uninstall_event = eina_list_remove(s_info.uninstall_event, item);
564 case PKGMGR_EVENT_INSTALL:
565 EINA_LIST_FOREACH(s_info.install_event, l, item) {
566 if (item->cb == cb && item->data == data) {
567 s_info.install_event = eina_list_remove(s_info.install_event, item);
574 case PKGMGR_EVENT_UPDATE:
575 EINA_LIST_FOREACH(s_info.update_event, l, item) {
576 if (item->cb == cb && item->data == data) {
577 s_info.update_event = eina_list_remove(s_info.update_event, item);
584 case PKGMGR_EVENT_RECOVER:
585 EINA_LIST_FOREACH(s_info.recover_event, l, item) {
586 if (item->cb == cb && item->data == data) {
587 s_info.recover_event = eina_list_remove(s_info.recover_event, item);
595 ErrPrint("Invalid type\n");