From 5cb01bf9f4f90bc6a5e2b75b400de61977c21e71 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 26 Feb 2016 15:57:48 +0900 Subject: [PATCH 01/16] Fix the exception about checking widget feature Change-Id: I5ab197ba3ec80bae9a37d1a6cc0b45f4d1f46c5a Signed-off-by: Hwankyu Jhun --- src/widget_app.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/widget_app.c b/src/widget_app.c index b77fe74..905b186 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -119,7 +119,7 @@ static gint __comp_by_id(gconstpointer a, gconstpointer b) { widget_context_s *wc = (widget_context_s*)a; - return strcmp(wc->id, (const char*)b); + return strcmp(wc->id, (const char*)b); } static widget_context_s* __find_context_by_id(const char *id) @@ -173,13 +173,11 @@ static int __instance_create(widget_class_h handle, const char *id, bundle *b) bundle_get_str(b, WIDGET_K_WIDTH, &w_str); bundle_get_str(b, WIDGET_K_HEIGHT, &h_str); - if (w_str) { + if (w_str) w = (int)g_ascii_strtoll(w_str, &remain, 10); - } - if (h_str) { + if (h_str) h = (int)g_ascii_strtoll(h_str, &remain, 10); - } contexts = g_list_append(contexts, wc); @@ -578,14 +576,20 @@ EXPORT_API int widget_app_get_elm_win(widget_context_h context, widget_class_h _widget_class_create(widget_class_s *prev, const char *class_id, widget_instance_lifecycle_callback_s callback, void *user_data) { + widget_class_s *wc; + if (!_is_widget_feature_enabled()) { _E("not supported"); set_last_result(WIDGET_ERROR_NOT_SUPPORTED); return NULL; } - widget_class_s *wc = (widget_class_s*)malloc(sizeof(widget_class_s)); + if (class_id == NULL) { + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + wc = (widget_class_s *)malloc(sizeof(widget_class_s)); if (wc == NULL) { _E("failed to malloc : %s", __FUNCTION__); set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); @@ -609,27 +613,11 @@ widget_class_h _widget_class_create(widget_class_s *prev, const char *class_id, EXPORT_API widget_class_h widget_app_class_add(widget_class_h widget_class, const char *class_id, widget_instance_lifecycle_callback_s callback, void *user_data) { - if (!_is_widget_feature_enabled()) { - _E("not supported"); - set_last_result(WIDGET_ERROR_INVALID_PARAMETER); - return NULL; - } - - if (class_id == NULL) { - set_last_result(WIDGET_ERROR_INVALID_PARAMETER); - return NULL; - } - return _widget_class_create(widget_class, class_id, callback, user_data); } EXPORT_API widget_class_h widget_app_class_create(widget_instance_lifecycle_callback_s callback, void *user_data) { - if (!_is_widget_feature_enabled()) { - set_last_result(WIDGET_ERROR_INVALID_PARAMETER); - return NULL; - } - return _widget_class_create(class_provider, appid, callback, user_data); } -- 2.7.4 From cf58e4b97a8c72028d7a88649854cb33d7c0400a Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Wed, 9 Mar 2016 12:06:26 +0900 Subject: [PATCH 02/16] Enable compiler option -Werror Change-Id: I28bb59cb233d9f988f80086301188229a54d46ac Signed-off-by: Junghoon Park --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 495fac4..d57515e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -Wall") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") SET(CMAKE_SKIP_BUILD_RPATH TRUE) -- 2.7.4 From 95a4e10ca6d551b1830e97e1763062615af74a9e Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Wed, 30 Mar 2016 20:01:03 +0900 Subject: [PATCH 03/16] fix widget status notify Change-Id: I7d4792423d1c67891d67b93172a1f638cae556e6 --- src/widget_app.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/widget_app.c b/src/widget_app.c index 905b186..b856c16 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -144,6 +144,7 @@ static int __send_update_status(const char *class_id, const char *instance_id, bundle_add_str(b, WIDGET_K_INSTANCE, instance_id); bundle_add_byte(b, WIDGET_K_STATUS, &status, sizeof(int)); + _E("send update %s(%d) to %s", instance_id, status, viewer_endpoint); aul_app_com_send(viewer_endpoint, b); if (extra == NULL) @@ -182,7 +183,6 @@ static int __instance_create(widget_class_h handle, const char *id, bundle *b) contexts = g_list_append(contexts, wc); handle->ops.create(wc, b, w, h, handle->user_data); - ret = __send_update_status(handle->classid, wc->id, WIDGET_INSTANCE_EVENT_CREATE, b, 0); return ret; @@ -336,6 +336,8 @@ static int __before_loop(int argc, char **argv) bundle_get_str(kb, AUL_K_WAYLAND_WORKING_DIR, &xdg_runtime_dir); bundle_get_str(kb, AUL_K_WAYLAND_DISPLAY, &wayland_display); bundle_get_str(kb, WIDGET_K_ENDPOINT, &viewer_endpoint); + _E("viewer endpoint :%s", viewer_endpoint); + viewer_endpoint = strdup(viewer_endpoint); if (xdg_runtime_dir) setenv("XDG_RUNTIME_DIR", xdg_runtime_dir, 1); @@ -381,6 +383,9 @@ static void __after_loop() if (app_ops->terminate) app_ops->terminate(app_user_data); + if (viewer_endpoint) + free(viewer_endpoint); + elm_shutdown(); } -- 2.7.4 From 013d5c1e938cd23dbeed7bbf019f634d7ec5c506 Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Wed, 30 Mar 2016 21:10:11 +0900 Subject: [PATCH 04/16] Add NULL check for endpoint Change-Id: I3d1819d9f30784c785fd680593b5e9cb1c4cc65f --- src/widget_app.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/widget_app.c b/src/widget_app.c index b856c16..f515704 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -336,8 +336,12 @@ static int __before_loop(int argc, char **argv) bundle_get_str(kb, AUL_K_WAYLAND_WORKING_DIR, &xdg_runtime_dir); bundle_get_str(kb, AUL_K_WAYLAND_DISPLAY, &wayland_display); bundle_get_str(kb, WIDGET_K_ENDPOINT, &viewer_endpoint); - _E("viewer endpoint :%s", viewer_endpoint); - viewer_endpoint = strdup(viewer_endpoint); + if (viewer_endpoint) { + _E("viewer endpoint :%s", viewer_endpoint); + viewer_endpoint = strdup(viewer_endpoint); + } else { + _E("endpoint is missing"); + } if (xdg_runtime_dir) setenv("XDG_RUNTIME_DIR", xdg_runtime_dir, 1); -- 2.7.4 From f23e0188ab8db88c7d98391f1e4b451a8cd02951 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 25 Mar 2016 21:48:38 +0900 Subject: [PATCH 05/16] Adjust coding rules Change-Id: Id7b804be392640d7459a91019e180f08a83f1a52 Signed-off-by: Hwankyu Jhun --- doc/appcore-widget_doc.h | 2 +- include/widget_app.h | 17 ++++--- include/widget_app_efl.h | 5 +- include/widget_app_internal.h | 31 +++++------- src/widget-i18n.c | 14 +++--- src/widget-log.h | 72 ++++++++++++++-------------- src/widget-private.h | 7 +-- src/widget_app.c | 109 ++++++++++++++++++++++++++---------------- src/widget_error.c | 32 ++++--------- 9 files changed, 150 insertions(+), 139 deletions(-) diff --git a/doc/appcore-widget_doc.h b/doc/appcore-widget_doc.h index e9fe5a5..1a83d63 100755 --- a/doc/appcore-widget_doc.h +++ b/doc/appcore-widget_doc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/include/widget_app.h b/include/widget_app.h index 67b6457..3c935cd 100755 --- a/include/widget_app.h +++ b/include/widget_app.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. @@ -51,13 +51,13 @@ typedef enum widget_app_destroy_type { * @brief The handle for widget class. * @since_tizen 2.3.1 */ -typedef struct _widget_class* widget_class_h; +typedef struct _widget_class *widget_class_h; /** * @brief The handle for widget context. * @since_tizen 2.3.1 */ -typedef struct _widget_context* widget_context_h; +typedef struct _widget_context *widget_context_h; /** * @brief Called when the widget instance starts. @@ -164,8 +164,7 @@ typedef int (*widget_instance_update_cb)(widget_context_h context, bundle *conte * @brief The structure for lifecycle of a widget instance. * @since_tizen 2.3.1 */ -typedef struct -{ +typedef struct { widget_instance_create_cb create; /**< The callback function is called after widget instance is created. */ widget_instance_destroy_cb destroy; /**< The callback function is called before widget instance is destroyed. */ widget_instance_pause_cb pause; /**< The callback function is called when the widget is invisible. */ @@ -213,8 +212,7 @@ typedef void (*widget_app_terminate_cb)(void *user_data); * @brief The structure for lifecycle of a widget application. * @since_tizen 2.3.1 */ -typedef struct -{ +typedef struct { widget_app_create_cb create; /**< The callback function is called before the main loop of the application starts. */ widget_app_terminate_cb terminate; /**< This callback function is called once after the main loop of the application exits. */ } widget_app_lifecycle_callback_s; @@ -321,7 +319,7 @@ int widget_app_foreach_context(widget_context_cb callback, void *data); * @see watch_app_remove_event_handler() */ int widget_app_add_event_handler(app_event_handler_h *event_handler, app_event_type_e event_type, - app_event_cb callback, void *user_data); + app_event_cb callback, void *user_data); /** * @brief Removes registered event handler. @@ -352,7 +350,7 @@ int widget_app_remove_event_handler(app_event_handler_h event_handler); * @remark You must not free returned Widget ID * @see get_last_result() */ -const char* widget_app_get_id(widget_context_h context); +const char *widget_app_get_id(widget_context_h context); /** * @brief Makes a class for widget instances. @@ -456,3 +454,4 @@ widget_class_h widget_app_class_add(widget_class_h widget_class, const char *cla #endif #endif /* __TIZEN_APPFW_WIDGET_APP_H__ */ + diff --git a/include/widget_app_efl.h b/include/widget_app_efl.h index 4bd1765..fd1a0c0 100644 --- a/include/widget_app_efl.h +++ b/include/widget_app_efl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. @@ -52,4 +52,5 @@ int widget_app_get_elm_win(widget_context_h context, Evas_Object **win); } #endif -#endif +#endif /* __TIZEN_APPFW_WIDGET_APP_EFL_H__ */ + diff --git a/include/widget_app_internal.h b/include/widget_app_internal.h index 260f4f3..024cfa9 100644 --- a/include/widget_app_internal.h +++ b/include/widget_app_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. @@ -27,18 +27,14 @@ extern "C" { * For in-house applications * */ - -typedef struct -{ - struct __pointer - { +typedef struct { + struct __pointer { double x; double y; int down; } pointer; - struct __part - { + struct __part { double sx; double sy; double ex; @@ -47,28 +43,27 @@ typedef struct } widget_obj_event_info_s; -typedef int (*widget_instance_text_signal_cb)(widget_context_h context, const char *signal_name, - const char *source, widget_obj_event_info_s *info, void *user_data); +typedef int (*widget_instance_text_signal_cb)(widget_context_h context, + const char *signal_name, const char *source, + widget_obj_event_info_s *info, void *user_data); -typedef struct _widget_obj_private_ops -{ +typedef struct _widget_obj_private_ops { widget_instance_text_signal_cb text_signal; } widget_obj_private_ops_s; typedef struct _widget_class_factory_full widget_class_factory_full_s; -typedef const widget_class_factory_full_s* (*widget_class_factory_override_text_signal)(widget_instance_text_signal_cb op); - +typedef const widget_class_factory_full_s *(*widget_class_factory_override_text_signal)(widget_instance_text_signal_cb op); typedef widget_class_h (*_widget_class_factory_operation_make)(widget_instance_lifecycle_callback_s callback); -struct _widget_class_factory_full -{ +struct _widget_class_factory_full { widget_class_factory_override_text_signal override_text_signal; }; -const widget_class_factory_full_s* widget_app_get_class_factory(void); +const widget_class_factory_full_s *widget_app_get_class_factory(void); #ifdef __cplusplus } #endif -#endif +#endif /* __TIZEN_APPFW_WIDGET_APP_INTERNAL_H__ */ + diff --git a/src/widget-i18n.c b/src/widget-i18n.c index 23cbd3b..91804e2 100755 --- a/src/widget-i18n.c +++ b/src/widget-i18n.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. @@ -33,18 +33,17 @@ void _update_lang(void) { + char *r; char *lang = vconf_get_str(VCONFKEY_LANGSET); if (lang) { setenv("LANG", lang, 1); setenv("LC_MESSAGES", lang, 1); - char *r = setlocale(LC_ALL, ""); + r = setlocale(LC_ALL, ""); if (r == NULL) { r = setlocale(LC_ALL, lang); - if (r) _D("*****appcore setlocale=%s\n", r); - } free(lang); } else { @@ -70,8 +69,8 @@ void _update_region(void) setenv("LC_TELEPHONE", region, 1); setenv("LC_MEASUREMENT", region, 1); setenv("LC_IDENTIFICATION", region, 1); - r = setlocale(LC_ALL, ""); + r = setlocale(LC_ALL, ""); if (r != NULL) _D("*****appcore setlocale=%s\n", r); @@ -85,6 +84,7 @@ static int __set_i18n(const char *domain) { char *r; char dirname[PATH_MAX] = {0, }; + char *lang; if (domain == NULL) { errno = EINVAL; @@ -97,15 +97,13 @@ static int __set_i18n(const char *domain) r = setlocale(LC_ALL, ""); /* if locale is not set properly, try again to set as language base */ if (r == NULL) { - char *lang = vconf_get_str(VCONFKEY_LANGSET); + lang = vconf_get_str(VCONFKEY_LANGSET); r = setlocale(LC_ALL, lang); - if (r) _D("*****appcore setlocale=%s\n", r); if (lang) free(lang); - } if (r == NULL) _E("appcore: setlocale() error"); diff --git a/src/widget-log.h b/src/widget-log.h index e8eb56d..980f3e3 100755 --- a/src/widget-log.h +++ b/src/widget-log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. @@ -45,37 +45,39 @@ #define _W(...) LOGW(__VA_ARGS__) #endif -#define _warn_if(expr, fmt, arg...) do { \ - if (expr) { \ - _ERR(fmt, ##arg); \ - } \ - } while (0) - -#define _ret_if(expr) do { \ - if (expr) { \ - return; \ - } \ - } while (0) - -#define _retv_if(expr, val) do { \ - if (expr) { \ - return (val); \ - } \ - } while (0) - -#define _retm_if(expr, fmt, arg...) do { \ - if (expr) { \ - _ERR(fmt, ##arg); \ - return; \ - } \ - } while (0) - -#define _retvm_if(expr, val, fmt, arg...) do { \ - if (expr) { \ - _ERR(fmt, ##arg); \ - return (val); \ - } \ - } while (0) - - -#endif //__APPFW_WIDGET_LOG_H_ +#define _warn_if(expr, fmt, arg...) \ + do { \ + if (expr) \ + _ERR(fmt, ##arg); \ + } while (0) + +#define _ret_if(expr) \ + do { \ + if (expr) \ + return; \ + } while (0) + +#define _retv_if(expr, val) \ + do { \ + if (expr) \ + return (val); \ + } while (0) + +#define _retm_if(expr, fmt, arg...) \ + do { \ + if (expr) { \ + _ERR(fmt, ##arg); \ + return; \ + } \ + } while (0) + +#define _retvm_if(expr, val, fmt, arg...) \ + do { \ + if (expr) { \ + _ERR(fmt, ##arg); \ + return (val); \ + } \ + } while (0) + +#endif /* __APPFW_WIDGET_LOG_H_ */ + diff --git a/src/widget-private.h b/src/widget-private.h index 662b734..ef6d32c 100644 --- a/src/widget-private.h +++ b/src/widget-private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. @@ -24,10 +24,11 @@ #define FEATURE_SHELL_APPWIDGET "http://tizen.org/feature/shell.appwidget" - int _set_i18n(const char *domainname); void _update_lang(void); void _update_region(void); -int widget_app_error(widget_error_e error, const char* function, const char *description); +int widget_app_error(widget_error_e error, const char *function, + const char *description); #endif /* __APPCORE_WIDGET_PRIVATE_H__ */ + diff --git a/src/widget_app.c b/src/widget_app.c index f515704..82f1f89 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. @@ -117,14 +117,14 @@ static inline bool _is_widget_feature_enabled(void) static gint __comp_by_id(gconstpointer a, gconstpointer b) { - widget_context_s *wc = (widget_context_s*)a; + widget_context_s *wc = (widget_context_s *)a; - return strcmp(wc->id, (const char*)b); + return strcmp(wc->id, (const char *)b); } -static widget_context_s* __find_context_by_id(const char *id) +static widget_context_s *__find_context_by_id(const char *id) { - GList* ret = g_list_find_custom(contexts, id, __comp_by_id); + GList *ret = g_list_find_custom(contexts, id, __comp_by_id); if (ret == NULL) return NULL; @@ -183,21 +183,25 @@ static int __instance_create(widget_class_h handle, const char *id, bundle *b) contexts = g_list_append(contexts, wc); handle->ops.create(wc, b, w, h, handle->user_data); - ret = __send_update_status(handle->classid, wc->id, WIDGET_INSTANCE_EVENT_CREATE, b, 0); + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_CREATE, b, 0); return ret; } -static int __instance_destroy(widget_class_h handle, const char *id, widget_destroy_type_e reason, bundle *b) +static int __instance_destroy(widget_class_h handle, const char *id, + widget_destroy_type_e reason, bundle *b) { widget_context_s *wc = __find_context_by_id(id); int ret = 0; if (wc) { wc->state = WC_TERMINATED; - handle->ops.destroy(wc, (widget_app_destroy_type_e)reason, b, handle->user_data); + handle->ops.destroy(wc, (widget_app_destroy_type_e)reason, b, + handle->user_data); - ret = __send_update_status(handle->classid, id, WIDGET_INSTANCE_EVENT_TERMINATE, b, 0); + ret = __send_update_status(handle->classid, id, + WIDGET_INSTANCE_EVENT_TERMINATE, b, 0); contexts = g_list_remove(contexts, wc); @@ -212,7 +216,8 @@ static int __instance_destroy(widget_class_h handle, const char *id, widget_dest return ret; } -static widget_class_h __find_class_handler(const char *class_id, widget_class_h handle) +static widget_class_h __find_class_handler(const char *class_id, + widget_class_h handle) { if (!class_id || !handle) return NULL; @@ -267,7 +272,8 @@ static void __control(bundle *b) } else if (strcmp(operation, "destroy") == 0) { bundle_get_str(b, WIDGET_K_REASON, &reason); if (reason) - destroy_type = (int)g_ascii_strtoll(reason, &remain, 10); + destroy_type = (int)g_ascii_strtoll(reason, &remain, + 10); __instance_destroy(handle, id, destroy_type, b); } else if (strcmp(operation, "resume") == 0) { @@ -296,9 +302,10 @@ static int __aul_handler(aul_type type, bundle *b, void *data) case AUL_START: if (b) { bundle_get_str(b, WIDGET_K_CALLER, &caller); - if (caller) - caller_pid = g_ascii_strtoll(caller, &remain, 10); - else { + if (caller) { + caller_pid = g_ascii_strtoll(caller, &remain, + 10); + } else { /* using caller appid and query pid using caller appid? */ _E("no caller pid"); } @@ -359,14 +366,16 @@ static int __before_loop(int argc, char **argv) r = aul_launch_init(__aul_handler, NULL); if (r < 0) { - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, - "Fail to call the aul_launch_init"); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, + "Fail to call the aul_launch_init"); } r = aul_launch_argv_handler(argc, argv); if (r < 0) { - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, - "Fail to call the aul_launch_argv_handler"); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, + "Fail to call the aul_launch_argv_handler"); } r = app_get_id(&appid); @@ -375,8 +384,8 @@ static int __before_loop(int argc, char **argv) class_provider = app_ops->create(app_user_data); if (class_provider == NULL) { - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, - "widget_class is NULL"); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, "widget_class is NULL"); } return WIDGET_ERROR_NONE; @@ -394,7 +403,7 @@ static void __after_loop() } EXPORT_API int widget_app_main(int argc, char **argv, - widget_app_lifecycle_callback_s *callback, void *user_data) + widget_app_lifecycle_callback_s *callback, void *user_data) { int r; @@ -404,10 +413,14 @@ EXPORT_API int widget_app_main(int argc, char **argv, } if (argc <= 0 || argv == NULL || callback == NULL) - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); if (callback->create == NULL) - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, "widget_app_create_cb() callback must be registered"); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, + "widget_app_create_cb() callback must be " + "registered"); app_ops = callback; app_user_data = user_data; @@ -467,7 +480,8 @@ EXPORT_API int widget_app_terminate_context(widget_context_h context) } if (context == NULL) - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); g_idle_add(__finish_event_cb, context); return WIDGET_ERROR_NONE; @@ -487,8 +501,8 @@ EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data) } EXPORT_API int widget_app_add_event_handler(app_event_handler_h *event_handler, - app_event_type_e event_type, app_event_cb callback, - void *user_data) + app_event_type_e event_type, app_event_cb callback, + void *user_data) { if (!_is_widget_feature_enabled()) { _E("not supported"); @@ -530,7 +544,7 @@ EXPORT_API int widget_app_remove_event_handler(app_event_handler_h return WIDGET_ERROR_NONE; } -EXPORT_API const char* widget_app_get_id(widget_context_h context) +EXPORT_API const char *widget_app_get_id(widget_context_h context) { if (!_is_widget_feature_enabled()) { _E("not supported"); @@ -549,7 +563,7 @@ EXPORT_API const char* widget_app_get_id(widget_context_h context) EXPORT_API int widget_app_get_elm_win(widget_context_h context, Evas_Object **win) { - widget_context_s *cxt = (widget_context_s*)context; + widget_context_s *cxt = (widget_context_s *)context; Evas_Object *ret_win; Ecore_Wl_Window *wl_win; @@ -559,7 +573,8 @@ EXPORT_API int widget_app_get_elm_win(widget_context_h context, } if (context == NULL || win == NULL) - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); ret_win = elm_win_add(NULL, cxt->id, ELM_WIN_BASIC); if (ret_win == NULL) { @@ -619,13 +634,16 @@ widget_class_h _widget_class_create(widget_class_s *prev, const char *class_id, return wc; } -EXPORT_API widget_class_h widget_app_class_add(widget_class_h widget_class, const char *class_id, +EXPORT_API widget_class_h widget_app_class_add(widget_class_h widget_class, + const char *class_id, widget_instance_lifecycle_callback_s callback, void *user_data) { - return _widget_class_create(widget_class, class_id, callback, user_data); + return _widget_class_create(widget_class, class_id, callback, + user_data); } -EXPORT_API widget_class_h widget_app_class_create(widget_instance_lifecycle_callback_s callback, void *user_data) +EXPORT_API widget_class_h widget_app_class_create( + widget_instance_lifecycle_callback_s callback, void *user_data) { return _widget_class_create(class_provider, appid, callback, user_data); } @@ -638,7 +656,8 @@ EXPORT_API int widget_app_context_set_tag(widget_context_h context, void *tag) } if (context == NULL) - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); context->tag = tag; @@ -653,14 +672,16 @@ EXPORT_API int widget_app_context_get_tag(widget_context_h context, void **tag) } if (context == NULL || tag == NULL) - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); *tag = context->tag; return WIDGET_ERROR_NONE; } -EXPORT_API int widget_app_context_set_content_info(widget_context_h context, bundle *content_info) +EXPORT_API int widget_app_context_set_content_info(widget_context_h context, + bundle *content_info) { const char *class_id = NULL; int ret = 0; @@ -671,27 +692,33 @@ EXPORT_API int widget_app_context_set_content_info(widget_context_h context, bun } if (context == NULL || content_info == NULL) - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); if (context->provider == NULL) - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); class_id = context->provider->classid; if (class_id == NULL) return widget_app_error(WIDGET_ERROR_FAULT, __FUNCTION__, NULL); - ret = __send_update_status(class_id, context->id, WIDGET_INSTANCE_EVENT_UPDATE, content_info, true); + ret = __send_update_status(class_id, context->id, + WIDGET_INSTANCE_EVENT_UPDATE, content_info, true); if (ret < 0) { - _E("failed to send content info: %s of %s (%d)", context->id, class_id, ret); - return widget_app_error(WIDGET_ERROR_IO_ERROR, __FUNCTION__, NULL); + _E("failed to send content info: %s of %s (%d)", context->id, + class_id, ret); + return widget_app_error(WIDGET_ERROR_IO_ERROR, __FUNCTION__, + NULL); } return WIDGET_ERROR_NONE; } -EXPORT_API int widget_app_context_set_title(widget_context_h context, const char *title) +EXPORT_API int widget_app_context_set_title(widget_context_h context, + const char *title) { if (!_is_widget_feature_enabled()) { _E("not supported"); diff --git a/src/widget_error.c b/src/widget_error.c index 010adb0..b6a63cc 100755 --- a/src/widget_error.c +++ b/src/widget_error.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. @@ -29,68 +29,56 @@ #define LOG_TAG "CAPI_WIDGET_APPLICATIO" -static const char* widget_app_error_to_string(widget_error_e error) +static const char *widget_app_error_to_string(widget_error_e error) { switch (error) { case WIDGET_ERROR_NONE: return "NONE"; - case WIDGET_ERROR_INVALID_PARAMETER: return "INVALID_PARAMETER"; - case WIDGET_ERROR_OUT_OF_MEMORY: return "OUT_OF_MEMORY"; - case WIDGET_ERROR_RESOURCE_BUSY: return "RESOURCE_BUSY"; - case WIDGET_ERROR_PERMISSION_DENIED: return "PERMISSION_DENIED"; - case WIDGET_ERROR_CANCELED: return "CANCELED"; - case WIDGET_ERROR_IO_ERROR: return "IO_ERROR"; - case WIDGET_ERROR_TIMED_OUT: return "TIMED_OUT"; - case WIDGET_ERROR_NOT_SUPPORTED: return "NOT_SUPPORTED"; - case WIDGET_ERROR_FILE_NO_SPACE_ON_DEVICE: return "FILE_NO_SPACE_ON_DEVICE"; - case WIDGET_ERROR_FAULT: return "FAULT"; - case WIDGET_ERROR_ALREADY_EXIST: return "ALREADY_EXIST"; - case WIDGET_ERROR_ALREADY_STARTED: return "ALREADY_STARTED"; - case WIDGET_ERROR_NOT_EXIST: return "NOT_EXIST"; - case WIDGET_ERROR_DISABLED: return "DISABLED"; - default: return "UNKNOWN"; } } -int widget_app_error(widget_error_e error, const char* function, - const char *description) +int widget_app_error(widget_error_e error, const char *function, + const char *description) { if (description) { - LOGE("[%s] %s(0x%08x) : %s", function, widget_app_error_to_string(error), error, - description); + LOGE("[%s] %s(0x%08x) : %s", function, + widget_app_error_to_string(error), error, + description); } else { - LOGE("[%s] %s(0x%08x)", function, widget_app_error_to_string(error), error); + LOGE("[%s] %s(0x%08x)", function, + widget_app_error_to_string(error), error); } return error; } + -- 2.7.4 From bf69959df3783f311c5ae27e05a9b7b1a0b54694 Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Fri, 8 Apr 2016 18:00:03 +0900 Subject: [PATCH 06/16] Fix widget_app_destroy_type_e Change-Id: I77c1fb8a1e6db6138d08285ff9f1c97d87ffb582 --- include/widget_app.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/include/widget_app.h b/include/widget_app.h index 3c935cd..3b49868 100755 --- a/include/widget_app.h +++ b/include/widget_app.h @@ -38,13 +38,8 @@ extern "C" { * @since_tizen 2.3.1 */ typedef enum widget_app_destroy_type { - WIDGET_APP_DESTROY_TYPE_DEFAULT = 0x00, /**< Deleted */ - WIDGET_APP_DESTROY_TYPE_UPGRADE = 0x01, /**< Deleted for upgrading */ - WIDGET_APP_DESTROY_TYPE_UNINSTALL = 0x02, /**< Deleted by uninstalling */ - WIDGET_APP_DESTROY_TYPE_TERMINATE = 0x03, /**< Deleted for reboot device */ - WIDGET_APP_DESTROY_TYPE_FAULT = 0x04, /**< Deleted by system-fault */ - WIDGET_APP_DESTROY_TYPE_TEMPORARY = 0x05, /**< Temporarly deleted, will be created again */ - WIDGET_APP_DESTROY_TYPE_UNKNOWN = 0x06 /**< Undefined reason */ + WIDGET_APP_DESTROY_TYPE_PERMANENT = 0x00, /* User deleted this widget from the viewer */ + WIDGET_APP_DESTROY_TYPE_TEMPORARY = 0x01, /* Widget is deleted because of other reasons (e.g. widget process is terminated temporarily by the system) */ } widget_app_destroy_type_e; /**< Delete type */ /** @@ -83,7 +78,7 @@ typedef int (*widget_instance_create_cb)(widget_context_h context, bundle *conte * * @details The callback function is called before widget instance is destroyed. * In this callback, you can finalize resources for this instance. - * If reason is not #WIDGET_APP_DESTROY_TYPE_DEFAULT, It should store the current status by using incoming bundle. + * If reason is not #WIDGET_APP_DESTROY_TYPE_TEMPORARY, It should store the current status by using incoming bundle. * * @param[in] context The context of widget instance. * @param[in] reason The reason for destruction -- 2.7.4 From 0d73d4df19bbea7d7d71f055406b51673a409532 Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Tue, 12 Apr 2016 13:53:50 +0900 Subject: [PATCH 07/16] Fix gettext error Change-Id: I0e78c041f2c79db7c0801f84452987e80c1734f5 Signed-off-by: Daehyeon Jung --- src/widget_app.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/widget_app.c b/src/widget_app.c index 82f1f89..d337d64 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -326,6 +326,28 @@ static int __aul_handler(aul_type type, bundle *b, void *data) return 0; } +static char *__get_domain_name(char *appid) +{ + char *name_token; + + if (appid == NULL) { + _E("appid is NULL"); + return NULL; + } + + name_token = strrchr(appid, '.'); + + if (name_token == NULL) { + _E("appid is invalid"); + return appid; + } + + name_token++; + + return name_token; +} + +extern int _set_i18n(const char *name); static int __before_loop(int argc, char **argv) { @@ -333,6 +355,7 @@ static int __before_loop(int argc, char **argv) bundle *kb = NULL; char *wayland_display = NULL; char *xdg_runtime_dir = NULL; + char *name; #if !(GLIB_CHECK_VERSION(2, 36, 0)) g_type_init(); @@ -382,6 +405,22 @@ static int __before_loop(int argc, char **argv) if (r != APP_ERROR_NONE) return r; + name = __get_domain_name(appid); + + if (name == NULL) { + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, + "Fail to call __get_domain_name"); + } + + r = _set_i18n(name); + + if (r < 0) { + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, + "Fail to call _set_i18n"); + } + class_provider = app_ops->create(app_user_data); if (class_provider == NULL) { return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, -- 2.7.4 From ed46e42fcfe01b3d38459e06c6bf572848666495 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 18 Apr 2016 17:46:46 +0900 Subject: [PATCH 08/16] Fix the widget_app_get_id() - Set the result Change-Id: I10a03805e042ad3ebce8780329d8a4e519b15458 Signed-off-by: Hwankyu Jhun --- src/widget_app.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widget_app.c b/src/widget_app.c index d337d64..38cda3d 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -596,6 +596,7 @@ EXPORT_API const char *widget_app_get_id(widget_context_h context) return NULL; } + set_last_result(WIDGET_ERROR_NONE); return context->id; } -- 2.7.4 From 49cfed7131365b3b6a23594a619752a343cd027b Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Mon, 18 Apr 2016 18:13:07 +0900 Subject: [PATCH 09/16] implement widget_context_foreach, add window cb Change-Id: I112c0e502ae7906e8cf4614377b32f7f4ac5f231 Signed-off-by: Daehyeon Jung --- src/widget_app.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/widget_app.c b/src/widget_app.c index 38cda3d..96212dc 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -293,6 +293,41 @@ static void __show_all() LOGD("resume"); } +static Eina_Bool __show_cb(void *data, int type, void *event) +{ + Ecore_Wl_Event_Window_Show *ev = event; + LOGD("show %d %d", (unsigned int)ev->win, (unsigned int)ev->data[0]); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool __hide_cb(void *data, int type, void *event) +{ + Ecore_Wl_Event_Window_Hide *ev = event; + LOGD("hide %d", (unsigned int)ev->win); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool __visibility_cb(void *data, int type, void *event) +{ + Ecore_Wl_Event_Window_Visibility_Change *ev = event; + LOGD("visiblity change: %d %d", (unsigned int)ev->win, (unsigned int)ev->fully_obscured); + return ECORE_CALLBACK_RENEW; +} + +static Eina_Bool __lower_cb(void *data, int type, void *event) +{ + LOGD("lower"); + return ECORE_CALLBACK_RENEW; +} + +static void __add_climsg() +{ + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_SHOW, __show_cb, NULL); + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_HIDE, __hide_cb, NULL); + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE, __visibility_cb, NULL); + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_LOWER, __lower_cb, NULL); +} + static int __aul_handler(aul_type type, bundle *b, void *data) { char *caller = NULL; @@ -421,6 +456,8 @@ static int __before_loop(int argc, char **argv) "Fail to call _set_i18n"); } + __add_climsg(); + class_provider = app_ops->create(app_user_data); if (class_provider == NULL) { return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, @@ -528,6 +565,9 @@ EXPORT_API int widget_app_terminate_context(widget_context_h context) EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data) { + GList *list; + widget_context_s *wc; + if (!_is_widget_feature_enabled()) { _E("not supported"); return WIDGET_ERROR_NOT_SUPPORTED; @@ -536,6 +576,17 @@ EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data) if (!cb) return WIDGET_ERROR_INVALID_PARAMETER; + list = g_list_first(contexts); + + while (list) { + wc = (widget_context_s *)list->data; + if (wc) { + if (!cb(wc, data)) + break; + } + list = list->next; + } + return WIDGET_ERROR_NONE; } -- 2.7.4 From 782ef2dfa646d2673132cc73bfaefb5a8c6c4f3d Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Wed, 27 Apr 2016 17:02:48 +0900 Subject: [PATCH 10/16] fix set title Change-Id: I52191e195fb9ec316a0208ff1045008a7481a9bd --- src/widget_app.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/widget_app.c b/src/widget_app.c index 96212dc..50be7da 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -816,13 +816,12 @@ EXPORT_API int widget_app_context_set_title(widget_context_h context, return WIDGET_ERROR_NOT_SUPPORTED; } - /* TODO - call elm_win_title_set() - */ - if (!context || !title) return WIDGET_ERROR_INVALID_PARAMETER; + if (context->win) + elm_win_title_set(context->win, title); + return WIDGET_ERROR_NONE; } -- 2.7.4 From 16315dfb6b7cc68bc75a6e0c6bfb425620cc10b2 Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Tue, 10 May 2016 15:37:17 +0900 Subject: [PATCH 11/16] Implements system and lifecycle events - Status updates only supports partial events, and will be fixed later - App common event handler are adopted from 2.x implementation - Lifecycle handler are not yet completed Change-Id: I5b9956cf26b7cf516c943227a4fda1d36cfc2f09 Signed-off-by: Daehyeon Jung --- CMakeLists.txt | 1 + packaging/appcore-widget.spec | 1 + src/widget_app.c | 579 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 539 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d57515e..652d965 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ pkg_check_modules(pkg_widget REQUIRED aul dlog capi-appfw-app-control + appcore-common capi-appfw-app-common vconf elementary diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index 1fbbb9f..71da10d 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -13,6 +13,7 @@ BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(vconf-internal-keys) BuildRequires: pkgconfig(alarm-service) BuildRequires: pkgconfig(capi-appfw-app-control) +BuildRequires: pkgconfig(appcore-common) BuildRequires: pkgconfig(capi-appfw-app-common) BuildRequires: pkgconfig(widget_service) BuildRequires: pkgconfig(capi-system-info) diff --git a/src/widget_app.c b/src/widget_app.c index 50be7da..491ca1c 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -29,10 +29,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #include "widget_app.h" #include "widget-log.h" @@ -54,6 +57,14 @@ typedef enum _widget_obj_state_e { WC_TERMINATED = 3 } widget_obj_state_e; +struct _widget_class { + void *user_data; + widget_instance_lifecycle_callback_s ops; + char *classid; + struct _widget_class *next; + struct _widget_class *prev; +}; + struct app_event_handler { app_event_type_e type; app_event_cb cb; @@ -65,20 +76,13 @@ struct app_event_info { void *value; }; -struct _widget_class { - void *user_data; - widget_instance_lifecycle_callback_s ops; - char *classid; - struct _widget_class *next; - struct _widget_class *prev; -}; - struct _widget_context { char *id; struct _widget_class *provider; int state; void *tag; Evas_Object *win; + int win_id; bundle *content; widget_instance_lifecycle_callback_s ops; }; @@ -86,6 +90,9 @@ struct _widget_context { typedef struct _widget_class widget_class_s; typedef struct _widget_context widget_context_s; +#define WIDGET_APP_EVENT_MAX 5 +static GList *handler_list[WIDGET_APP_EVENT_MAX] = {NULL, }; + static int caller_pid = 0; static widget_app_lifecycle_callback_s *app_ops; static void *app_user_data = NULL; @@ -94,6 +101,25 @@ static widget_class_h class_provider = NULL; static GList *contexts = NULL; static char *viewer_endpoint = NULL; +static void _widget_core_set_appcore_event_cb(void); +static void _widget_core_unset_appcore_event_cb(void); + +static void __free_handler_cb(gpointer data) +{ + if (data) + free(data); +} + +static void __free_handler_list(void) +{ + int i; + + for (i = 0; i < WIDGET_APP_EVENT_MAX; i++) { + g_list_free_full(handler_list[i], __free_handler_cb); + handler_list[i] = NULL; + } +} + static inline bool _is_widget_feature_enabled(void) { static bool feature = false; @@ -132,10 +158,54 @@ static widget_context_s *__find_context_by_id(const char *id) return ret->data; } +static gint __comp_by_win(gconstpointer a, gconstpointer b) +{ + int win = GPOINTER_TO_INT(b); + widget_context_s *wc = (widget_context_s *)a; + + return (wc && wc->win_id == win) ? 0 : -1; +} + +static widget_context_s *__find_context_by_win(int win) +{ + GList *ret = g_list_find_custom(contexts, GINT_TO_POINTER(win), __comp_by_win); + + if (ret == NULL) + return NULL; + + return ret->data; +} + +static int __send_lifecycle_event(const char *class_id, const char *instance_id, + int status) +{ + bundle *b = bundle_create(); + int ret; + + if (b == NULL) { + _E("out of memory"); + return -1; + } + + bundle_add_str(b, WIDGET_K_ID, class_id); + bundle_add_str(b, WIDGET_K_INSTANCE, instance_id); + bundle_add_byte(b, WIDGET_K_STATUS, &status, sizeof(int)); + + _D("send lifecycle %s(%d)", instance_id, status); + ret = aul_app_com_send("widget.status", b); + if (ret < 0) + _E("send lifecycle error:%d", ret); + + bundle_free(b); + + return ret; +} + static int __send_update_status(const char *class_id, const char *instance_id, int status, bundle *extra, int internal_only) { bundle *b = extra; + int lifecycle = -1; if (b == NULL) b = bundle_create(); @@ -144,15 +214,142 @@ static int __send_update_status(const char *class_id, const char *instance_id, bundle_add_str(b, WIDGET_K_INSTANCE, instance_id); bundle_add_byte(b, WIDGET_K_STATUS, &status, sizeof(int)); - _E("send update %s(%d) to %s", instance_id, status, viewer_endpoint); + _D("send update %s(%d) to %s", instance_id, status, viewer_endpoint); aul_app_com_send(viewer_endpoint, b); + switch (status) { + case WIDGET_INSTANCE_EVENT_CREATE: + lifecycle = WIDGET_LIFE_CYCLE_EVENT_CREATE; + break; + case WIDGET_INSTANCE_EVENT_DESTROY: + lifecycle = WIDGET_LIFE_CYCLE_EVENT_DESTROY; + break; + case WIDGET_INSTANCE_EVENT_PAUSE: + lifecycle = WIDGET_LIFE_CYCLE_EVENT_PAUSE; + break; + case WIDGET_INSTANCE_EVENT_RESUME: + lifecycle = WIDGET_LIFE_CYCLE_EVENT_RESUME; + break; + } + + if (lifecycle > -1) + __send_lifecycle_event(class_id, instance_id, lifecycle); + if (extra == NULL) bundle_free(b); return 0; } +static int __instance_resume(widget_class_h handle, const char *id, bundle *b) +{ + widget_context_s *wc = __find_context_by_id(id); + int ret; + + if (wc) { + if (handle->ops.resume) + handle->ops.resume(wc, handle->user_data); + + wc->state = WC_RUNNING; + _D("%s is resumed", id); + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_RESUME, NULL, 0); + } else { + _E("context not found: %s", id); + ret = -1; + } + + return ret; +} + +static int __instance_pause(widget_class_h handle, const char *id, bundle *b) +{ + widget_context_s *wc = __find_context_by_id(id); + int ret; + + if (wc) { + if (handle->ops.pause) + handle->ops.pause(wc, handle->user_data); + + wc->state = WC_PAUSED; + _D("%s is paused", id); + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_PAUSE, NULL, 0); + } else { + _E("context not found: %s", id); + ret = -1; + } + + return ret; +} + +static int __instance_resize(widget_class_h handle, const char *id, bundle *b) +{ + widget_context_s *wc = __find_context_by_id(id); + int ret; + int w; + int h; + char *w_str = NULL; + char *h_str = NULL; + char *remain = NULL; + + if (wc) { + bundle_get_str(b, WIDGET_K_WIDTH, &w_str); + bundle_get_str(b, WIDGET_K_HEIGHT, &h_str); + + if (w_str) + w = (int)g_ascii_strtoll(w_str, &remain, 10); + else + w = -1; + + if (h_str) + h = (int)g_ascii_strtoll(h_str, &remain, 10); + else + h = -1; + + if (handle->ops.resize) + handle->ops.resize(wc, w, h, handle->user_data); + _D("%s is resized to %dx%d", id, w, h); + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL, 0); + } else { + _E("context not found: %s", id); + ret = -1; + } + + return ret; +} + +static int __instance_update(widget_class_h handle, const char *id, bundle *b) +{ + widget_context_s *wc = __find_context_by_id(id); + int ret; + int force; + char *force_str = NULL; + + if (!wc) { + _E("context not found: %s", id); + return -1; + } + + if (handle->ops.update) { + if (b) + bundle_get_str(b, WIDGET_K_FORCE, &force_str); + + if (force_str && strcmp(force_str, "true") == 0) + force = 1; + else + force = 0; + + handle->ops.update(wc, b, force, handle->user_data); + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_UPDATE, b, 0); + _D("updated:%s", id); + } + + return ret; +} + static int __instance_create(widget_class_h handle, const char *id, bundle *b) { widget_context_s *wc = NULL; @@ -169,6 +366,7 @@ static int __instance_create(widget_class_h handle, const char *id, bundle *b) wc->id = g_strdup(id); wc->provider = handle; wc->win = NULL; + wc->win_id = -1; wc->content = bundle_dup(b); bundle_get_str(b, WIDGET_K_WIDTH, &w_str); @@ -266,9 +464,9 @@ static void __control(bundle *b) if (strcmp(operation, "create") == 0) { __instance_create(handle, id, b); } else if (strcmp(operation, "resize") == 0) { - /* TODO */ + __instance_resize(handle, id, b); } else if (strcmp(operation, "update") == 0) { - /* TODO */ + __instance_update(handle, id, b); } else if (strcmp(operation, "destroy") == 0) { bundle_get_str(b, WIDGET_K_REASON, &reason); if (reason) @@ -277,9 +475,9 @@ static void __control(bundle *b) __instance_destroy(handle, id, destroy_type, b); } else if (strcmp(operation, "resume") == 0) { - /* TODO */ + __instance_resume(handle, id, b); } else if (strcmp(operation, "pause") == 0) { - /* TODO */ + __instance_pause(handle, id, b); } return; @@ -288,22 +486,96 @@ error: return; } -static void __show_all() +static void __resume_cb(const char *id, void *data) { - LOGD("resume"); + widget_context_s *cxt = __find_context_by_id(id); + + if (cxt) + __instance_resume(cxt->provider, id, NULL); + else + _E("invalid context id:%s", id); + +} + +static void __pause_cb(const char *id, void *data) +{ + widget_context_s *cxt = __find_context_by_id(id); + + if (cxt) + __instance_pause(cxt->provider, id, NULL); + else + _E("invalid context id:%s", id); +} + +static void __pause_all() +{ + GList *iter = g_list_first(contexts); + + while (iter != NULL) { + widget_context_s *cxt = (widget_context_s *)iter->data; + const char *id = cxt->id; + + switch (cxt->state) { + case WC_READY: + __resume_cb(id, NULL); + __pause_cb(id, NULL); + break; + case WC_RUNNING: + __pause_cb(id, NULL); + break; + } + iter = g_list_next(iter); + } +} + +static void __resume_all() +{ + GList *iter = g_list_first(contexts); + + while (iter != NULL) { + widget_context_s *cxt = (widget_context_s *)iter->data; + const char *id = cxt->id; + + switch (cxt->state) { + case WC_READY: + __resume_cb(id, NULL); + break; + case WC_PAUSED: + __resume_cb(id, NULL); + break; + } + iter = g_list_next(iter); + } } static Eina_Bool __show_cb(void *data, int type, void *event) { Ecore_Wl_Event_Window_Show *ev = event; + widget_context_s *cxt = __find_context_by_win(ev->win); + LOGD("show %d %d", (unsigned int)ev->win, (unsigned int)ev->data[0]); + + if (cxt) + __instance_resume(cxt->provider, cxt->id, NULL); + else + LOGE("unknown window error: %d", ev->win); + return ECORE_CALLBACK_RENEW; } static Eina_Bool __hide_cb(void *data, int type, void *event) { Ecore_Wl_Event_Window_Hide *ev = event; + widget_context_s *cxt = __find_context_by_win(ev->win); + + LOGD("hide %d", (unsigned int)ev->win); + + if (cxt) + __instance_pause(cxt->provider, cxt->id, NULL); + else + LOGE("unknown window error: %d", ev->win); + return ECORE_CALLBACK_RENEW; } @@ -311,6 +583,7 @@ static Eina_Bool __visibility_cb(void *data, int type, void *event) { Ecore_Wl_Event_Window_Visibility_Change *ev = event; LOGD("visiblity change: %d %d", (unsigned int)ev->win, (unsigned int)ev->fully_obscured); + /* this is not working so far*/ return ECORE_CALLBACK_RENEW; } @@ -349,7 +622,7 @@ static int __aul_handler(aul_type type, bundle *b, void *data) __control(b); break; case AUL_RESUME: - __show_all(); + __resume_all(); break; case AUL_TERMINATE: widget_app_exit(); @@ -382,6 +655,25 @@ static char *__get_domain_name(char *appid) return name_token; } +static void __on_poweroff(keynode_t *key, void *data) +{ + int val; + + val = vconf_keynode_get_int(key); + switch (val) { + case VCONFKEY_SYSMAN_POWER_OFF_DIRECT: + case VCONFKEY_SYSMAN_POWER_OFF_RESTART: + _I("power off changed: %d", val); + widget_app_exit(); + break; + case VCONFKEY_SYSMAN_POWER_OFF_NONE: + case VCONFKEY_SYSMAN_POWER_OFF_POPUP: + default: + /* DO NOTHING */ + break; + } +} + extern int _set_i18n(const char *name); static int __before_loop(int argc, char **argv) @@ -458,26 +750,186 @@ static int __before_loop(int argc, char **argv) __add_climsg(); + _widget_core_set_appcore_event_cb(); + class_provider = app_ops->create(app_user_data); if (class_provider == NULL) { return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, "widget_class is NULL"); } + vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, __on_poweroff, NULL); + return WIDGET_ERROR_NONE; } static void __after_loop() { + vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, __on_poweroff); + + __pause_all(); + if (app_ops->terminate) app_ops->terminate(app_user_data); if (viewer_endpoint) free(viewer_endpoint); + _widget_core_unset_appcore_event_cb(); + __free_handler_list(); elm_shutdown(); } +static void __on_low_memory(keynode_t *key, void *data) +{ + int val; + + val = vconf_keynode_get_int(key); + if (val == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) { + app_event_handler_h handler; + struct app_event_info event; + + _I("widget_app_low_memory"); + + event.type = APP_EVENT_LOW_MEMORY; + event.value = (void *)&val; + + GList *iter = g_list_first(handler_list[APP_EVENT_LOW_MEMORY]); + + while (iter) { + handler = (app_event_handler_h) iter->data; + handler->cb(&event, handler->data); + iter = g_list_next(iter); + } + } +} + +static void __on_low_battery(keynode_t *key, void *data) +{ + int val; + + val = vconf_keynode_get_int(key); + if (val <= VCONFKEY_SYSMAN_BAT_CRITICAL_LOW) { + app_event_handler_h handler; + struct app_event_info event; + + _I("widget_app_low_battery"); + + event.type = APP_EVENT_LOW_BATTERY; + event.value = (void *)&val; + + GList *iter = g_list_first(handler_list[APP_EVENT_LOW_BATTERY]); + + while (iter) { + handler = (app_event_handler_h) iter->data; + handler->cb(&event, handler->data); + iter = g_list_next(iter); + } + } +} + +static void __on_lang_changed(keynode_t *key, void *data) +{ + char *val; + + _update_lang(); + val = vconf_keynode_get_str(key); + + app_event_handler_h handler; + struct app_event_info event; + + _I("widget_app_lang_changed"); + + event.type = APP_EVENT_LANGUAGE_CHANGED; + event.value = (void *)val; + + GList *iter = g_list_first(handler_list[APP_EVENT_LANGUAGE_CHANGED]); + + while (iter) { + handler = (app_event_handler_h) iter->data; + handler->cb(&event, handler->data); + iter = g_list_next(iter); + } +} + +static void __on_region_changed(keynode_t *key, void *data) +{ + char *val; + + _update_region(); + val = vconf_keynode_get_str(key); + + app_event_handler_h handler; + struct app_event_info event; + + _I("widget_app_region_changed"); + + event.type = APP_EVENT_REGION_FORMAT_CHANGED; + event.value = (void *)val; + + GList *iter = g_list_first(handler_list[APP_EVENT_REGION_FORMAT_CHANGED]); + + while (iter) { + handler = (app_event_handler_h) iter->data; + handler->cb(&event, handler->data); + iter = g_list_next(iter); + } +} + +static void __register_event(int event_type) +{ + switch (event_type) { + case APP_EVENT_LOW_MEMORY: + vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory, NULL); + break; + + case APP_EVENT_LOW_BATTERY: + vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery, NULL); + break; + + case APP_EVENT_LANGUAGE_CHANGED: + vconf_notify_key_changed(VCONFKEY_LANGSET, __on_lang_changed, NULL); + break; + + case APP_EVENT_REGION_FORMAT_CHANGED: + vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __on_region_changed, NULL); + break; + } +} + +static void __unregister_event(int event_type) +{ + switch (event_type) { + case APP_EVENT_LOW_MEMORY: + vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory); + break; + + case APP_EVENT_LOW_BATTERY: + vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery); + break; + + case APP_EVENT_LANGUAGE_CHANGED: + vconf_ignore_key_changed(VCONFKEY_LANGSET, __on_lang_changed); + break; + + case APP_EVENT_REGION_FORMAT_CHANGED: + vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __on_region_changed); + break; + } +} + +static void _widget_core_set_appcore_event_cb(void) +{ + __register_event(APP_EVENT_LANGUAGE_CHANGED); + __register_event(APP_EVENT_REGION_FORMAT_CHANGED); +} + +static void _widget_core_unset_appcore_event_cb(void) +{ + __unregister_event(APP_EVENT_LANGUAGE_CHANGED); + __unregister_event(APP_EVENT_REGION_FORMAT_CHANGED); +} + EXPORT_API int widget_app_main(int argc, char **argv, widget_app_lifecycle_callback_s *callback, void *user_data) { @@ -544,7 +996,6 @@ static gboolean __finish_event_cb(gpointer user_data) break; } - return FALSE; } @@ -591,45 +1042,86 @@ EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data) } EXPORT_API int widget_app_add_event_handler(app_event_handler_h *event_handler, - app_event_type_e event_type, app_event_cb callback, - void *user_data) + app_event_type_e event_type, app_event_cb callback, + void *user_data) { - if (!_is_widget_feature_enabled()) { - _E("not supported"); + int r; + bool feature; + + r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature); + if (r < 0) + return WIDGET_ERROR_FAULT; + + if (!feature) return WIDGET_ERROR_NOT_SUPPORTED; - } - /* TODO */ - if (!event_handler || !callback) - return WIDGET_ERROR_INVALID_PARAMETER; + app_event_handler_h handler; - switch (event_type) { - case APP_EVENT_LOW_MEMORY: - case APP_EVENT_LOW_BATTERY: - case APP_EVENT_LANGUAGE_CHANGED: - case APP_EVENT_DEVICE_ORIENTATION_CHANGED: - case APP_EVENT_REGION_FORMAT_CHANGED: - case APP_EVENT_SUSPENDED_STATE_CHANGED: + if (event_handler == NULL || callback == NULL) + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - break; - default: - return WIDGET_ERROR_INVALID_PARAMETER; + if (event_type < APP_EVENT_LOW_MEMORY + || event_type > APP_EVENT_REGION_FORMAT_CHANGED) + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + if (event_type == APP_EVENT_DEVICE_ORIENTATION_CHANGED) + return widget_app_error(WIDGET_ERROR_NOT_SUPPORTED, __FUNCTION__, NULL); + + GList *iter = g_list_first(handler_list[event_type]); + + while (iter) { + handler = (app_event_handler_h) iter->data; + + if (handler->cb == callback) + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + iter = g_list_next(iter); } + handler = calloc(1, sizeof(struct app_event_handler)); + if (!handler) + return widget_app_error(WIDGET_ERROR_OUT_OF_MEMORY, __FUNCTION__, NULL); + + if (g_list_length(handler_list[event_type]) == 0) + __register_event(event_type); + + handler->type = event_type; + handler->cb = callback; + handler->data = user_data; + handler_list[event_type] = g_list_append(handler_list[event_type], handler); + + *event_handler = handler; + return WIDGET_ERROR_NONE; } EXPORT_API int widget_app_remove_event_handler(app_event_handler_h event_handler) { - if (!_is_widget_feature_enabled()) { - _E("not supported"); + int r; + bool feature; + + r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature); + if (r < 0) + return WIDGET_ERROR_FAULT; + + if (!feature) return WIDGET_ERROR_NOT_SUPPORTED; - } - /* TODO */ - if (!event_handler) - return WIDGET_ERROR_INVALID_PARAMETER; + app_event_type_e type; + + if (event_handler == NULL) + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + type = event_handler->type; + if (type < APP_EVENT_LOW_MEMORY || type > APP_EVENT_REGION_FORMAT_CHANGED) + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + + handler_list[type] = g_list_remove(handler_list[type], event_handler); + free(event_handler); + + if (g_list_length(handler_list[type]) == 0) + __unregister_event(type); return WIDGET_ERROR_NONE; } @@ -684,6 +1176,9 @@ EXPORT_API int widget_app_get_elm_win(widget_context_h context, *win = ret_win; cxt->win = ret_win; + cxt->win_id = ecore_wl_window_id_get(wl_win); + + _D("window created: %d", cxt->win_id); return WIDGET_ERROR_NONE; } @@ -796,7 +1291,7 @@ EXPORT_API int widget_app_context_set_content_info(widget_context_h context, return widget_app_error(WIDGET_ERROR_FAULT, __FUNCTION__, NULL); ret = __send_update_status(class_id, context->id, - WIDGET_INSTANCE_EVENT_UPDATE, content_info, true); + WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, content_info, true); if (ret < 0) { _E("failed to send content info: %s of %s (%d)", context->id, -- 2.7.4 From 52c08435887de74da64c77caee7adad0b67cf54a Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Fri, 20 May 2016 21:21:59 +0900 Subject: [PATCH 12/16] Implement window event callback Change-Id: I3792b4762b14ec655943d44d7d06291fc7a65e1d Signed-off-by: Daehyeon Jung --- src/widget_app.c | 216 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 147 insertions(+), 69 deletions(-) diff --git a/src/widget_app.c b/src/widget_app.c index 491ca1c..c8e3764 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -246,19 +246,29 @@ static int __instance_resume(widget_class_h handle, const char *id, bundle *b) widget_context_s *wc = __find_context_by_id(id); int ret; - if (wc) { - if (handle->ops.resume) - handle->ops.resume(wc, handle->user_data); - - wc->state = WC_RUNNING; - _D("%s is resumed", id); - ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_RESUME, NULL, 0); - } else { + if (!wc) { _E("context not found: %s", id); - ret = -1; + return -1; + } + + if (wc->state == WC_RUNNING) { + _D("%s is already in running state", id); + return 0; } + if (wc->state == WC_TERMINATED) { + _D("%s is in terminated state", id); + return 0; + } + + if (handle->ops.resume) + handle->ops.resume(wc, handle->user_data); + + wc->state = WC_RUNNING; + _D("%s is resumed", id); + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_RESUME, NULL, 0); + return ret; } @@ -267,56 +277,49 @@ static int __instance_pause(widget_class_h handle, const char *id, bundle *b) widget_context_s *wc = __find_context_by_id(id); int ret; - if (wc) { - if (handle->ops.pause) - handle->ops.pause(wc, handle->user_data); - - wc->state = WC_PAUSED; - _D("%s is paused", id); - ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_PAUSE, NULL, 0); - } else { + if (!wc) { _E("context not found: %s", id); - ret = -1; + return -1; } + if (wc->state == WC_PAUSED) { + _D("%s is already in paused state", id); + return 0; + } + + if (wc->state == WC_TERMINATED) { + _D("%s is in terminated state", id); + return 0; + } + + if (handle->ops.pause) + handle->ops.pause(wc, handle->user_data); + + wc->state = WC_PAUSED; + _D("%s is paused", id); + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_PAUSE, NULL, 0); + return ret; } -static int __instance_resize(widget_class_h handle, const char *id, bundle *b) +static int __instance_resize(widget_class_h handle, const char *id, int w, int h, bundle *b) { widget_context_s *wc = __find_context_by_id(id); int ret; - int w; - int h; - char *w_str = NULL; - char *h_str = NULL; - char *remain = NULL; - - if (wc) { - bundle_get_str(b, WIDGET_K_WIDTH, &w_str); - bundle_get_str(b, WIDGET_K_HEIGHT, &h_str); - if (w_str) - w = (int)g_ascii_strtoll(w_str, &remain, 10); - else - w = -1; - - if (h_str) - h = (int)g_ascii_strtoll(h_str, &remain, 10); - else - h = -1; - - if (handle->ops.resize) - handle->ops.resize(wc, w, h, handle->user_data); - _D("%s is resized to %dx%d", id, w, h); - ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL, 0); - } else { + if (!wc) { _E("context not found: %s", id); - ret = -1; + return -1; } + if (handle->ops.resize) + handle->ops.resize(wc, w, h, handle->user_data); + + _D("%s is resized to %dx%d", id, w, h); + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL, 0); + return ret; } @@ -393,23 +396,24 @@ static int __instance_destroy(widget_class_h handle, const char *id, widget_context_s *wc = __find_context_by_id(id); int ret = 0; - if (wc) { - wc->state = WC_TERMINATED; - handle->ops.destroy(wc, (widget_app_destroy_type_e)reason, b, - handle->user_data); + if (!wc) { + _E("could not find widget obj: %s", id); + return WIDGET_ERROR_INVALID_PARAMETER; + } - ret = __send_update_status(handle->classid, id, - WIDGET_INSTANCE_EVENT_TERMINATE, b, 0); + wc->state = WC_TERMINATED; + handle->ops.destroy(wc, (widget_app_destroy_type_e)reason, b, + handle->user_data); - contexts = g_list_remove(contexts, wc); + ret = __send_update_status(handle->classid, id, + WIDGET_INSTANCE_EVENT_TERMINATE, b, 0); - if (wc->id) - free(wc->id); - free(wc); - } else { - _E("could not find widget obj: %s", id); - ret = WIDGET_ERROR_INVALID_PARAMETER; - } + contexts = g_list_remove(contexts, wc); + + if (wc->id) + free(wc->id); + + free(wc); return ret; } @@ -432,6 +436,38 @@ static widget_class_h __find_class_handler(const char *class_id, return NULL; } +static void __resize_window(char *id, bundle *b) +{ + widget_context_s *wc = __find_context_by_id(id); + char *w_str = NULL; + char *h_str = NULL; + char *remain = NULL; + int w; + int h; + + bundle_get_str(b, WIDGET_K_WIDTH, &w_str); + bundle_get_str(b, WIDGET_K_HEIGHT, &h_str); + + if (w_str) { + w = (int)g_ascii_strtoll(w_str, &remain, 10); + } else { + _E("unable to get width"); + return; + } + + if (h_str) { + h = (int)g_ascii_strtoll(h_str, &remain, 10); + } else { + _E("unable to get height"); + return; + } + + if (wc->win) + evas_object_resize(wc->win, w, h); + else + _E("unable to find window of %d", wc->id); +} + static void __control(bundle *b) { char *class_id = NULL; @@ -464,7 +500,7 @@ static void __control(bundle *b) if (strcmp(operation, "create") == 0) { __instance_create(handle, id, b); } else if (strcmp(operation, "resize") == 0) { - __instance_resize(handle, id, b); + __resize_window(id, b); } else if (strcmp(operation, "update") == 0) { __instance_update(handle, id, b); } else if (strcmp(operation, "destroy") == 0) { @@ -490,21 +526,24 @@ static void __resume_cb(const char *id, void *data) { widget_context_s *cxt = __find_context_by_id(id); - if (cxt) - __instance_resume(cxt->provider, id, NULL); - else + if (!cxt) { _E("invalid context id:%s", id); + return; + } + __instance_resume(cxt->provider, id, NULL); } static void __pause_cb(const char *id, void *data) { widget_context_s *cxt = __find_context_by_id(id); - if (cxt) - __instance_pause(cxt->provider, id, NULL); - else + if (!cxt) { _E("invalid context id:%s", id); + return; + } + + __instance_pause(cxt->provider, id, NULL); } static void __pause_all() @@ -582,8 +621,23 @@ static Eina_Bool __hide_cb(void *data, int type, void *event) static Eina_Bool __visibility_cb(void *data, int type, void *event) { Ecore_Wl_Event_Window_Visibility_Change *ev = event; + widget_context_s *cxt = __find_context_by_win(ev->win); + LOGD("visiblity change: %d %d", (unsigned int)ev->win, (unsigned int)ev->fully_obscured); - /* this is not working so far*/ + + if (!cxt) { + LOGE("unknown window error: %d", ev->win); + return ECORE_CALLBACK_RENEW; + } + + if (cxt->state == WC_PAUSED && ev->fully_obscured == 0) { + __instance_resume(cxt->provider, cxt->id, NULL); + } else if (cxt->state == WC_RUNNING && ev->fully_obscured == 1) { + __instance_pause(cxt->provider, cxt->id, NULL); + } else { + LOGD("cxt:%s state:%d obscured:%d", cxt->id, cxt->state, ev->fully_obscured); + } + return ECORE_CALLBACK_RENEW; } @@ -593,12 +647,32 @@ static Eina_Bool __lower_cb(void *data, int type, void *event) return ECORE_CALLBACK_RENEW; } +static Eina_Bool __configure_cb(void *data, int type, void *event) +{ + Ecore_Wl_Event_Window_Configure *ev = event; + widget_context_s *cxt = __find_context_by_win(ev->win); + + LOGD("configure: %d %d", ev->w, ev->h); + + if (!cxt) { + LOGE("unknown window error: %d", ev->win); + return ECORE_CALLBACK_RENEW; + } + + if (cxt->state == WC_PAUSED || cxt->state == WC_RUNNING) + __instance_resize(cxt->provider, cxt->id, ev->w, ev->h, NULL); + LOGD("cxt:%s resized to %dx%d", cxt->id, ev->w, ev->h); + + return ECORE_CALLBACK_RENEW; +} + static void __add_climsg() { ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_SHOW, __show_cb, NULL); ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_HIDE, __hide_cb, NULL); ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_VISIBILITY_CHANGE, __visibility_cb, NULL); ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_LOWER, __lower_cb, NULL); + ecore_event_handler_add(ECORE_WL_EVENT_WINDOW_CONFIGURE, __configure_cb, NULL); } static int __aul_handler(aul_type type, bundle *b, void *data) @@ -703,9 +777,13 @@ static int __before_loop(int argc, char **argv) if (xdg_runtime_dir) setenv("XDG_RUNTIME_DIR", xdg_runtime_dir, 1); + _D("xdg_runtime_dir:%s", xdg_runtime_dir); + if (wayland_display) setenv("WAYLAND_DISPLAY", wayland_display, 1); + _D("wayland_display:%s", wayland_display); + bundle_free(kb); kb = NULL; } else { -- 2.7.4 From c8b6d7c69aa6227d6f288349379c89f9a20fb48e Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 14 Jun 2016 15:13:21 +0900 Subject: [PATCH 13/16] Fix getting locale resource path Change-Id: I7583298a629d57d3df27dccbc9ef8a1420b7021e Signed-off-by: Hwankyu Jhun --- src/widget-i18n.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/widget-i18n.c b/src/widget-i18n.c index 91804e2..c739dd8 100755 --- a/src/widget-i18n.c +++ b/src/widget-i18n.c @@ -31,6 +31,8 @@ #include "widget-log.h" #include "widget-private.h" +#define PATH_LOCALE "locale" + void _update_lang(void) { char *r; @@ -80,10 +82,27 @@ void _update_region(void) } } +static int __get_locale_resource_dir(char *locale_dir, int size) +{ + const char *res_path; + + res_path = aul_get_app_resource_path(); + if (res_path == NULL) { + _E("Failed to get resource path"); + return -1; + } + + snprintf(locale_dir, size, "%s" PATH_LOCALE, res_path); + if (access(locale_dir, R_OK) != 0) + return -1; + + return 0; +} + static int __set_i18n(const char *domain) { char *r; - char dirname[PATH_MAX] = {0, }; + char locale_dir[PATH_MAX]; char *lang; if (domain == NULL) { @@ -91,8 +110,8 @@ static int __set_i18n(const char *domain) return -1; } - snprintf(dirname, PATH_MAX, "%s/res/locale", aul_get_app_root_path()); - _D("locale dir: %s", dirname); + __get_locale_resource_dir(locale_dir, sizeof(locale_dir)); + _D("locale dir: %s", locale_dir); r = setlocale(LC_ALL, ""); /* if locale is not set properly, try again to set as language base */ @@ -108,7 +127,7 @@ static int __set_i18n(const char *domain) if (r == NULL) _E("appcore: setlocale() error"); - r = bindtextdomain(domain, dirname); + r = bindtextdomain(domain, locale_dir); if (r == NULL) _E("appcore: bindtextdomain() error"); -- 2.7.4 From d6f67ac711930f8789599f5c8f09746025ebbbba Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Fri, 17 Jun 2016 14:22:16 +0900 Subject: [PATCH 14/16] fix dereference wrong ptr and uninitialized val Change-Id: Ib47aaf212970c533912ac2cd08f7a7324ce5897f --- src/widget_app.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/widget_app.c b/src/widget_app.c index c8e3764..ba14ac9 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -326,7 +326,7 @@ static int __instance_resize(widget_class_h handle, const char *id, int w, int h static int __instance_update(widget_class_h handle, const char *id, bundle *b) { widget_context_s *wc = __find_context_by_id(id); - int ret; + int ret = 0; int force; char *force_str = NULL; @@ -445,6 +445,11 @@ static void __resize_window(char *id, bundle *b) int w; int h; + if (!wc) { + _E("can not find instance: %s", id); + return; + } + bundle_get_str(b, WIDGET_K_WIDTH, &w_str); bundle_get_str(b, WIDGET_K_HEIGHT, &h_str); -- 2.7.4 From 0d8c91b6bf1dc48314bf49345b058dd34b2c8b7b Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Thu, 23 Jun 2016 12:59:16 +0900 Subject: [PATCH 15/16] fix update content info - from 2.x implementation, widget internally uses content_info as string. - in initial 3.0 impemenation of widget tried use bundle as is, but using bundle with content_info together may involves security issues and may introduce unintended bugs that developer expects bundle contains only their data. Change-Id: I98629753ab7141a4bbe6fd0299c8068a0e33a748 Signed-off-by: Daehyeon Jung --- src/widget_app.c | 311 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 178 insertions(+), 133 deletions(-) diff --git a/src/widget_app.c b/src/widget_app.c index ba14ac9..2018931 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -57,6 +57,11 @@ typedef enum _widget_obj_state_e { WC_TERMINATED = 3 } widget_obj_state_e; +enum { + UPDATE_LOCAL = 0, + UPDATE_ALL = 1, +}; + struct _widget_class { void *user_data; widget_instance_lifecycle_callback_s ops; @@ -83,7 +88,7 @@ struct _widget_context { void *tag; Evas_Object *win; int win_id; - bundle *content; + char *content; widget_instance_lifecycle_callback_s ops; }; @@ -93,13 +98,14 @@ typedef struct _widget_context widget_context_s; #define WIDGET_APP_EVENT_MAX 5 static GList *handler_list[WIDGET_APP_EVENT_MAX] = {NULL, }; -static int caller_pid = 0; +static int caller_pid; static widget_app_lifecycle_callback_s *app_ops; -static void *app_user_data = NULL; -static char *appid = NULL; -static widget_class_h class_provider = NULL; -static GList *contexts = NULL; -static char *viewer_endpoint = NULL; +static void *app_user_data; +static char *appid; +static widget_class_h class_provider; +static GList *contexts; +static char *viewer_endpoint; +static int exit_called; static void _widget_core_set_appcore_event_cb(void); static void _widget_core_unset_appcore_event_cb(void); @@ -202,18 +208,28 @@ static int __send_lifecycle_event(const char *class_id, const char *instance_id, } static int __send_update_status(const char *class_id, const char *instance_id, - int status, bundle *extra, int internal_only) + int status, bundle *extra) { - bundle *b = extra; + bundle *b; int lifecycle = -1; + bundle_raw *raw = NULL; + int len; - if (b == NULL) - b = bundle_create(); + b = bundle_create(); + if (!b) { + _E("out of memory"); + return -1; + } bundle_add_str(b, WIDGET_K_ID, class_id); bundle_add_str(b, WIDGET_K_INSTANCE, instance_id); bundle_add_byte(b, WIDGET_K_STATUS, &status, sizeof(int)); + if (extra) { + bundle_encode(extra, &raw, &len); + bundle_add_str(b, WIDGET_K_CONTENT_INFO, (const char *)raw); + } + _D("send update %s(%d) to %s", instance_id, status, viewer_endpoint); aul_app_com_send(viewer_endpoint, b); @@ -235,13 +251,14 @@ static int __send_update_status(const char *class_id, const char *instance_id, if (lifecycle > -1) __send_lifecycle_event(class_id, instance_id, lifecycle); - if (extra == NULL) - bundle_free(b); + bundle_free(b); + if (raw) + free(raw); return 0; } -static int __instance_resume(widget_class_h handle, const char *id, bundle *b) +static int __instance_resume(widget_class_h handle, const char *id, int send_update) { widget_context_s *wc = __find_context_by_id(id); int ret; @@ -266,13 +283,17 @@ static int __instance_resume(widget_class_h handle, const char *id, bundle *b) wc->state = WC_RUNNING; _D("%s is resumed", id); - ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_RESUME, NULL, 0); + if (send_update) { + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_RESUME, NULL); + } else { + ret = 0; + } return ret; } -static int __instance_pause(widget_class_h handle, const char *id, bundle *b) +static int __instance_pause(widget_class_h handle, const char *id, int send_update) { widget_context_s *wc = __find_context_by_id(id); int ret; @@ -297,13 +318,17 @@ static int __instance_pause(widget_class_h handle, const char *id, bundle *b) wc->state = WC_PAUSED; _D("%s is paused", id); - ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_PAUSE, NULL, 0); + if (send_update) { + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_PAUSE, NULL); + } else { + ret = 0; + } return ret; } -static int __instance_resize(widget_class_h handle, const char *id, int w, int h, bundle *b) +static int __instance_resize(widget_class_h handle, const char *id, int w, int h) { widget_context_s *wc = __find_context_by_id(id); int ret; @@ -318,48 +343,42 @@ static int __instance_resize(widget_class_h handle, const char *id, int w, int h _D("%s is resized to %dx%d", id, w, h); ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL, 0); + WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL); return ret; } -static int __instance_update(widget_class_h handle, const char *id, bundle *b) +static int __instance_update(widget_class_h handle, const char *id, int force, const char *content) { widget_context_s *wc = __find_context_by_id(id); int ret = 0; - int force; - char *force_str = NULL; - + bundle *b = NULL; if (!wc) { _E("context not found: %s", id); return -1; } - if (handle->ops.update) { - if (b) - bundle_get_str(b, WIDGET_K_FORCE, &force_str); - - if (force_str && strcmp(force_str, "true") == 0) - force = 1; - else - force = 0; + if (content) + b = bundle_decode((const bundle_raw *)content, strlen(content)); + if (handle->ops.update) { handle->ops.update(wc, b, force, handle->user_data); ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_UPDATE, b, 0); + WIDGET_INSTANCE_EVENT_UPDATE, NULL); _D("updated:%s", id); } + if (b) + bundle_free(b); + return ret; } -static int __instance_create(widget_class_h handle, const char *id, bundle *b) +static int __instance_create(widget_class_h handle, const char *id, const char *content, int w, int h) { widget_context_s *wc = NULL; - int w = 0, h = 0; - char *w_str = NULL, *h_str = NULL; - char *remain = NULL; int ret = 0; + bundle *content_info = NULL; wc = (widget_context_s *)malloc(sizeof(widget_context_s)); if (!wc) @@ -371,30 +390,30 @@ static int __instance_create(widget_class_h handle, const char *id, bundle *b) wc->win = NULL; wc->win_id = -1; - wc->content = bundle_dup(b); - bundle_get_str(b, WIDGET_K_WIDTH, &w_str); - bundle_get_str(b, WIDGET_K_HEIGHT, &h_str); - - if (w_str) - w = (int)g_ascii_strtoll(w_str, &remain, 10); - - if (h_str) - h = (int)g_ascii_strtoll(h_str, &remain, 10); + if (content) { + wc->content = strdup(content); + content_info = bundle_decode((const bundle_raw *)content, strlen(content)); + } contexts = g_list_append(contexts, wc); - handle->ops.create(wc, b, w, h, handle->user_data); + handle->ops.create(wc, content_info, w, h, handle->user_data); ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_CREATE, b, 0); + WIDGET_INSTANCE_EVENT_CREATE, NULL); + + if (content_info) + bundle_free(content_info); return ret; } static int __instance_destroy(widget_class_h handle, const char *id, - widget_destroy_type_e reason, bundle *b) + widget_app_destroy_type_e reason, int send_update) { widget_context_s *wc = __find_context_by_id(id); int ret = 0; + int event = WIDGET_INSTANCE_EVENT_TERMINATE; + bundle *content_info; if (!wc) { _E("could not find widget obj: %s", id); @@ -402,19 +421,39 @@ static int __instance_destroy(widget_class_h handle, const char *id, } wc->state = WC_TERMINATED; - handle->ops.destroy(wc, (widget_app_destroy_type_e)reason, b, + if (wc->content) + content_info = bundle_decode((const bundle_raw *)wc->content, strlen(wc->content)); + else + content_info = bundle_create(); + + handle->ops.destroy(wc, reason, content_info, handle->user_data); - ret = __send_update_status(handle->classid, id, - WIDGET_INSTANCE_EVENT_TERMINATE, b, 0); + if (reason == WIDGET_APP_DESTROY_TYPE_PERMANENT) { + event = WIDGET_INSTANCE_EVENT_DESTROY; + } else { + ret = __send_update_status(handle->classid, id, + WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, content_info); + } + + if (content_info) + bundle_free(content_info); + + ret = __send_update_status(handle->classid, id, event, NULL); contexts = g_list_remove(contexts, wc); if (wc->id) free(wc->id); + if (wc->content) + free(wc->content); + free(wc); + if (contexts == NULL && !exit_called) /* all instance destroyed */ + widget_app_exit(); + return ret; } @@ -436,37 +475,15 @@ static widget_class_h __find_class_handler(const char *class_id, return NULL; } -static void __resize_window(char *id, bundle *b) +static void __resize_window(char *id, int w, int h) { widget_context_s *wc = __find_context_by_id(id); - char *w_str = NULL; - char *h_str = NULL; - char *remain = NULL; - int w; - int h; if (!wc) { _E("can not find instance: %s", id); return; } - bundle_get_str(b, WIDGET_K_WIDTH, &w_str); - bundle_get_str(b, WIDGET_K_HEIGHT, &h_str); - - if (w_str) { - w = (int)g_ascii_strtoll(w_str, &remain, 10); - } else { - _E("unable to get width"); - return; - } - - if (h_str) { - h = (int)g_ascii_strtoll(h_str, &remain, 10); - } else { - _E("unable to get height"); - return; - } - if (wc->win) evas_object_resize(wc->win, w, h); else @@ -478,11 +495,16 @@ static void __control(bundle *b) char *class_id = NULL; char *id = NULL; char *operation = NULL; - char *reason = NULL; + char *content = NULL; + char *w_str = NULL; + char *h_str = NULL; + int w = 0; + int h = 0; char *remain = NULL; - int destroy_type = WIDGET_DESTROY_TYPE_DEFAULT; - + int force; + char *force_str = NULL; widget_class_h handle = NULL; + bundle_get_str(b, WIDGET_K_CLASS, &class_id); /* for previous version compatibility, use appid for default class id */ if (class_id == NULL) @@ -502,23 +524,36 @@ static void __control(bundle *b) goto error; } + bundle_get_str(b, WIDGET_K_FORCE, &force_str); + + if (force_str && strcmp(force_str, "true") == 0) + force = 1; + else + force = 0; + + bundle_get_str(b, WIDGET_K_CONTENT_INFO, &content); + bundle_get_str(b, WIDGET_K_WIDTH, &w_str); + bundle_get_str(b, WIDGET_K_HEIGHT, &h_str); + if (w_str) + w = (int)g_ascii_strtoll(w_str, &remain, 10); + + if (h_str) + h = (int)g_ascii_strtoll(h_str, &remain, 10); + if (strcmp(operation, "create") == 0) { - __instance_create(handle, id, b); + __instance_create(handle, id, content, w, h); } else if (strcmp(operation, "resize") == 0) { - __resize_window(id, b); + __resize_window(id, w, h); } else if (strcmp(operation, "update") == 0) { - __instance_update(handle, id, b); + __instance_update(handle, id, force, content); } else if (strcmp(operation, "destroy") == 0) { - bundle_get_str(b, WIDGET_K_REASON, &reason); - if (reason) - destroy_type = (int)g_ascii_strtoll(reason, &remain, - 10); - - __instance_destroy(handle, id, destroy_type, b); + __instance_destroy(handle, id, WIDGET_APP_DESTROY_TYPE_PERMANENT, UPDATE_ALL); } else if (strcmp(operation, "resume") == 0) { - __instance_resume(handle, id, b); + __instance_resume(handle, id, UPDATE_ALL); } else if (strcmp(operation, "pause") == 0) { - __instance_pause(handle, id, b); + __instance_pause(handle, id, UPDATE_ALL); + } else if (strcmp(operation, "terminate") == 0) { + __instance_destroy(handle, id, WIDGET_APP_DESTROY_TYPE_TEMPORARY, UPDATE_ALL); } return; @@ -527,71 +562,64 @@ error: return; } -static void __resume_cb(const char *id, void *data) +static void __pause_all(int send_update) { - widget_context_s *cxt = __find_context_by_id(id); - - if (!cxt) { - _E("invalid context id:%s", id); - return; - } - - __instance_resume(cxt->provider, id, NULL); -} + GList *iter = g_list_first(contexts); -static void __pause_cb(const char *id, void *data) -{ - widget_context_s *cxt = __find_context_by_id(id); + while (iter != NULL) { + widget_context_s *cxt = (widget_context_s *)iter->data; - if (!cxt) { - _E("invalid context id:%s", id); - return; + switch (cxt->state) { + case WC_READY: + __instance_resume(cxt->provider, cxt->id, send_update); + __instance_pause(cxt->provider, cxt->id, send_update); + break; + case WC_RUNNING: + __instance_pause(cxt->provider, cxt->id, send_update); + break; + } + iter = g_list_next(iter); } - - __instance_pause(cxt->provider, id, NULL); } -static void __pause_all() +static void __resume_all(int send_update) { GList *iter = g_list_first(contexts); while (iter != NULL) { widget_context_s *cxt = (widget_context_s *)iter->data; - const char *id = cxt->id; switch (cxt->state) { case WC_READY: - __resume_cb(id, NULL); - __pause_cb(id, NULL); + __instance_resume(cxt->provider, cxt->id, send_update); break; - case WC_RUNNING: - __pause_cb(id, NULL); + case WC_PAUSED: + __instance_resume(cxt->provider, cxt->id, send_update); break; } iter = g_list_next(iter); } } -static void __resume_all() +static void __destroy_all(int reason, int send_update) { GList *iter = g_list_first(contexts); + __pause_all(send_update); + while (iter != NULL) { widget_context_s *cxt = (widget_context_s *)iter->data; - const char *id = cxt->id; switch (cxt->state) { - case WC_READY: - __resume_cb(id, NULL); - break; case WC_PAUSED: - __resume_cb(id, NULL); + __instance_destroy(cxt->provider, cxt->id, reason, send_update); break; } iter = g_list_next(iter); } } + static Eina_Bool __show_cb(void *data, int type, void *event) { Ecore_Wl_Event_Window_Show *ev = event; @@ -600,7 +628,7 @@ static Eina_Bool __show_cb(void *data, int type, void *event) LOGD("show %d %d", (unsigned int)ev->win, (unsigned int)ev->data[0]); if (cxt) - __instance_resume(cxt->provider, cxt->id, NULL); + __instance_resume(cxt->provider, cxt->id, UPDATE_ALL); else LOGE("unknown window error: %d", ev->win); @@ -616,7 +644,7 @@ static Eina_Bool __hide_cb(void *data, int type, void *event) LOGD("hide %d", (unsigned int)ev->win); if (cxt) - __instance_pause(cxt->provider, cxt->id, NULL); + __instance_pause(cxt->provider, cxt->id, UPDATE_ALL); else LOGE("unknown window error: %d", ev->win); @@ -636,9 +664,9 @@ static Eina_Bool __visibility_cb(void *data, int type, void *event) } if (cxt->state == WC_PAUSED && ev->fully_obscured == 0) { - __instance_resume(cxt->provider, cxt->id, NULL); + __instance_resume(cxt->provider, cxt->id, UPDATE_ALL); } else if (cxt->state == WC_RUNNING && ev->fully_obscured == 1) { - __instance_pause(cxt->provider, cxt->id, NULL); + __instance_pause(cxt->provider, cxt->id, UPDATE_ALL); } else { LOGD("cxt:%s state:%d obscured:%d", cxt->id, cxt->state, ev->fully_obscured); } @@ -665,7 +693,7 @@ static Eina_Bool __configure_cb(void *data, int type, void *event) } if (cxt->state == WC_PAUSED || cxt->state == WC_RUNNING) - __instance_resize(cxt->provider, cxt->id, ev->w, ev->h, NULL); + __instance_resize(cxt->provider, cxt->id, ev->w, ev->h); LOGD("cxt:%s resized to %dx%d", cxt->id, ev->w, ev->h); return ECORE_CALLBACK_RENEW; @@ -701,7 +729,7 @@ static int __aul_handler(aul_type type, bundle *b, void *data) __control(b); break; case AUL_RESUME: - __resume_all(); + __resume_all(UPDATE_ALL); break; case AUL_TERMINATE: widget_app_exit(); @@ -848,9 +876,11 @@ static int __before_loop(int argc, char **argv) static void __after_loop() { + exit_called = 1; vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, __on_poweroff); - __pause_all(); + __pause_all(UPDATE_LOCAL); + __destroy_all(WIDGET_APP_DESTROY_TYPE_TEMPORARY, UPDATE_ALL); if (app_ops->terminate) app_ops->terminate(app_user_data); @@ -1053,6 +1083,11 @@ EXPORT_API int widget_app_exit(void) return WIDGET_ERROR_NOT_SUPPORTED; } + if (exit_called) + return WIDGET_ERROR_NONE; + + exit_called = 1; + ecore_main_loop_quit(); return WIDGET_ERROR_NONE; @@ -1067,13 +1102,12 @@ static gboolean __finish_event_cb(gpointer user_data) switch (wc->state) { case WC_READY: - - break; + __instance_resume(wc->provider, wc->id, UPDATE_LOCAL); case WC_RUNNING: - - break; + __instance_pause(wc->provider, wc->id, UPDATE_LOCAL); case WC_PAUSED: - + __instance_destroy(wc->provider, wc->id, + WIDGET_DESTROY_TYPE_TEMPORARY, UPDATE_ALL); break; default: break; @@ -1354,6 +1388,8 @@ EXPORT_API int widget_app_context_set_content_info(widget_context_h context, { const char *class_id = NULL; int ret = 0; + bundle_raw *raw = NULL; + int len; if (!_is_widget_feature_enabled()) { _E("not supported"); @@ -1374,7 +1410,16 @@ EXPORT_API int widget_app_context_set_content_info(widget_context_h context, return widget_app_error(WIDGET_ERROR_FAULT, __FUNCTION__, NULL); ret = __send_update_status(class_id, context->id, - WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, content_info, true); + WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, content_info); + + if (context->content) + free(context->content); + + bundle_encode(content_info, &raw, &len); + if (raw) + context->content = strdup((const char *)raw); + else + context->content = NULL; if (ret < 0) { _E("failed to send content info: %s of %s (%d)", context->id, -- 2.7.4 From d80235315bcd8e876cb7ecfef6f345fc6b9dbcad Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Mon, 4 Jul 2016 13:16:35 +0900 Subject: [PATCH 16/16] Initialize widget data structures Uninitialized context->content_info causes crashes Change-Id: I949e6c36dd754713447d32515505aa6640c2b4fb Signed-off-by: Semun Lee --- src/widget_app.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widget_app.c b/src/widget_app.c index 2018931..77ac4dd 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -380,7 +380,7 @@ static int __instance_create(widget_class_h handle, const char *id, const char * int ret = 0; bundle *content_info = NULL; - wc = (widget_context_s *)malloc(sizeof(widget_context_s)); + wc = (widget_context_s *)calloc(1, sizeof(widget_context_s)); if (!wc) return WIDGET_ERROR_OUT_OF_MEMORY; @@ -1316,9 +1316,9 @@ widget_class_h _widget_class_create(widget_class_s *prev, const char *class_id, return NULL; } - wc = (widget_class_s *)malloc(sizeof(widget_class_s)); + wc = (widget_class_s *)calloc(1, sizeof(widget_class_s)); if (wc == NULL) { - _E("failed to malloc : %s", __FUNCTION__); + _E("failed to calloc : %s", __FUNCTION__); set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); return NULL; } -- 2.7.4