2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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://floralicense.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>
23 #include <livebox-errno.h>
35 enum pkgmgr_event_type type;
36 enum pkgmgr_status status;
40 pkgmgr_client *listen_pc;
43 Eina_List *install_event;
44 Eina_List *uninstall_event;
45 Eina_List *update_event;
46 Eina_List *download_event;
47 Eina_List *recover_event;
52 .install_event = NULL,
53 .uninstall_event = NULL,
55 .download_event = NULL,
56 .recover_event = NULL,
60 int (*cb)(const char *pkgname, enum pkgmgr_status status, double value, void *data);
64 static inline void invoke_install_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
67 struct event_item *item;
69 EINA_LIST_FOREACH(s_info.install_event, l, item) {
71 item->cb(pkgname, status, value, item->data);
75 static inline void invoke_uninstall_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
78 struct event_item *item;
80 EINA_LIST_FOREACH(s_info.uninstall_event, l, item) {
82 item->cb(pkgname, status, value, item->data);
86 static inline void invoke_update_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
89 struct event_item *item;
91 EINA_LIST_FOREACH(s_info.update_event, l, item) {
93 item->cb(pkgname, status, value, item->data);
97 static inline void invoke_download_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
100 struct event_item *item;
102 EINA_LIST_FOREACH(s_info.download_event, l, item) {
104 item->cb(pkgname, status, value, item->data);
108 static inline void invoke_recover_event_handler(const char *pkgname, enum pkgmgr_status status, double value)
111 struct event_item *item;
113 EINA_LIST_FOREACH(s_info.recover_event, l, item) {
115 item->cb(pkgname, status, value, item->data);
119 static inline void invoke_callback(const char *pkgname, struct item *item, double value)
121 switch (item->type) {
122 case PKGMGR_EVENT_DOWNLOAD:
123 invoke_download_event_handler(pkgname, item->status, value);
125 case PKGMGR_EVENT_UNINSTALL:
126 invoke_uninstall_event_handler(pkgname, item->status, value);
128 case PKGMGR_EVENT_INSTALL:
129 invoke_install_event_handler(pkgname, item->status, value);
131 case PKGMGR_EVENT_UPDATE:
132 invoke_update_event_handler(pkgname, item->status, value);
134 case PKGMGR_EVENT_RECOVER:
135 invoke_recover_event_handler(pkgname, item->status, value);
138 ErrPrint("Unknown type: %d\n", item->type);
143 static inline int is_valid_status(struct item *item, const char *status)
145 const char *expected_status;
147 switch (item->type) {
148 case PKGMGR_EVENT_DOWNLOAD:
149 expected_status = "download";
151 case PKGMGR_EVENT_UNINSTALL:
152 expected_status = "uninstall";
154 case PKGMGR_EVENT_INSTALL:
155 expected_status = "install";
157 case PKGMGR_EVENT_UPDATE:
158 expected_status = "update";
160 case PKGMGR_EVENT_RECOVER:
161 expected_status = "recover";
167 return !strcasecmp(status, expected_status);
170 static struct item *find_item(const char *pkgname)
176 ErrPrint("Package name is not valid\n");
180 EINA_LIST_FOREACH(s_info.item_list, l, item) {
181 if (strcmp(item->pkgname, pkgname))
187 DbgPrint("Package %s is not found\n", pkgname);
191 static int start_cb(const char *pkgname, const char *val, void *data)
195 DbgPrint("[%s] %s\n", pkgname, val);
197 item = calloc(1, sizeof(*item));
199 ErrPrint("Heap: %s\n", strerror(errno));
200 return LB_STATUS_ERROR_MEMORY;
203 item->pkgname = strdup(pkgname);
204 if (!item->pkgname) {
205 ErrPrint("Heap: %s\n", strerror(errno));
207 return LB_STATUS_ERROR_MEMORY;
210 item->status = PKGMGR_STATUS_START;
211 s_info.item_list = eina_list_append(s_info.item_list, item);
213 if (!strcasecmp(val, "download")) {
214 item->type = PKGMGR_EVENT_DOWNLOAD;
215 } else if (!strcasecmp(val, "uninstall")) {
216 item->type = PKGMGR_EVENT_UNINSTALL;
217 } else if (!strcasecmp(val, "install")) {
218 item->type = PKGMGR_EVENT_INSTALL;
219 } else if (!strcasecmp(val, "update")) {
220 item->type = PKGMGR_EVENT_UPDATE;
221 } else if (!strcasecmp(val, "recover")) {
222 item->type = PKGMGR_EVENT_RECOVER;
224 DbgFree(item->pkgname);
226 ErrPrint("Invalid val: %s\n", val);
227 return LB_STATUS_ERROR_INVALID;
230 invoke_callback(pkgname, item, 0.0f);
231 return LB_STATUS_SUCCESS;
234 static int icon_path_cb(const char *pkgname, const char *val, void *data)
238 DbgPrint("[%s] %s\n", pkgname, val);
240 item = find_item(pkgname);
242 return LB_STATUS_ERROR_NOT_EXIST;
247 item->icon = strdup(val);
249 ErrPrint("Heap: %s\n", strerror(errno));
250 return LB_STATUS_ERROR_MEMORY;
253 return LB_STATUS_SUCCESS;
256 static int command_cb(const char *pkgname, const char *val, void *data)
260 DbgPrint("[%s] %s\n", pkgname, val);
262 item = find_item(pkgname);
264 return LB_STATUS_ERROR_NOT_EXIST;
266 if (!is_valid_status(item, val)) {
267 DbgPrint("Invalid status: %d, %s\n", item->type, val);
268 return LB_STATUS_ERROR_INVALID;
271 item->status = PKGMGR_STATUS_COMMAND;
272 invoke_callback(pkgname, item, 0.0f);
273 return LB_STATUS_SUCCESS;
276 static int error_cb(const char *pkgname, const char *val, void *data)
281 DbgPrint("[%s] %s\n", pkgname, val);
283 item = find_item(pkgname);
285 return LB_STATUS_ERROR_NOT_EXIST;
287 item->status = PKGMGR_STATUS_ERROR;
288 invoke_callback(pkgname, item, 0.0f);
289 return LB_STATUS_SUCCESS;
292 static int change_pkgname_cb(const char *pkgname, const char *val, void *data)
297 DbgPrint("[%s] %s\n", pkgname, val);
299 item = find_item(pkgname);
301 return LB_STATUS_ERROR_NOT_EXIST;
303 new_pkgname = strdup(val);
305 ErrPrint("Heap: %s\n", strerror(errno));
306 return LB_STATUS_ERROR_MEMORY;
309 DbgFree(item->pkgname);
310 item->pkgname = new_pkgname;
311 return LB_STATUS_SUCCESS;
314 static int download_cb(const char *pkgname, const char *val, void *data)
320 DbgPrint("[%s] %s\n", pkgname, val);
322 item = find_item(pkgname);
324 DbgPrint("ITEM is not started from the start_cb\n");
325 return LB_STATUS_ERROR_INVALID;
328 if (item->type != PKGMGR_EVENT_DOWNLOAD) {
329 DbgPrint("TYPE is not \"download\" : %d\n", item->type);
330 item->type = PKGMGR_EVENT_DOWNLOAD;
333 switch (item->status) {
334 case PKGMGR_STATUS_START:
335 case PKGMGR_STATUS_COMMAND:
336 item->status = PKGMGR_STATUS_PROCESSING;
337 case PKGMGR_STATUS_PROCESSING:
340 ErrPrint("Invalid state [%s, %s]\n", pkgname, val);
341 return LB_STATUS_ERROR_INVALID;
345 if (sscanf(val, "%lf", &value) != 1)
346 value = (double)LB_STATUS_ERROR_INVALID;
348 value = (double)LB_STATUS_ERROR_INVALID;
351 invoke_download_event_handler(pkgname, item->status, value);
352 return LB_STATUS_SUCCESS;
355 static int progress_cb(const char *pkgname, const char *val, void *data)
361 DbgPrint("[%s] %s\n", pkgname, val);
363 item = find_item(pkgname);
365 ErrPrint("ITEM is not started from the start_cb\n");
366 return LB_STATUS_ERROR_INVALID;
369 switch (item->status) {
370 case PKGMGR_STATUS_START:
371 case PKGMGR_STATUS_COMMAND:
372 item->status = PKGMGR_STATUS_PROCESSING;
373 case PKGMGR_STATUS_PROCESSING:
376 ErrPrint("Invalid state [%s, %s]\n", pkgname, val);
377 return LB_STATUS_ERROR_INVALID;
381 if (sscanf(val, "%lf", &value) != 1)
382 value = (double)LB_STATUS_ERROR_INVALID;
384 value = (double)LB_STATUS_ERROR_INVALID;
387 invoke_callback(pkgname, item, value);
388 return LB_STATUS_SUCCESS;
391 static int end_cb(const char *pkgname, const char *val, void *data)
395 DbgPrint("[%s] %s\n", pkgname, val);
397 item = find_item(pkgname);
399 return LB_STATUS_ERROR_NOT_EXIST;
401 item->status = !strcasecmp(val, "ok") ? PKGMGR_STATUS_END : PKGMGR_STATUS_ERROR;
403 invoke_callback(pkgname, item, 0.0f);
405 s_info.item_list = eina_list_remove(s_info.item_list, item);
407 DbgFree(item->pkgname);
409 return LB_STATUS_SUCCESS;
412 static struct pkgmgr_handler {
414 int (*func)(const char *package, const char *val, void *data);
416 { "install_percent", progress_cb },
417 { "download_percent", download_cb },
418 { "start", start_cb },
420 { "change_pkg_name", change_pkgname_cb },
421 { "icon_path", icon_path_cb },
422 { "command", command_cb },
423 { "error", error_cb },
427 static int pkgmgr_cb(int req_id, const char *type, const char *pkgname, const char *key, const char *val, const void *pmsg, void *data)
432 for (i = 0; handler[i].key; i++) {
433 if (strcasecmp(key, handler[i].key))
436 ret = handler[i].func(pkgname, val, data);
437 DbgPrint("REQ[%d] pkgname[%s], type[%s], key[%s], val[%s], ret = %d\n",
438 req_id, pkgname, type, key, val, ret);
441 return LB_STATUS_SUCCESS;
444 HAPI int pkgmgr_init(void)
446 if (s_info.listen_pc)
447 return LB_STATUS_ERROR_ALREADY;
449 s_info.listen_pc = pkgmgr_client_new(PC_LISTENING);
450 if (!s_info.listen_pc)
451 return LB_STATUS_ERROR_FAULT;
453 if (pkgmgr_client_listen_status(s_info.listen_pc, pkgmgr_cb, NULL) != PKGMGR_R_OK)
454 return LB_STATUS_ERROR_FAULT;
456 return LB_STATUS_SUCCESS;
459 HAPI int pkgmgr_fini(void)
461 struct event_item *item;
464 if (!s_info.listen_pc)
465 return LB_STATUS_ERROR_INVALID;
467 if (pkgmgr_client_free(s_info.listen_pc) != PKGMGR_R_OK)
468 return LB_STATUS_ERROR_FAULT;
470 s_info.listen_pc = NULL;
472 EINA_LIST_FREE(s_info.download_event, item) {
476 EINA_LIST_FREE(s_info.uninstall_event, item) {
480 EINA_LIST_FREE(s_info.install_event, item) {
484 EINA_LIST_FREE(s_info.update_event, item) {
488 EINA_LIST_FREE(s_info.recover_event, item) {
492 EINA_LIST_FREE(s_info.item_list, ctx) {
493 DbgFree(ctx->pkgname);
498 return LB_STATUS_SUCCESS;
501 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)
503 struct event_item *item;
505 item = calloc(1, sizeof(*item));
507 ErrPrint("Heap: %s\n", strerror(errno));
508 return LB_STATUS_ERROR_MEMORY;
515 case PKGMGR_EVENT_DOWNLOAD:
516 s_info.download_event = eina_list_prepend(s_info.download_event, item);
518 case PKGMGR_EVENT_UNINSTALL:
519 s_info.uninstall_event = eina_list_prepend(s_info.uninstall_event, item);
521 case PKGMGR_EVENT_INSTALL:
522 s_info.install_event = eina_list_prepend(s_info.install_event, item);
524 case PKGMGR_EVENT_UPDATE:
525 s_info.update_event = eina_list_prepend(s_info.update_event, item);
527 case PKGMGR_EVENT_RECOVER:
528 s_info.recover_event = eina_list_prepend(s_info.recover_event, item);
532 return LB_STATUS_ERROR_INVALID;
535 return LB_STATUS_SUCCESS;
538 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)
540 struct event_item *item;
545 case PKGMGR_EVENT_DOWNLOAD:
546 EINA_LIST_FOREACH(s_info.download_event, l, item) {
547 if (item->cb == cb && item->data == data) {
548 s_info.download_event = eina_list_remove(s_info.download_event, item);
555 case PKGMGR_EVENT_UNINSTALL:
556 EINA_LIST_FOREACH(s_info.uninstall_event, l, item) {
557 if (item->cb == cb && item->data == data) {
558 s_info.uninstall_event = eina_list_remove(s_info.uninstall_event, item);
565 case PKGMGR_EVENT_INSTALL:
566 EINA_LIST_FOREACH(s_info.install_event, l, item) {
567 if (item->cb == cb && item->data == data) {
568 s_info.install_event = eina_list_remove(s_info.install_event, item);
575 case PKGMGR_EVENT_UPDATE:
576 EINA_LIST_FOREACH(s_info.update_event, l, item) {
577 if (item->cb == cb && item->data == data) {
578 s_info.update_event = eina_list_remove(s_info.update_event, item);
585 case PKGMGR_EVENT_RECOVER:
586 EINA_LIST_FOREACH(s_info.recover_event, l, item) {
587 if (item->cb == cb && item->data == data) {
588 s_info.recover_event = eina_list_remove(s_info.recover_event, item);
596 ErrPrint("Invalid type\n");