From 0642934264fd99143a235ea87f70600c74111183 Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Wed, 4 Jan 2017 17:50:03 +0900 Subject: [PATCH 01/16] Fix API description Change-Id: I9184102cc89cd08f654697a2ae67e2d627dfd39c --- include/widget_app.h | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/include/widget_app.h b/include/widget_app.h index da53d6b..4a2068e 100755 --- a/include/widget_app.h +++ b/include/widget_app.h @@ -35,13 +35,13 @@ extern "C" { /** - * @brief Destroy type of widget instance. + * @brief Enumeration for destroy type of widget instance. * @since_tizen 2.3.1 */ typedef enum widget_app_destroy_type { 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 */ +} widget_app_destroy_type_e; /** @@ -60,9 +60,9 @@ typedef struct _widget_context *widget_context_h; /** * @brief Called when the widget instance starts. - * @since_tizen 2.3.1 * @details The callback function is called after widget instance is created. * In this callback, you can initialize resources for this instance. + * @since_tizen 2.3.1 * @param[in] context The context of widget instance * @param[in] content The data set for the previous status * @param[in] w The pixel value for widget width @@ -77,10 +77,10 @@ typedef int (*widget_instance_create_cb)(widget_context_h context, bundle *conte /** * @brief Called before the widget instance is destroyed. - * @since_tizen 2.3.1 * @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_TEMPORARY, it should store the current status by using incoming bundle. + * @since_tizen 2.3.1 * @remark Note that the parameter 'content' is used to save the status of the widget instance. * As a input parameter, content contains the saved status of the widget instance. * You can fill the content parameter with the current status in this callback, @@ -99,9 +99,9 @@ typedef int (*widget_instance_destroy_cb)(widget_context_h context, widget_app_d /** * @brief Called when the widget is invisible. - * @since_tizen 2.3.1 * @details The callback function is called when the widget is invisible. * The paused instance may be destroyed by framework. + * @since_tizen 2.3.1 * @param[in] context The context of widget instance * @param[in] user_data The user data passed from widget_app_class_create function * @return #WIDGET_ERROR_NONE on success, @@ -112,8 +112,8 @@ typedef int (*widget_instance_pause_cb)(widget_context_h context, void *user_dat /** * @brief Called when the widget is visible. - * @since_tizen 2.3.1 * @details The callback function is called when the widget is visible. + * @since_tizen 2.3.1 * @param[in] context The context of widget instance * @param[in] user_data The user data passed from widget_app_class_create function * @return #WIDGET_ERROR_NONE on success, @@ -124,8 +124,8 @@ typedef int (*widget_instance_resume_cb)(widget_context_h context, void *user_da /** * @brief Called before the widget size is changed. - * @since_tizen 2.3.1 * @details The callback function is called before the widget size is changed. + * @since_tizen 2.3.1 * @param[in] context The context of widget instance * @param[in] w The pixel value for widget width * @param[in] h The pixel value for widget height @@ -138,8 +138,8 @@ typedef int (*widget_instance_resize_cb)(widget_context_h context, int w, int h, /** * @brief Called when the event for updating widget is received. - * @since_tizen 2.3.1 * @details The callback function is called when the event for updating widget is received. + * @since_tizen 2.3.1 * @param[in] context The context of widget instance * @param[in] content The data set for updating this widget. It will be provided by requester. * Requester can use widget_service_trigger_update() @@ -153,7 +153,7 @@ typedef int (*widget_instance_update_cb)(widget_context_h context, bundle *conte /** - * @brief The structure for lifecycle of a widget instance. + * @brief The structure type containing the set of callback functions for lifecycle of a widget instance. * @since_tizen 2.3.1 */ typedef struct { @@ -168,10 +168,10 @@ typedef struct { /** * @brief Called when the application starts. - * @since_tizen 2.3.1 * @details The callback function is called before the main loop of the application starts. * In this callback, you can initialize resources which can be shared among widget instances. * This function should return the handle for widget class so that it will be used for making instances of widget. + * @since_tizen 2.3.1 * @param[in] user_data The user data passed from the callback registration function * @return The object of widget class * @see widget_app_main() @@ -212,8 +212,8 @@ typedef struct { /** * @brief Called for each widget context. - * @since_tizen 2.3.1 * @details This function will be called in the function of widget_app_foreach_context repeatedly. + * @since_tizen 2.3.1 * @param[in] context The context for widget instance * @param[in] data The data for caller * @return @c true to continue with the next iteration of the loop, @@ -312,7 +312,7 @@ int widget_app_add_event_handler(app_event_handler_h *event_handler, app_event_t * @brief Removes registered event handler. * @since_tizen 2.3.1 * @param[in] event_handler The event handler - * @return #WIDGET_ERROR_NONE on success + * @return #WIDGET_ERROR_NONE on success, * otherwise an error code (see WIDGET_ERROR_XXX) on failure * @retval #WIDGET_ERROR_NONE Successful * @retval #WIDGET_ERROR_INVALID_PARAMETER Invalid parameter @@ -344,7 +344,8 @@ const char *widget_app_get_id(widget_context_h context); * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. * @param[in] callback The set of lifecycle callbacks * @param[in] user_data The user data to be passed to the callback functions - * @return The new widget class object. NULL on error + * @return The new widget class object, + * NULL on error * @exception #WIDGET_ERROR_NONE Successfully added * @exception #WIDGET_ERROR_INVALID_PARAMETER Not supported * @exception #WIDGET_ERROR_NOT_SUPPORTED Not supported @@ -422,7 +423,8 @@ int widget_app_context_set_title(widget_context_h context, const char *title); * @param[in] class_id The class id of provider * @param[in] callback The set of lifecycle callbacks * @param[in] user_data The user data to be passed to the callback functions - * @return The new widget class object. NULL on error + * @return The new widget class object, + * NULL on error * @exception #WIDGET_ERROR_NONE Successfully added * @exception #WIDGET_ERROR_INVALID_PARAMETER Not supported * @exception #WIDGET_ERROR_NOT_SUPPORTED Not supported -- 2.7.4 From e123e9a0ee0720d4d84b17dabca59a92cc7ed539 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 20 Jan 2017 17:30:32 +0900 Subject: [PATCH 02/16] Fix memory leak Change-Id: I6dfa71dd1baebac7c12725badf15459b29b13204 Signed-off-by: Hwankyu Jhun --- src/widget_app.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/widget_app.c b/src/widget_app.c index 3b85e32..b3c18c5 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -973,6 +973,11 @@ static void __after_loop() package_id = NULL; } + if (appid) { + free(appid); + appid = NULL; + } + elm_shutdown(); } @@ -1148,8 +1153,13 @@ EXPORT_API int widget_app_main(int argc, char **argv, app_ops = callback; app_user_data = user_data; r = __before_loop(argc, argv); - if (r < 0) + if (r < 0) { + if (appid) { + free(appid); + appid = NULL; + } return r; + } ecore_main_loop_begin(); aul_status_update(STATUS_DYING); @@ -1538,6 +1548,7 @@ EXPORT_API int widget_app_context_set_content_info(widget_context_h context, else context->content = NULL; + free(raw); if (ret < 0) { /* LCOV_EXCL_START */ _E("failed to send content info: %s of %s (%d)", context->id, -- 2.7.4 From be6863152ed6d4bf9653a3fb44e98397d874cef6 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 24 Jan 2017 08:13:17 +0900 Subject: [PATCH 03/16] Fix versioning Change-Id: I9e095901a6c52607387d86298836fcdc2c1c47da Signed-off-by: Hwankyu Jhun --- CMakeLists.txt | 10 +++++----- ...idget-application.pc => capi-appfw-widget-application.pc.in | 2 +- packaging/appcore-widget.spec | 4 +--- 3 files changed, 7 insertions(+), 9 deletions(-) rename capi-appfw-widget-application.pc => capi-appfw-widget-application.pc.in (95%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 13129fc..f295aae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,7 @@ PROJECT(appcore-widget C) SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(EXEC_PREFIX "\${prefix}") SET(INCLUDEDIR "\${prefix}/include") -SET(VERSION_MAJOR 1) -SET(VERSION "${VERSION_MAJOR}.1") +SET(VERSION ${FULLVER}) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) @@ -45,15 +44,16 @@ ENDFOREACH(flag) AUX_SOURCE_DIRECTORY(src SOURCES) ADD_LIBRARY(${APPCORE_WIDGET} SHARED ${SOURCES}) -SET_TARGET_PROPERTIES(${APPCORE_WIDGET} PROPERTIES SOVERSION ${VERSION_MAJOR}) -SET_TARGET_PROPERTIES(${APPCORE_WIDGET} PROPERTIES VERSION ${VERSION}) +SET_TARGET_PROPERTIES(${APPCORE_WIDGET} PROPERTIES SOVERSION ${MAJORVER}) +SET_TARGET_PROPERTIES(${APPCORE_WIDGET} PROPERTIES VERSION ${FULLVER}) SET_TARGET_PROPERTIES(${APPCORE_WIDGET} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_widget}) TARGET_LINK_LIBRARIES(${APPCORE_WIDGET} ${pkg_widget_LDFLAGS} "-ldl -Wl,--no-undefined") +CONFIGURE_FILE(${APPCORE_WIDGET}.pc.in ${APPCORE_WIDGET}.pc @ONLY) INSTALL(TARGETS ${APPCORE_WIDGET} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${APPCORE_WIDGET}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/appfw/ FILES_MATCHING PATTERN "*.h" - ) \ No newline at end of file + ) diff --git a/capi-appfw-widget-application.pc b/capi-appfw-widget-application.pc.in similarity index 95% rename from capi-appfw-widget-application.pc rename to capi-appfw-widget-application.pc.in index e857f73..e1ef14d 100644 --- a/capi-appfw-widget-application.pc +++ b/capi-appfw-widget-application.pc.in @@ -7,7 +7,7 @@ includedir=@INCLUDEDIR@ Name: capi-appfw-widget-application Description: widget application library -Version: 1.1 +Version: @VERSION@ Requires: aul dlog elementary capi-appfw-app-control capi-appfw-app-common widget_service Libs: -L${libdir} -lcapi-appfw-widget-application Cflags: -I${includedir} -I${includedir}/appfw diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index 8bdedaa..a340ebe 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -59,9 +59,7 @@ cp LICENSE %{buildroot}/usr/share/license/%{name} %files %manifest appcore-widget.manifest %defattr(-,root,root,-) -%{_libdir}/libcapi-appfw-widget-application.so -%{_libdir}/libcapi-appfw-widget-application.so.1 -%{_libdir}/libcapi-appfw-widget-application.so.1.1 +%{_libdir}/libcapi-appfw-widget-application.so* /usr/share/license/%{name} %files -n capi-appfw-widget-application-devel -- 2.7.4 From 73fd24b43226fc4c1736d8793fa558fd97049f52 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 25 Jan 2017 13:47:24 +0900 Subject: [PATCH 04/16] Release version 1.0.1 Changes: - Fix versioning - Fix memory leak Change-Id: I5e582e84080f70d1e8d8b743b686979773b7d5bc Signed-off-by: Hwankyu Jhun --- packaging/appcore-widget.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index a340ebe..7cc4463 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -1,6 +1,6 @@ Name: appcore-widget Summary: Widget Application -Version: 1.0.0.0 +Version: 1.0.1 Release: 1 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 93a29b50d193051cd3ca8d031be856e8e0164e0e Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Tue, 31 Jan 2017 09:25:30 +0900 Subject: [PATCH 05/16] Fix errata in doxygen comment Change-Id: Ib4c4879cd0c9b2a26e15fec2b678699fbcad51cf Signed-off-by: Semun Lee --- doc/appcore-widget_doc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/appcore-widget_doc.h b/doc/appcore-widget_doc.h index 99b698c..0dbc9a9 100755 --- a/doc/appcore-widget_doc.h +++ b/doc/appcore-widget_doc.h @@ -79,7 +79,7 @@ * widget_instance_create_cb() * Called after widget instance is created. * In this callback, you can initialize resources for this instance. - * If parameter 'content' is not NULL, you should restore the pervious status. + * If parameter 'content' is not NULL, you should restore the previous status. * * * -- 2.7.4 From 48cb35c7092cd696f061bde3fa53b48044bc1b59 Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Wed, 22 Feb 2017 10:33:32 +0900 Subject: [PATCH 06/16] Send FG/BG signal to resourced - resourced should know the FG/BG status to control oom score Change-Id: Ieab8aa28f9f80bbb087cef1f662c58ad8e4cb3de Signed-off-by: Junghoon Park (cherry picked from commit 0c9faf0db7a4b3776c9a097e6952f8393087f01a) --- src/widget_app.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/widget_app.c b/src/widget_app.c index b3c18c5..3911a6d 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -16,6 +16,7 @@ #include +#include #include #include @@ -50,6 +51,9 @@ #define STR_MAX_BUF 128 #define LOG_TAG "CAPI_WIDGET_APPLICATION" #define K_REASON "__WC_K_REASON__" +#define APP_TYPE_WIDGET "widgetapp" +#define STATUS_FOREGROUND "fg" +#define STATUS_BACKGROUND "bg" typedef enum _widget_obj_state_e { WC_READY = 0, @@ -86,6 +90,7 @@ static char *appid; static widget_class_h class_provider; static int exit_called; static char *package_id; +static bool fg_signal; static void _widget_core_set_appcore_event_cb(void); static void _widget_core_unset_appcore_event_cb(void); @@ -149,6 +154,28 @@ static widget_context_s *__find_context_by_id(const char *id) return ret->data; } +static gint __comp_by_state(gconstpointer a, gconstpointer b) +{ + widget_context_s *wc = (widget_context_s *)a; + + if (wc->state == (widget_obj_state_e)GPOINTER_TO_INT(b)) + return 0; + + return -1; +} + +static widget_context_s *__find_context_by_state(widget_obj_state_e state) +{ + GList *ret; + GList *contexts = _widget_app_get_contexts(); + + ret = g_list_find_custom(contexts, GINT_TO_POINTER((int)state), __comp_by_state); + if (ret == NULL) + return NULL; + + return ret->data; +} + static gint __comp_by_win(gconstpointer a, gconstpointer b) { int win = GPOINTER_TO_INT(b); @@ -283,6 +310,15 @@ static int __instance_resume(widget_class_h handle, const char *id, int send_upd if (send_update) { ret = __send_update_status(handle->classid, wc->id, WIDGET_INSTANCE_EVENT_RESUME, NULL); + if (!fg_signal) { + _D("Send fg signal to resourceD"); + aul_send_app_status_change_signal(getpid(), + appid, + package_id, + STATUS_FOREGROUND, + APP_TYPE_WIDGET); + fg_signal = true; + } } else { ret = 0; } @@ -318,6 +354,16 @@ static int __instance_pause(widget_class_h handle, const char *id, int send_upda if (send_update) { ret = __send_update_status(handle->classid, wc->id, WIDGET_INSTANCE_EVENT_PAUSE, NULL); + wc = __find_context_by_state(WC_RUNNING); + if (!wc && fg_signal) { + _D("Send bg signal to resourceD"); + aul_send_app_status_change_signal(getpid(), + appid, + package_id, + STATUS_BACKGROUND, + APP_TYPE_WIDGET); + fg_signal = false; + } } else { ret = 0; } -- 2.7.4 From 85b92fd555cdf4365e238cf949f50c5e58497c86 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 16 Mar 2017 11:39:08 +0900 Subject: [PATCH 07/16] Add log messages Change-Id: I9cc598c0b9252b16946aa93771290538854ddd68 Signed-off-by: Hwankyu Jhun --- src/widget_app.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/widget_app.c b/src/widget_app.c index 3911a6d..6cedfa8 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -455,8 +455,10 @@ static int __instance_create(widget_class_h handle, const char *id, const char * bundle *content_info = NULL; wc = (widget_context_s *)calloc(1, sizeof(widget_context_s)); - if (!wc) + if (!wc) { + _E("Out of memory"); return WIDGET_ERROR_OUT_OF_MEMORY; + } wc->state = WC_READY; wc->id = strdup(id); @@ -473,6 +475,7 @@ static int __instance_create(widget_class_h handle, const char *id, const char * ret = handle->ops.create(wc, content_info, w, h, handle->user_data); if (ret < 0) { + _W("Create callback resturns error(%d)", ret); /* TODO send abort */ } else { ret = __send_update_status(handle->classid, wc->id, -- 2.7.4 From ae1eeb5eb6e7bec59ed96c4d80f8fa43ee818adb Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 16 Mar 2017 12:59:35 +0900 Subject: [PATCH 08/16] Release version 1.0.2 Changes: - Add log messages - Send FG/BG signal to resourced - Fix errata in doxygen comment Change-Id: I65e2aea56a83ebfb943acdabe8b13e0bb4a89a8b Signed-off-by: Hwankyu Jhun --- packaging/appcore-widget.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index 7cc4463..dc9afee 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -1,6 +1,6 @@ Name: appcore-widget Summary: Widget Application -Version: 1.0.1 +Version: 1.0.2 Release: 1 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From fcbfa76f54caaff86e2ff9648d420f1338854af8 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 17 Mar 2017 16:53:20 +0900 Subject: [PATCH 09/16] Send create aborted event to the widget viewer Requires: - https://review.tizen.org/gerrit/119553 Change-Id: Iaac8a02534fd72381a270aa00e00de59756559f0 Signed-off-by: Hwankyu Jhun --- src/widget_app.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/widget_app.c b/src/widget_app.c index 6cedfa8..e25fdd1 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -476,7 +476,17 @@ static int __instance_create(widget_class_h handle, const char *id, const char * ret = handle->ops.create(wc, content_info, w, h, handle->user_data); if (ret < 0) { _W("Create callback resturns error(%d)", ret); - /* TODO send abort */ + ret = __send_update_status(handle->classid, wc->id, + WIDGET_INSTANCE_EVENT_CREATE_ABORTED, NULL); + _widget_app_remove_context(wc); + if (wc->id) + free(wc->id); + if (wc->content) + free(wc->content); + free(wc); + + if (_widget_app_get_contexts() == NULL && !exit_called) + widget_app_exit(); } else { ret = __send_update_status(handle->classid, wc->id, WIDGET_INSTANCE_EVENT_CREATE, NULL); -- 2.7.4 From e14b8629ef2df41c3a018aaed9f2d40a791c03ff Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Fri, 17 Mar 2017 22:59:28 +0900 Subject: [PATCH 10/16] Handle widget resize event Change-Id: I8a6a8cc7be128ebd8720bb2bd6a0794385a2b97a Signed-off-by: Hyunho Kang --- src/widget_app.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widget_app.c b/src/widget_app.c index e25fdd1..5995238 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -644,6 +644,7 @@ static void __control(bundle *b) __instance_create(handle, id, content, w, h); } else if (strcmp(operation, "resize") == 0) { __resize_window(id, w, h); + __instance_resize(handle, id, w, h); } else if (strcmp(operation, "update") == 0) { if (id) __instance_update(handle, id, force, content); -- 2.7.4 From c21a135e1b7221cef0953ac99cd65448905281ed Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Mon, 20 Mar 2017 14:02:25 +0900 Subject: [PATCH 11/16] Release version 1.0.3 Changes: - Send create aborted event to the widget viewer - Handle widget resize event Change-Id: If1ccaf402f6bf1550748d89bf97a136a53c205f3 Signed-off-by: Hyunho Kang --- packaging/appcore-widget.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index dc9afee..4083dc1 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -1,6 +1,6 @@ Name: appcore-widget Summary: Widget Application -Version: 1.0.2 +Version: 1.0.3 Release: 1 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From bcaf074b462bc2dceea9a6f8c291d8c02255983c Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Thu, 23 Mar 2017 10:47:57 +0900 Subject: [PATCH 12/16] Set license using %license Change-Id: If5d4a82e5155d2d4395ee1f01189ec62c46c7ca5 Signed-off-by: Hyunho Kang --- packaging/appcore-widget.spec | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index 4083dc1..7212bdd 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -47,9 +47,6 @@ rm -rf %{buildroot} mkdir -p %{buildroot}%{_libdir}/pkgconfig cp capi-appfw-widget-application.pc %{buildroot}%{_libdir}/pkgconfig -mkdir -p %{buildroot}/usr/share/license -cp LICENSE %{buildroot}/usr/share/license/%{name} - %post -p /sbin/ldconfig @@ -60,7 +57,7 @@ cp LICENSE %{buildroot}/usr/share/license/%{name} %manifest appcore-widget.manifest %defattr(-,root,root,-) %{_libdir}/libcapi-appfw-widget-application.so* -/usr/share/license/%{name} +%license LICENSE %files -n capi-appfw-widget-application-devel /usr/include/appfw/widget_app.h -- 2.7.4 From 5c83778cd7e835307a83001cafb99e089ff99418 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Thu, 23 Mar 2017 12:55:45 +0900 Subject: [PATCH 13/16] Release version 1.0.4 Changes: - Set license using %license Change-Id: I8ccb83d4ac309405aedfc5b088cec3a50bfbf47b Signed-off-by: Hyunho Kang --- packaging/appcore-widget.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index 7212bdd..11bc0bd 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -1,6 +1,6 @@ Name: appcore-widget Summary: Widget Application -Version: 1.0.3 +Version: 1.0.4 Release: 1 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 0db6707d80cbb80da2cf9db73f0c42489eceef78 Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Mon, 27 Mar 2017 21:10:59 +0900 Subject: [PATCH 14/16] Refactor appcore-widget using appcore_multiwindow_base Change-Id: Ib7125b66d8fb4562cf3bd1024f8ad7a06f612491 Signed-off-by: Junghoon Park --- CMakeLists.txt | 3 +- capi-appfw-widget-application.pc.in | 2 +- include/widget_app.h | 3 +- include/widget_app_efl.h | 2 +- include/widget_app_internal.h | 43 +- packaging/appcore-widget.spec | 8 +- src/widget-i18n.c | 155 ---- src/widget-log.h | 2 +- src/widget-private.h | 32 +- src/widget_app.c | 1722 ++++++++++++++--------------------- src/widget_app_internal.c | 75 +- src/widget_error.c | 2 +- 12 files changed, 712 insertions(+), 1337 deletions(-) delete mode 100755 src/widget-i18n.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f295aae..6dc73c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,6 @@ INCLUDE(FindPkgConfig) pkg_check_modules(pkg_widget REQUIRED aul dlog - capi-appfw-app-control appcore-common capi-appfw-app-common vconf @@ -35,8 +34,8 @@ pkg_check_modules(pkg_widget REQUIRED widget_service capi-system-info ecore-wayland - tizen-remote-surface-client screen_connector_provider + appcore-multiwindow ) FOREACH(flag ${pkg_widget_CFLAGS}) SET(EXTRA_CFLAGS_widget "${EXTRA_CFLAGS_widget} ${flag}") diff --git a/capi-appfw-widget-application.pc.in b/capi-appfw-widget-application.pc.in index e1ef14d..8512e85 100644 --- a/capi-appfw-widget-application.pc.in +++ b/capi-appfw-widget-application.pc.in @@ -8,6 +8,6 @@ includedir=@INCLUDEDIR@ Name: capi-appfw-widget-application Description: widget application library Version: @VERSION@ -Requires: aul dlog elementary capi-appfw-app-control capi-appfw-app-common widget_service +Requires: aul dlog elementary capi-appfw-app-common widget_service Libs: -L${libdir} -lcapi-appfw-widget-application Cflags: -I${includedir} -I${includedir}/appfw diff --git a/include/widget_app.h b/include/widget_app.h index 4a2068e..5e29aea 100755 --- a/include/widget_app.h +++ b/include/widget_app.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2017 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. @@ -19,7 +19,6 @@ #define __TIZEN_APPFW_WIDGET_APP_H__ #include -#include #include #include #include diff --git a/include/widget_app_efl.h b/include/widget_app_efl.h index 092f195..7d65cf3 100644 --- a/include/widget_app_efl.h +++ b/include/widget_app_efl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2017 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_internal.h b/include/widget_app_internal.h index c278012..c225263 100644 --- a/include/widget_app_internal.h +++ b/include/widget_app_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2017 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. @@ -23,46 +23,7 @@ extern "C" { #endif -/** - * For in-house applications - * - */ - -typedef struct { - struct __pointer { - double x; - double y; - int down; - } pointer; - - struct __part { - double sx; - double sy; - double ex; - double ey; - } part; - -} 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 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 widget_class_h (*_widget_class_factory_operation_make)(widget_instance_lifecycle_callback_s callback); - -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); -int widget_app_restart(); - +int widget_app_restart(void); #ifdef __cplusplus } diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index 11bc0bd..1c81f3c 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -11,15 +11,13 @@ BuildRequires: pkgconfig(elementary) BuildRequires: pkgconfig(dbus-glib-1) 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) -BuildRequires: pkgconfig(wayland-tbm-client) -BuildRequires: pkgconfig(ecore-wayland) -BuildRequires: pkgconfig(screen_connector_provider) +BuildRequires: pkgconfig(ecore-wayland) +BuildRequires: pkgconfig(appcore-multiwindow) +BuildRequires: pkgconfig(screen_connector_provider) BuildRequires: cmake diff --git a/src/widget-i18n.c b/src/widget-i18n.c deleted file mode 100755 index 39ae5c5..0000000 --- a/src/widget-i18n.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "widget-log.h" -#include "widget-private.h" - -#define PATH_LOCALE "locale" - -void _update_lang(void) -{ - char language[32]; - char *r; - char *lang = vconf_get_str(VCONFKEY_LANGSET); - if (lang) { - snprintf(language, sizeof(language), "%s:en_US:en_GB:en", lang); - setenv("LANGUAGE", language, 1); - setenv("LANG", lang, 1); - setenv("LC_MESSAGES", lang, 1); - - r = setlocale(LC_ALL, ""); - if (r == NULL) { - /* LCOV_EXCL_START */ - r = setlocale(LC_ALL, lang); - if (r) - _D("*****appcore setlocale=%s\n", r); - /* LCOV_EXCL_STOP */ - } - free(lang); - } else { - _E("failed to get current language for set lang env"); /* LCOV_EXCL_LINE */ - } -} - -void _update_region(void) -{ - char *region; - char *r; - - region = vconf_get_str(VCONFKEY_REGIONFORMAT); - if (region) { - setenv("LC_CTYPE", region, 1); - setenv("LC_NUMERIC", region, 1); - setenv("LC_TIME", region, 1); - setenv("LC_COLLATE", region, 1); - setenv("LC_MONETARY", region, 1); - setenv("LC_PAPER", region, 1); - setenv("LC_NAME", region, 1); - setenv("LC_ADDRESS", region, 1); - setenv("LC_TELEPHONE", region, 1); - setenv("LC_MEASUREMENT", region, 1); - setenv("LC_IDENTIFICATION", region, 1); - - r = setlocale(LC_ALL, ""); - if (r != NULL) - _D("*****appcore setlocale=%s\n", r); - - free(region); - } else { - _E("failed to get current region format for set region env"); /* LCOV_EXCL_LINE */ - } -} - -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"); /* LCOV_EXCL_LINE */ - return -1; /* LCOV_EXCL_LINE */ - } - - 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 locale_dir[PATH_MAX]; - char *lang; - - if (domain == NULL) { - errno = EINVAL; /* LCOV_EXCL_LINE */ - return -1; /* LCOV_EXCL_LINE */ - } - - __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 */ - if (r == NULL) { - /* LCOV_EXCL_START */ - lang = vconf_get_str(VCONFKEY_LANGSET); - r = setlocale(LC_ALL, lang); - if (r) - _D("*****appcore setlocale=%s\n", r); - - if (lang) - free(lang); - /* LCOV_EXCL_STOP */ - } - if (r == NULL) - _E("appcore: setlocale() error"); /* LCOV_EXCL_LINE */ - - r = bindtextdomain(domain, locale_dir); - if (r == NULL) - _E("appcore: bindtextdomain() error"); /* LCOV_EXCL_LINE */ - - r = textdomain(domain); - if (r == NULL) - _E("appcore: textdomain() error"); /* LCOV_EXCL_LINE */ - - return 0; -} - -int _set_i18n(const char *domainname) -{ - _update_lang(); - _update_region(); - - return __set_i18n(domainname); -} - diff --git a/src/widget-log.h b/src/widget-log.h index 980f3e3..a316028 100755 --- a/src/widget-log.h +++ b/src/widget-log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2017 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/src/widget-private.h b/src/widget-private.h index 847c099..293e226 100644 --- a/src/widget-private.h +++ b/src/widget-private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2017 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,36 +27,6 @@ #define FEATURE_SHELL_APPWIDGET "http://tizen.org/feature/shell.appwidget" -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; - char *content; - widget_instance_lifecycle_callback_s ops; -}; - -typedef struct _widget_context widget_context_s; - -GList *_widget_app_get_contexts(); -int _widget_app_add_context(widget_context_s *wc); -int _widget_app_remove_context(widget_context_s *wc); -int _widget_app_set_viewer_endpoint(char *viewer_endpoint); -char *_widget_app_get_viewer_endpoint(); -int _widget_app_free_viewer_endpoint(); -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); diff --git a/src/widget_app.c b/src/widget_app.c index 5995238..fcc7ae3 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2017 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. @@ -25,19 +25,16 @@ #include #include #include -#include -#include #include #include #include -#include -#include #include #include #include #include #include #include +#include #include "widget_app.h" #include "widget-log.h" @@ -48,28 +45,32 @@ #undef LOG_TAG #endif -#define STR_MAX_BUF 128 #define LOG_TAG "CAPI_WIDGET_APPLICATION" -#define K_REASON "__WC_K_REASON__" #define APP_TYPE_WIDGET "widgetapp" #define STATUS_FOREGROUND "fg" #define STATUS_BACKGROUND "bg" -typedef enum _widget_obj_state_e { - WC_READY = 0, - WC_RUNNING = 1, - WC_PAUSED = 2, - WC_TERMINATED = 3 -} widget_obj_state_e; +struct widget_extra { + void *extra; + char *instance_id; + bundle *args; + char *content; + Evas_Object *win; +}; -enum { - UPDATE_LOCAL = 0, - UPDATE_ALL = 1, +struct widget_class_context { + widget_instance_lifecycle_callback_s callback; + void *data; }; -struct app_event_handler { - app_event_type_e type; - app_event_cb cb; +struct widget_app_context { + widget_app_lifecycle_callback_s callback; + void *data; + bool dirty; +}; + +struct widget_foreach_context { + widget_context_cb callback; void *data; }; @@ -78,40 +79,33 @@ struct app_event_info { void *value; }; -typedef struct _widget_class widget_class_s; - -#define WIDGET_APP_EVENT_MAX 5 -static GList *handler_list[WIDGET_APP_EVENT_MAX] = {NULL, }; - -static int caller_pid; -static widget_app_lifecycle_callback_s *app_ops; -static void *app_user_data; -static char *appid; -static widget_class_h class_provider; -static int exit_called; -static char *package_id; -static bool fg_signal; - -static void _widget_core_set_appcore_event_cb(void); -static void _widget_core_unset_appcore_event_cb(void); +struct app_event_handler { + app_event_type_e type; + app_event_cb cb; + void *data; + void *raw; +}; -static void __free_handler_cb(gpointer data) -{ - if (data) - free(data); -} +struct _widget_context { + int dummy; +}; -static void __free_handler_list(void) -{ - int i; +static int __app_event_converter[APPCORE_BASE_EVENT_MAX] = { + [APP_EVENT_LOW_MEMORY] = APPCORE_BASE_EVENT_LOW_MEMORY, + [APP_EVENT_LOW_BATTERY] = APPCORE_BASE_EVENT_LOW_BATTERY, + [APP_EVENT_LANGUAGE_CHANGED] = APPCORE_BASE_EVENT_LANG_CHANGE, + [APP_EVENT_DEVICE_ORIENTATION_CHANGED] = APPCORE_BASE_EVENT_DEVICE_ORIENTATION_CHANGED, + [APP_EVENT_REGION_FORMAT_CHANGED] = APPCORE_BASE_EVENT_REGION_CHANGE, + [APP_EVENT_SUSPENDED_STATE_CHANGED] = APPCORE_BASE_EVENT_SUSPENDED_STATE_CHANGE, +}; - for (i = 0; i < WIDGET_APP_EVENT_MAX; i++) { - g_list_free_full(handler_list[i], __free_handler_cb); - handler_list[i] = NULL; - } -} +static struct widget_app_context __context; +static char *__appid; +static char *__package_id; +static bool __fg_signal; +char *_viewer_endpoint; -static inline bool _is_widget_feature_enabled(void) +static bool __is_widget_feature_enabled(void) { static bool feature = false; static bool retrieved = false; @@ -132,74 +126,91 @@ static inline bool _is_widget_feature_enabled(void) return feature; } -static gint __comp_by_id(gconstpointer a, gconstpointer b) +/* LCOV_EXCL_START */ +static void __on_poweroff(keynode_t *key, void *data) { - widget_context_s *wc = (widget_context_s *)a; + int val; - return strcmp(wc->id, (const char *)b); + 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; + } } +/* LCOV_EXCL_STOP */ -static widget_context_s *__find_context_by_id(const char *id) +static int __widget_app_create(void *data) { - GList *ret; - GList *contexts = _widget_app_get_contexts(); + char pkgid[256] = {0, }; - if (id == NULL) - return NULL; + appcore_multiwindow_base_on_create(); + app_get_id(&__appid); + if (aul_app_get_pkgid_bypid(getpid(), pkgid, sizeof(pkgid)) == 0) + __package_id = strdup(pkgid); - ret = g_list_find_custom(contexts, id, __comp_by_id); - if (ret == NULL) - return NULL; + if (!__package_id || !__appid) { + _E("__package_id is NULL"); + return -1; + } - return ret->data; -} + screen_connector_provider_init(); + vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, __on_poweroff, NULL); -static gint __comp_by_state(gconstpointer a, gconstpointer b) -{ - widget_context_s *wc = (widget_context_s *)a; + if (__context.callback.create == NULL) { + _E("__context.callback.create(is NULL"); + return -1; + } - if (wc->state == (widget_obj_state_e)GPOINTER_TO_INT(b)) - return 0; + if (__context.callback.create(__context.data) == NULL) { + _E("app_create_cb() returns NULL"); + return -1; + } - return -1; + _D("widget app is created"); + return 0; } -static widget_context_s *__find_context_by_state(widget_obj_state_e state) +static int __widget_app_terminate(void *data) { - GList *ret; - GList *contexts = _widget_app_get_contexts(); + if (__context.callback.terminate) + __context.callback.terminate(__context.data); - ret = g_list_find_custom(contexts, GINT_TO_POINTER((int)state), __comp_by_state); - if (ret == NULL) - return NULL; - - return ret->data; -} + vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, __on_poweroff); + screen_connector_provider_fini(); -static gint __comp_by_win(gconstpointer a, gconstpointer b) -{ - int win = GPOINTER_TO_INT(b); - widget_context_s *wc = (widget_context_s *)a; + if (_viewer_endpoint) { + free(_viewer_endpoint); + _viewer_endpoint = NULL; + } - return (wc && wc->win_id == win) ? 0 : -1; -} + if (__package_id) { + free(__package_id); + __package_id = NULL; + } -static widget_context_s *__find_context_by_win(int win) -{ - GList *contexts = _widget_app_get_contexts(); - GList *ret = g_list_find_custom(contexts, GINT_TO_POINTER(win), __comp_by_win); + if (__appid) { + free(__appid); + __appid = NULL; + } - if (ret == NULL) - return NULL; + appcore_multiwindow_base_on_terminate(); - return ret->data; + _D("widget app is terminated"); + return 0; } static int __send_lifecycle_event(const char *class_id, const char *instance_id, int status) { bundle *b = bundle_create(); - char pkgid[256] = {0, }; int ret; if (b == NULL) { @@ -207,17 +218,10 @@ static int __send_lifecycle_event(const char *class_id, const char *instance_id, return -1; /* LCOV_EXCL_LINE */ } - if (package_id == NULL) { - ret = aul_app_get_pkgid_bypid(getpid(), pkgid, sizeof(pkgid)); - if (ret == 0) - package_id = strdup(pkgid); - } - bundle_add_str(b, AUL_K_WIDGET_ID, class_id); bundle_add_str(b, AUL_K_WIDGET_INSTANCE_ID, instance_id); bundle_add_byte(b, AUL_K_WIDGET_STATUS, &status, sizeof(int)); - if (package_id) - bundle_add_str(b, AUL_K_PKGID, package_id); + bundle_add_str(b, AUL_K_PKGID, __package_id); _D("send lifecycle %s(%d)", instance_id, status); ret = aul_app_com_send("widget.status", b); @@ -236,7 +240,6 @@ static int __send_update_status(const char *class_id, const char *instance_id, int lifecycle = -1; bundle_raw *raw = NULL; int len; - char *viewer_endpoint = _widget_app_get_viewer_endpoint(); b = bundle_create(); if (!b) { @@ -254,8 +257,8 @@ static int __send_update_status(const char *class_id, const char *instance_id, aul_widget_instance_add(class_id, instance_id); } - _D("send update %s(%d) to %s", instance_id, status, viewer_endpoint); - aul_app_com_send(viewer_endpoint, b); + _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: @@ -282,921 +285,342 @@ static int __send_update_status(const char *class_id, const char *instance_id, return 0; } -static int __instance_resume(widget_class_h handle, const char *id, int send_update) +static void __instance_resume(const char *class_id, const char *id, bundle *b) { - widget_context_s *wc = __find_context_by_id(id); - int ret; - - if (!wc) { - _E("context not found: %s", id); /* LCOV_EXCL_LINE */ - return -1; /* LCOV_EXCL_LINE */ - } + appcore_multiwindow_base_instance_h cxt; - if (wc->state == WC_RUNNING) { - _D("%s is already in running state", id); /* LCOV_EXCL_LINE */ - return 0; /* LCOV_EXCL_LINE */ - } + cxt = appcore_multiwindow_base_instance_find(id); - if (wc->state == WC_TERMINATED) { - _D("%s is in terminated state", id); /* LCOV_EXCL_LINE */ - return 0; /* LCOV_EXCL_LINE */ + if (!cxt) { + _E("context not found: %s", id); + return; } - if (handle->ops.resume) - handle->ops.resume(wc, handle->user_data); + appcore_multiwindow_base_instance_resume(cxt); - wc->state = WC_RUNNING; - _D("%s is resumed", id); - if (send_update) { - ret = __send_update_status(handle->classid, wc->id, + __send_update_status(class_id, id, WIDGET_INSTANCE_EVENT_RESUME, NULL); - if (!fg_signal) { - _D("Send fg signal to resourceD"); - aul_send_app_status_change_signal(getpid(), - appid, - package_id, - STATUS_FOREGROUND, - APP_TYPE_WIDGET); - fg_signal = true; - } - } else { - ret = 0; + if (!__fg_signal) { + _D("Send fg signal to resourceD"); + aul_send_app_status_change_signal(getpid(), + __appid, + __package_id, + STATUS_FOREGROUND, + APP_TYPE_WIDGET); + __fg_signal = true; } - - return ret; } -static int __instance_pause(widget_class_h handle, const char *id, int send_update) +static void __instance_pause(const char *class_id, const char *id, bundle *b) { - widget_context_s *wc = __find_context_by_id(id); - int ret; + appcore_multiwindow_base_instance_h cxt; - if (!wc) { - _E("context not found: %s", id); /* LCOV_EXCL_LINE */ - return -1; /* LCOV_EXCL_LINE */ - } - - if (wc->state == WC_PAUSED) { - _D("%s is already in paused state", id); /* LCOV_EXCL_LINE */ - return 0; /* LCOV_EXCL_LINE */ - } + cxt = appcore_multiwindow_base_instance_find(id); - if (wc->state == WC_TERMINATED) { - _D("%s is in terminated state", id); /* LCOV_EXCL_LINE */ - return 0; /* LCOV_EXCL_LINE */ - } - - if (handle->ops.pause) - handle->ops.pause(wc, handle->user_data); - - wc->state = WC_PAUSED; - _D("%s is paused", id); - if (send_update) { - ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_PAUSE, NULL); - wc = __find_context_by_state(WC_RUNNING); - if (!wc && fg_signal) { - _D("Send bg signal to resourceD"); - aul_send_app_status_change_signal(getpid(), - appid, - package_id, - STATUS_BACKGROUND, - APP_TYPE_WIDGET); - fg_signal = false; - } - } else { - ret = 0; - } - - return ret; -} - -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; - - if (!wc) { - _E("context not found: %s", id); /* LCOV_EXCL_LINE */ - return -1; /* LCOV_EXCL_LINE */ - } - - 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); - - return ret; -} - -/* LCOV_EXCL_START */ -static int __instance_update_all(widget_class_h handle, int force, const char *content) -{ - widget_context_s *wc; - int ret = 0; - bundle *b = NULL; - GList *context = _widget_app_get_contexts(); - - if (content) - b = bundle_decode((const bundle_raw *)content, strlen(content)); - - if (handle->ops.update) { - while (context) { - wc = (widget_context_s *)context->data; - handle->ops.update(wc, b, force, handle->user_data); - ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_UPDATE, NULL); - _D("updated:%s", wc->id); - context = context->next; - } - } - - if (b) - bundle_free(b); - - return ret; -} -/* LCOV_EXCL_STOP */ - -/* LCOV_EXCL_START */ -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; - bundle *b = NULL; - if (!wc) { + if (!cxt) { _E("context not found: %s", id); - return -1; - } - - 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, NULL); - _D("updated:%s", id); - } - - if (b) - bundle_free(b); - - return ret; -} -/* LCOV_EXCL_STOP */ - -static int __instance_create(widget_class_h handle, const char *id, const char *content, int w, int h) -{ - widget_context_s *wc = NULL; - int ret = 0; - bundle *content_info = NULL; - - wc = (widget_context_s *)calloc(1, sizeof(widget_context_s)); - if (!wc) { - _E("Out of memory"); - return WIDGET_ERROR_OUT_OF_MEMORY; - } - - wc->state = WC_READY; - wc->id = strdup(id); - wc->provider = handle; - wc->win = NULL; - wc->win_id = -1; - - if (content) { - wc->content = strdup(content); - content_info = bundle_decode((const bundle_raw *)content, strlen(content)); - } - - _widget_app_add_context(wc); - - ret = handle->ops.create(wc, content_info, w, h, handle->user_data); - if (ret < 0) { - _W("Create callback resturns error(%d)", ret); - ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_CREATE_ABORTED, NULL); - _widget_app_remove_context(wc); - if (wc->id) - free(wc->id); - if (wc->content) - free(wc->content); - free(wc); - - if (_widget_app_get_contexts() == NULL && !exit_called) - widget_app_exit(); - } else { - ret = __send_update_status(handle->classid, wc->id, - WIDGET_INSTANCE_EVENT_CREATE, NULL); - - if (content == NULL) - content = "NULL"; - - aul_widget_instance_add(handle->classid, id); - } - - if (content_info) - bundle_free(content_info); - - return ret; -} - -static int __instance_destroy(widget_class_h handle, const char *id, - 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, clear amd info", id); /* LCOV_EXCL_LINE */ - aul_widget_instance_del(handle->classid, id); /* LCOV_EXCL_LINE */ - return WIDGET_ERROR_NONE; /* LCOV_EXCL_LINE */ - } - - wc->state = WC_TERMINATED; - 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); - - if (reason == WIDGET_APP_DESTROY_TYPE_PERMANENT) { - event = WIDGET_INSTANCE_EVENT_DESTROY; - aul_widget_instance_del(handle->classid, id); - } 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); - - _widget_app_remove_context(wc); - - if (wc->id) - free(wc->id); - - if (wc->content) - free(wc->content); - - free(wc); - - if (_widget_app_get_contexts() == NULL && !exit_called) /* all instance destroyed */ - widget_app_exit(); - - return ret; -} - -static widget_class_h __find_class_handler(const char *class_id, - widget_class_h handle) -{ - if (!class_id || !handle) - return NULL; - - widget_class_h head = handle; - - while (head) { - if (head->classid && strcmp(head->classid, class_id) == 0) - return head; - - head = head->next; + return; } - return NULL; -} - -/* LCOV_EXCL_START */ -static void __resize_window(char *id, int w, int h) -{ - widget_context_s *wc = __find_context_by_id(id); + appcore_multiwindow_base_instance_pause(cxt); - if (!wc) { - _E("can not find instance: %s", id); - return; + if (__fg_signal) { + _D("Send bg signal to resourceD"); + aul_send_app_status_change_signal(getpid(), + __appid, + __package_id, + STATUS_BACKGROUND, + APP_TYPE_WIDGET); + __fg_signal = false; } - - if (wc->win) - evas_object_resize(wc->win, w, h); - else - _E("unable to find window of %d", wc->id); } -/* LCOV_EXCL_STOP */ -static void __control(bundle *b) +static void __instance_resize(const char *class_id, const char *id, bundle *b) { - char *class_id = NULL; - char *id = NULL; - char *operation = NULL; - char *content = NULL; + appcore_multiwindow_base_instance_h cxt; + struct widget_class_context *class_cxt; + const appcore_multiwindow_base_class *cls; + struct widget_extra *we; + char *remain = NULL; char *w_str = NULL; char *h_str = NULL; int w = 0; int h = 0; - char *remain = NULL; - 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) - class_id = appid; + cxt = appcore_multiwindow_base_instance_find(id); - bundle_get_str(b, AUL_K_WIDGET_INSTANCE_ID, &id); - bundle_get_str(b, WIDGET_K_OPERATION, &operation); - - handle = __find_class_handler(class_id, class_provider); - if (!handle) { - _E("no handle provided: %s", class_id); /* LCOV_EXCL_LINE */ - goto error; + if (!cxt) { + _E("context not found: %s", id); + return; } - if (!operation) { - _E("no operation provided"); - goto error; - } + cls = appcore_multiwindow_base_instance_get_class(cxt); + if (!cls) + return; - bundle_get_str(b, WIDGET_K_FORCE, &force_str); + class_cxt = cls->data; + if (!class_cxt) { + _E("class is NULL"); + return; + } - if (force_str && strcmp(force_str, "true") == 0) - force = 1; - else - force = 0; + we = appcore_multiwindow_base_instance_get_extra(cxt); + if (!we) { + _E("widget extra is NULL"); + return; + } - 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, content, w, h); - } else if (strcmp(operation, "resize") == 0) { - __resize_window(id, w, h); - __instance_resize(handle, id, w, h); - } else if (strcmp(operation, "update") == 0) { - if (id) - __instance_update(handle, id, force, content); - else - __instance_update_all(handle, force, content); - - } else if (strcmp(operation, "destroy") == 0) { - __instance_destroy(handle, id, WIDGET_APP_DESTROY_TYPE_PERMANENT, UPDATE_ALL); - } else if (strcmp(operation, "resume") == 0) { - __instance_resume(handle, id, UPDATE_ALL); - } else if (strcmp(operation, "pause") == 0) { - __instance_pause(handle, id, UPDATE_ALL); - } else if (strcmp(operation, "terminate") == 0) { - __instance_destroy(handle, id, WIDGET_APP_DESTROY_TYPE_TEMPORARY, UPDATE_ALL); - } - - return; -error: - LOGD("error on control"); - return; -} - -static void __pause_all(int send_update) -{ - GList *contexts = _widget_app_get_contexts(); - GList *iter = g_list_first(contexts); - - while (iter != NULL) { - widget_context_s *cxt = (widget_context_s *)iter->data; - - 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; - } - LOGD("pause %s", cxt->id); - iter = g_list_next(iter); - } -} - -/* LCOV_EXCL_START */ -static void __resume_all(int send_update) -{ - GList *contexts = _widget_app_get_contexts(); - GList *iter = g_list_first(contexts); - - while (iter != NULL) { - widget_context_s *cxt = (widget_context_s *)iter->data; - - switch (cxt->state) { - case WC_READY: - __instance_resume(cxt->provider, cxt->id, send_update); - break; - case WC_PAUSED: - __instance_resume(cxt->provider, cxt->id, send_update); - break; - } - iter = g_list_next(iter); - } -} -/* LCOV_EXCL_STOP */ - -static void __destroy_all(int reason, int send_update) -{ - GList *contexts = _widget_app_get_contexts(); - GList *iter = g_list_first(contexts); - - __pause_all(send_update); - while (iter != NULL) { - widget_context_s *cxt = (widget_context_s *)iter->data; - iter = g_list_next(iter); - switch (cxt->state) { - case WC_PAUSED: - LOGD("destroy %d : %s", cxt->state, cxt->id); - __instance_destroy(cxt->provider, cxt->id, reason, send_update); - break; - } - } -} - - -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, UPDATE_ALL); + if (we->win) + evas_object_resize(we->win, w, h); else - LOGE("unknown window error: %d", ev->win); /* LCOV_EXCL_LINE */ - - 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, UPDATE_ALL); - else - LOGE("unknown window error: %d", ev->win); /* LCOV_EXCL_LINE */ - - return ECORE_CALLBACK_RENEW; -} - -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); - - if (!cxt) { - LOGE("unknown window error: %d", ev->win); - return ECORE_CALLBACK_RENEW; - } + _E("unable to find window of %s", id); - if (cxt->state == WC_PAUSED && ev->fully_obscured == 0) { - __instance_resume(cxt->provider, cxt->id, UPDATE_ALL); - } else if (cxt->state == WC_RUNNING && ev->fully_obscured == 1) { - __instance_pause(cxt->provider, cxt->id, UPDATE_ALL); - } else { - LOGD("cxt:%s state:%d obscured:%d", cxt->id, cxt->state, ev->fully_obscured); - } - - return ECORE_CALLBACK_RENEW; -} - -/* LCOV_EXCL_START */ -static Eina_Bool __lower_cb(void *data, int type, void *event) -{ - LOGD("lower"); - return ECORE_CALLBACK_RENEW; -} -/* LCOV_EXCL_STOP */ - -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); /* LCOV_EXCL_LINE */ - return ECORE_CALLBACK_RENEW; /* LCOV_EXCL_LINE */ - } - - if (cxt->state == WC_PAUSED || cxt->state == WC_RUNNING) - __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; -} - -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); + if (class_cxt->callback.resize) + class_cxt->callback.resize(cxt, w, h, class_cxt->data); + _D("%s is resized to %dx%d", id, w, h); + __send_update_status(class_id, id, + WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL); } -static void __get_content(bundle *b) +static void __inst_cb(const char *class_id, const char *id, + appcore_multiwindow_base_instance_h cxt, void *data) { - char *instance_id = NULL; - widget_context_s *cxt = NULL; - - bundle_get_str(b, AUL_K_WIDGET_INSTANCE_ID, &instance_id); - if (!instance_id) - return; + struct widget_class_context *class_cxt; + const appcore_multiwindow_base_class *cls; + bundle *content = NULL; + char *content_raw = NULL; + char *force_str = NULL; + int force; + bundle *b = data; - cxt = __find_context_by_id(instance_id); - if (!cxt) { - _E("can not find instance id:%s", instance_id); + if (!b) { + _E("bundle is NULL"); return; } - if (cxt->content) { - bundle_add_str(b, AUL_K_WIDGET_CONTENT_INFO, cxt->content); - _D("content info of %s found", cxt->id); - } else { - bundle_add_str(b, AUL_K_WIDGET_CONTENT_INFO, ""); - _D("empty content info added"); + cls = appcore_multiwindow_base_instance_get_class(cxt); + if (!cls) { + _E("class is NULL"); + return; } -} -static int __aul_handler(aul_type type, bundle *b, void *data) -{ - char *caller = NULL; - char *remain = NULL; - - switch (type) { - case AUL_START: - if (b) { - bundle_get_str(b, WIDGET_K_CALLER, &caller); - if (caller) { - caller_pid = g_ascii_strtoll(caller, &remain, - 10); - } else { - /* using caller appid and query pid using caller appid? */ - _E("no caller pid"); - } - } - - __control(b); - break; - case AUL_RESUME: - __resume_all(UPDATE_ALL); - break; - case AUL_TERMINATE: - widget_app_exit(); - break; - case AUL_WIDGET_CONTENT: - __get_content(b); - break; - default: - break; + class_cxt = cls->data; + if (!class_cxt) { + _E("class context is NULL"); + return; } - return 0; -} - -static char *__get_domain_name(char *appid) -{ - char *name_token; - - if (appid == NULL) { - _E("appid is NULL"); /* LCOV_EXCL_LINE */ - return NULL; /* LCOV_EXCL_LINE */ + if (!class_cxt->callback.update) { + _E("update callback is NULL"); + return; } - name_token = strrchr(appid, '.'); - - if (name_token == NULL) { - _E("appid is invalid"); /* LCOV_EXCL_LINE */ - return appid; /* LCOV_EXCL_LINE */ - } + bundle_get_str(b, WIDGET_K_FORCE, &force_str); - name_token++; + if (force_str && strcmp(force_str, "true") == 0) + force = 1; + else + force = 0; - return name_token; -} + bundle_get_str(b, WIDGET_K_CONTENT_INFO, &content_raw); -/* LCOV_EXCL_START */ -static void __on_poweroff(keynode_t *key, void *data) -{ - int val; + if (content_raw) + content = bundle_decode((const bundle_raw *)content_raw, strlen(content_raw)); + class_cxt->callback.update(cxt, content, force, class_cxt->data); + __send_update_status(class_id, id, + WIDGET_INSTANCE_EVENT_UPDATE, NULL); + _D("updated:%s", id); - 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; - } + if (content) + bundle_free(content); } -/* LCOV_EXCL_STOP */ - -extern int _set_i18n(const char *name); -static int __before_loop(int argc, char **argv) +static void __instance_update(const char *class_id, const char *id, bundle *b) { - int r; - bundle *kb = NULL; - char *name; - char *viewer_endpoint = NULL; - -#if !(GLIB_CHECK_VERSION(2, 36, 0)) - g_type_init(); -#endif + appcore_multiwindow_base_instance_h cxt; - kb = bundle_import_from_argv(argc, argv); - if (kb) { - bundle_get_str(kb, WIDGET_K_ENDPOINT, &viewer_endpoint); - if (viewer_endpoint) { - _E("viewer endpoint :%s", viewer_endpoint); - _widget_app_set_viewer_endpoint(viewer_endpoint); - } else { - _E("endpoint is missing"); - } - - bundle_free(kb); - kb = NULL; - } else { - _E("failed to get launch argv"); /* LCOV_EXCL_LINE */ - } - - screen_connector_provider_init(); - elm_init(argc, argv); - - r = aul_launch_init(__aul_handler, NULL); - if (r < 0) { - /* LCOV_EXCL_START */ - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, - __FUNCTION__, - "Fail to call the aul_launch_init"); - /* LCOV_EXCL_STOP */ - } - - r = aul_launch_argv_handler(argc, argv); - if (r < 0) { - /* LCOV_EXCL_START */ - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, - __FUNCTION__, - "Fail to call the aul_launch_argv_handler"); - /* LCOV_EXCL_STOP */ - } - - r = app_get_id(&appid); - if (r != APP_ERROR_NONE) - return r; - - name = __get_domain_name(appid); - - if (name == NULL) { - /* LCOV_EXCL_START */ - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, - __FUNCTION__, - "Fail to call __get_domain_name"); - /* LCOV_EXCL_STOP */ - } - - r = _set_i18n(name); - - if (r < 0) { - /* LCOV_EXCL_START */ - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, - __FUNCTION__, - "Fail to call _set_i18n"); - /* LCOV_EXCL_STOP */ - } - - __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"); + if (!id) { + appcore_multiwindow_base_instance_foreach(class_id, __inst_cb, b); + return; } - vconf_notify_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, __on_poweroff, NULL); - - return WIDGET_ERROR_NONE; -} - -static void __after_loop() -{ - exit_called = 1; - vconf_ignore_key_changed(VCONFKEY_SYSMAN_POWER_OFF_STATUS, __on_poweroff); - - __pause_all(UPDATE_LOCAL); - __destroy_all(WIDGET_APP_DESTROY_TYPE_TEMPORARY, UPDATE_ALL); + cxt = appcore_multiwindow_base_instance_find(id); - if (app_ops->terminate) - app_ops->terminate(app_user_data); - - screen_connector_provider_fini(); - - _widget_app_free_viewer_endpoint(); - _widget_core_unset_appcore_event_cb(); - __free_handler_list(); - - if (package_id) { - free(package_id); - package_id = NULL; - } - - if (appid) { - free(appid); - appid = NULL; + if (!cxt) { + _E("context not found: %s", id); + return; } - elm_shutdown(); + __inst_cb(class_id, id, cxt, b); } -static void __on_low_memory(keynode_t *key, void *data) +static void __instance_create(const char *class_id, const char *id, bundle *b) { - 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]); + struct widget_extra *we; + char *content = NULL; - while (iter) { - handler = (app_event_handler_h) iter->data; - handler->cb(&event, handler->data); - iter = g_list_next(iter); - } + we = (struct widget_extra *)calloc(1, sizeof(struct widget_extra)); + if (!we) { + _E("Out of memory"); + return; } -} - -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]); + we->instance_id = strdup(id); + we->args = b; + appcore_multiwindow_base_instance_run(class_id, id, we); + we->args = NULL; + we->win = NULL; + bundle_get_str(b, WIDGET_K_CONTENT_INFO, &content); + if (content) + we->content = strdup(content); - 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) +static void __check_empty_instance(void) { - 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"); + int cnt = appcore_multiwindow_base_instance_get_cnt(); - event.type = APP_EVENT_LANGUAGE_CHANGED; - event.value = (void *)val; + if (cnt == 0) + widget_app_exit(); +} - GList *iter = g_list_first(handler_list[APP_EVENT_LANGUAGE_CHANGED]); +static void __instance_destroy(const char *class_id, const char *id, bundle *b) +{ + appcore_multiwindow_base_instance_h cxt; + struct widget_extra *we; - while (iter) { - handler = (app_event_handler_h) iter->data; - handler->cb(&event, handler->data); - iter = g_list_next(iter); + cxt = appcore_multiwindow_base_instance_find(id); + if (!cxt) { + _E("could not find widget obj: %s, clear amd info", id); + aul_widget_instance_del(class_id, id); + return; } + + we = appcore_multiwindow_base_instance_get_extra(cxt); + we->args = b; + appcore_multiwindow_base_instance_exit(cxt); + free(we->instance_id); + free(we->content); + free(we); + __check_empty_instance(); } -static void __on_region_changed(keynode_t *key, void *data) +static int __widget_app_control(bundle *b, void *data) { - char *val; - - _update_region(); - val = vconf_keynode_get_str(key); + char *class_id = NULL; + char *id = NULL; + char *operation = NULL; - app_event_handler_h handler; - struct app_event_info event; + appcore_multiwindow_base_on_control(b); - _I("widget_app_region_changed"); + bundle_get_str(b, WIDGET_K_CLASS, &class_id); + /* for previous version compatibility, use appid for default class id */ + if (class_id == NULL) + class_id = __appid; - event.type = APP_EVENT_REGION_FORMAT_CHANGED; - event.value = (void *)val; + bundle_get_str(b, AUL_K_WIDGET_INSTANCE_ID, &id); + bundle_get_str(b, WIDGET_K_OPERATION, &operation); - GList *iter = g_list_first(handler_list[APP_EVENT_REGION_FORMAT_CHANGED]); + if (!operation) { + _E("operation is NULL"); + return 0; + } - while (iter) { - handler = (app_event_handler_h) iter->data; - handler->cb(&event, handler->data); - iter = g_list_next(iter); + if (strcmp(operation, "create") == 0) { + __instance_create(class_id, id, b); + } else if (strcmp(operation, "resize") == 0) { + __instance_resize(class_id, id, b); + } else if (strcmp(operation, "update") == 0) { + __instance_update(class_id, id, b); + } else if (strcmp(operation, "destroy") == 0) { + __instance_destroy(class_id, id, b); + } else if (strcmp(operation, "resume") == 0) { + __instance_resume(class_id, id, b); + } else if (strcmp(operation, "pause") == 0) { + __instance_pause(class_id, id, b); + } else if (strcmp(operation, "terminate") == 0) { + __instance_destroy(class_id, id, b); } + + return 0; } -static void __register_event(int event_type) +static void __inst_resume_cb(const char *class_id, const char *id, + appcore_multiwindow_base_instance_h cxt, void *data) { - switch (event_type) { - case APP_EVENT_LOW_MEMORY: - vconf_notify_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory, NULL); - break; + __instance_resume(class_id, id, data); +} - case APP_EVENT_LOW_BATTERY: - vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery, NULL); - break; +static void __get_content(bundle *b) +{ + char *instance_id = NULL; + appcore_multiwindow_base_instance_h cxt; + struct widget_extra *we; - case APP_EVENT_LANGUAGE_CHANGED: - vconf_notify_key_changed(VCONFKEY_LANGSET, __on_lang_changed, NULL); - break; + bundle_get_str(b, AUL_K_WIDGET_INSTANCE_ID, &instance_id); + if (!instance_id) { + _E("instance id is NULL"); + return; + } - case APP_EVENT_REGION_FORMAT_CHANGED: - vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, __on_region_changed, NULL); - break; + cxt = appcore_multiwindow_base_instance_find(instance_id); + if (!cxt) { + _E("could not find widget obj: %s", instance_id); + return; + } + + we = appcore_multiwindow_base_instance_get_extra(cxt); + if (!we) { + _E("widget extra is NULL"); + return; + } + + if (we->content) { + bundle_add_str(b, AUL_K_WIDGET_CONTENT_INFO, we->content); + _D("content info of %s found", instance_id); + } else { + bundle_add_str(b, AUL_K_WIDGET_CONTENT_INFO, ""); + _D("empty content info added"); } } -static void __unregister_event(int event_type) +static int __widget_app_receive(aul_type type, bundle *b, void *data) { - switch (event_type) { - case APP_EVENT_LOW_MEMORY: - vconf_ignore_key_changed(VCONFKEY_SYSMAN_LOW_MEMORY, __on_low_memory); - break; + appcore_multiwindow_base_on_receive(type, b); - case APP_EVENT_LOW_BATTERY: - vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_STATUS_LOW, __on_low_battery); + switch (type) { + case AUL_RESUME: + appcore_multiwindow_base_instance_foreach_full(__inst_resume_cb, b); break; - - case APP_EVENT_LANGUAGE_CHANGED: - vconf_ignore_key_changed(VCONFKEY_LANGSET, __on_lang_changed); + case AUL_TERMINATE: + widget_app_exit(); break; - - case APP_EVENT_REGION_FORMAT_CHANGED: - vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, __on_region_changed); + case AUL_WIDGET_CONTENT: + __get_content(b); + break; + default: 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); + return 0; } EXPORT_API int widget_app_main(int argc, char **argv, widget_app_lifecycle_callback_s *callback, void *user_data) { - int r; + bundle *kb; + char *viewer_endpoint = NULL; - if (!_is_widget_feature_enabled()) { + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */ } @@ -1205,74 +629,92 @@ EXPORT_API int widget_app_main(int argc, char **argv, return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); + if (__context.dirty) { + _E("Already started"); + return widget_app_error(WIDGET_ERROR_FAULT, __FUNCTION__, NULL); + } + if (callback->create == NULL) 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; - r = __before_loop(argc, argv); - if (r < 0) { - if (appid) { - free(appid); - appid = NULL; + + appcore_multiwindow_base_ops ops = appcore_multiwindow_base_get_default_ops(); + + /* override methods */ + ops.base.create = __widget_app_create; + ops.base.control = __widget_app_control; + ops.base.terminate = __widget_app_terminate; + ops.base.receive = __widget_app_receive; + __context.callback = *callback; + __context.data = user_data; + kb = bundle_import_from_argv(argc, argv); + if (kb) { + bundle_get_str(kb, WIDGET_K_ENDPOINT, &viewer_endpoint); + if (viewer_endpoint) { + _D("viewer endpoint :%s", viewer_endpoint); + _viewer_endpoint = strdup(viewer_endpoint); + } else { + _E("endpoint is missing"); } - return r; + + bundle_free(kb); + } else { + _E("failed to get launch argv"); /* LCOV_EXCL_LINE */ + return widget_app_error(WIDGET_ERROR_FAULT, __FUNCTION__, NULL); } - ecore_main_loop_begin(); - aul_status_update(STATUS_DYING); - __after_loop(); + __context.dirty = true; + appcore_multiwindow_base_init(ops, argc, argv, NULL); + appcore_multiwindow_base_fini(); + __context.dirty = false; return WIDGET_ERROR_NONE; } EXPORT_API int widget_app_exit(void) { - if (!_is_widget_feature_enabled()) { + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */ } - if (exit_called) - return WIDGET_ERROR_NONE; - - exit_called = 1; - - ecore_main_loop_quit(); - + appcore_multiwindow_base_exit(); return WIDGET_ERROR_NONE; } -/* LCOV_EXCL_START */ static gboolean __finish_event_cb(gpointer user_data) { - if (user_data == NULL) + appcore_multiwindow_base_instance_h cxt = user_data; + bundle *b; + const char *id; + const char *class_id; + + if (!cxt) { + _E("user_data is NULL"); return FALSE; + } - widget_context_s *wc = (widget_context_s *)user_data; + id = appcore_multiwindow_base_instance_get_id(cxt); + class_id = appcore_multiwindow_base_instance_get_class_id(cxt); + b = bundle_create(); - switch (wc->state) { - case WC_READY: - __instance_resume(wc->provider, wc->id, UPDATE_LOCAL); - case WC_RUNNING: - __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; + if (!b) { + _E("Out-of-memory"); + return FALSE; } + bundle_add_str(b, WIDGET_K_OPERATION, "terminate"); + __instance_destroy(class_id, id, b); + bundle_free(b); + return FALSE; } -/* LCOV_EXCL_STOP */ EXPORT_API int widget_app_terminate_context(widget_context_h context) { - if (!_is_widget_feature_enabled()) { + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */ } @@ -1285,40 +727,61 @@ EXPORT_API int widget_app_terminate_context(widget_context_h context) return WIDGET_ERROR_NONE; } +static void __inst_full_cb(const char *class_id, const char *id, + appcore_multiwindow_base_instance_h cxt, void *data) +{ + struct widget_foreach_context *foreach_context = data; + + if (!data) + return; + + if (foreach_context->callback) + foreach_context->callback(cxt, foreach_context->data); +} + EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data) { - GList *contexts = _widget_app_get_contexts(); - GList *list; - widget_context_s *wc; + struct widget_foreach_context foreach_context; - if (!_is_widget_feature_enabled()) { + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */ } - if (!cb) + if (!cb) { + _E("callback is NULL"); 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; } + foreach_context.callback = cb; + foreach_context.data = data; + appcore_multiwindow_base_instance_foreach_full(__inst_full_cb, &foreach_context); + return WIDGET_ERROR_NONE; } +int __event_cb(void *event, void *data) +{ + app_event_handler_h handler = data; + + struct app_event_info app_event; + + app_event.type = handler->type; + app_event.value = event; + + if (handler->cb) + handler->cb(&app_event, handler->data); + + return 0; +} + 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) { int r; bool feature; + app_event_handler_h handler; r = system_info_get_platform_bool(FEATURE_SHELL_APPWIDGET, &feature); if (r < 0) @@ -1327,8 +790,6 @@ EXPORT_API int widget_app_add_event_handler(app_event_handler_h *event_handler, if (!feature) return WIDGET_ERROR_NOT_SUPPORTED; - app_event_handler_h handler; - if (event_handler == NULL || callback == NULL) return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); @@ -1339,29 +800,15 @@ EXPORT_API int widget_app_add_event_handler(app_event_handler_h *event_handler, 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); /* LCOV_EXCL_LINE */ - - if (g_list_length(handler_list[event_type]) == 0) - __register_event(event_type); + return widget_app_error(WIDGET_ERROR_OUT_OF_MEMORY, __FUNCTION__, "failed to create handler"); handler->type = event_type; handler->cb = callback; handler->data = user_data; - handler_list[event_type] = g_list_append(handler_list[event_type], handler); - + handler->raw = appcore_base_add_event(__app_event_converter[event_type], __event_cb, handler); *event_handler = handler; return WIDGET_ERROR_NONE; @@ -1389,18 +836,18 @@ EXPORT_API int widget_app_remove_event_handler(app_event_handler_h 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); + r = appcore_base_remove_event(event_handler->raw); + if (r < 0) + return widget_app_error(APP_ERROR_INVALID_PARAMETER, __FUNCTION__, "invalid raw handler"); - if (g_list_length(handler_list[type]) == 0) - __unregister_event(type); + free(event_handler); return WIDGET_ERROR_NONE; } EXPORT_API const char *widget_app_get_id(widget_context_h context) { - if (!_is_widget_feature_enabled()) { + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ set_last_result(WIDGET_ERROR_NOT_SUPPORTED); /* LCOV_EXCL_LINE */ return NULL; /* LCOV_EXCL_LINE */ @@ -1412,12 +859,11 @@ EXPORT_API const char *widget_app_get_id(widget_context_h context) } set_last_result(WIDGET_ERROR_NONE); - return context->id; + return appcore_multiwindow_base_instance_get_id(context); } -static void _win_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) +static void __win_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) { - /* Remove data used in accessibility */ char *plug_id; plug_id = evas_object_data_del(obj, "___PLUGID"); free(plug_id); @@ -1426,14 +872,17 @@ static void _win_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info) EXPORT_API int widget_app_get_elm_win(widget_context_h context, Evas_Object **win) { - widget_context_s *cxt = (widget_context_s *)context; Evas_Object *ret_win; Ecore_Wl_Window *wl_win; struct wl_surface *surface; + struct widget_extra *we; char buffer[256]; int rots[3] = {0}; + int win_id; + const char *id; + appcore_multiwindow_base_instance_h cxt; - if (!_is_widget_feature_enabled()) { + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */ } @@ -1442,7 +891,9 @@ EXPORT_API int widget_app_get_elm_win(widget_context_h context, return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - ret_win = elm_win_add(NULL, cxt->id, ELM_WIN_BASIC); + cxt = (appcore_multiwindow_base_instance_h)context; + id = appcore_multiwindow_base_instance_get_id(cxt); + ret_win = elm_win_add(NULL, id, ELM_WIN_BASIC); if (ret_win == NULL) { _E("failed to create window"); /* LCOV_EXCL_LINE */ goto fault; /* LCOV_EXCL_LINE */ @@ -1462,21 +913,23 @@ EXPORT_API int widget_app_get_elm_win(widget_context_h context, _E("failed to get surface"); /* LCOV_EXCL_LINE */ goto fault; /* LCOV_EXCL_LINE */ } - screen_connector_provider_remote_enable(cxt->id, surface); + screen_connector_provider_remote_enable(id, surface); - ecore_wl_window_class_name_set(wl_win, cxt->id); + ecore_wl_window_class_name_set(wl_win, id); elm_win_aux_hint_add(ret_win, "wm.policy.win.user.geometry", "1"); *win = ret_win; - cxt->win = ret_win; - cxt->win_id = ecore_wl_window_id_get(wl_win); + we = appcore_multiwindow_base_instance_get_extra(cxt); + we->win = ret_win; + win_id = ecore_wl_window_id_get(wl_win); /* Set data to use in accessibility */ - snprintf(buffer, sizeof(buffer), "%s:%d", cxt->id, getpid()); + snprintf(buffer, sizeof(buffer), "%s:%d", id, getpid()); evas_object_data_set(ret_win, "___PLUGID", strdup(buffer)); - evas_object_event_callback_add(ret_win, EVAS_CALLBACK_DEL, _win_del_cb, NULL); + evas_object_event_callback_add(ret_win, EVAS_CALLBACK_DEL, __win_del_cb, NULL); + appcore_multiwindow_base_window_bind(cxt, ret_win); - _D("window created: %d", cxt->win_id); + _D("window created: %d", win_id); return WIDGET_ERROR_NONE; @@ -1485,88 +938,264 @@ fault: evas_object_del(ret_win); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_FAULT; /* LCOV_EXCL_LINE */ +} +static void __instance_drop(appcore_multiwindow_base_instance_h cxt) +{ + struct widget_extra *we; + + we = appcore_multiwindow_base_instance_get_extra(cxt); + appcore_multiwindow_base_instance_drop(cxt); + free(we->instance_id); + free(we->content); + free(we); + __check_empty_instance(); } -widget_class_h _widget_class_create(widget_class_s *prev, const char *class_id, - widget_instance_lifecycle_callback_s callback, void *user_data) +static void __stub_create(appcore_multiwindow_base_instance_h context, void *data) { - widget_class_s *wc; + struct widget_class_context *cxt = data; + struct widget_extra *we; + bundle *b; + bundle *content_info = NULL; + char *id = NULL; + char *class_id = NULL; + char *operation = NULL; + char *content = NULL; + char *w_str = NULL; + char *h_str = NULL; + char *remain = NULL; + int w = 0; + int h = 0; + int ret = -1; - if (!_is_widget_feature_enabled()) { - _E("not supported"); /* LCOV_EXCL_LINE */ - set_last_result(WIDGET_ERROR_NOT_SUPPORTED); /* LCOV_EXCL_LINE */ - return NULL; + appcore_multiwindow_base_class_on_create(context); + we = appcore_multiwindow_base_instance_get_extra((appcore_multiwindow_base_instance_h)context); + b = we->args; + + bundle_get_str(b, WIDGET_K_CLASS, &class_id); + /* for previous version compatibility, use appid for default class id */ + if (class_id == NULL) + class_id = __appid; + + bundle_get_str(b, AUL_K_WIDGET_INSTANCE_ID, &id); + bundle_get_str(b, WIDGET_K_OPERATION, &operation); + + if (!operation) { + _E("no operation provided"); + return; } - if (class_id == NULL) { - set_last_result(WIDGET_ERROR_INVALID_PARAMETER); - return NULL; + 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 (content) + content_info = bundle_decode((const bundle_raw *)content, strlen(content)); + + if (cxt->callback.create) + ret = cxt->callback.create(context, content_info, w, h, cxt->data); + _D("%s is created %d", id); + + if (ret < 0) { + _W("Create callback resturns error(%d)", ret); + ret = __send_update_status(class_id, id, + WIDGET_INSTANCE_EVENT_CREATE_ABORTED, NULL); + __instance_drop(context); + } else { + ret = __send_update_status(class_id, id, + WIDGET_INSTANCE_EVENT_CREATE, NULL); + + aul_widget_instance_add(class_id, id); } - wc = (widget_class_s *)calloc(1, sizeof(widget_class_s)); - if (wc == NULL) { - _E("failed to calloc : %s", __FUNCTION__); /* LCOV_EXCL_LINE */ - set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); /* LCOV_EXCL_LINE */ - return NULL; /* LCOV_EXCL_LINE */ + if (content_info) + bundle_free(content_info); +} + +static void __stub_terminate(appcore_multiwindow_base_instance_h context, void *data) +{ + struct widget_class_context *class_cxt = data; + struct widget_extra *we; + bundle *b; + char *operation = NULL; + bundle *content_info; + widget_app_destroy_type_e reason = WIDGET_APP_DESTROY_TYPE_TEMPORARY; + int event = WIDGET_INSTANCE_EVENT_TERMINATE; + const char *id; + const char *class_id; + + id = appcore_multiwindow_base_instance_get_id(context); + class_id = appcore_multiwindow_base_instance_get_class_id(context); + we = appcore_multiwindow_base_instance_get_extra((appcore_multiwindow_base_instance_h)context); + b = we->args; + + if (b) { + bundle_get_str(b, WIDGET_K_OPERATION, &operation); + if (operation && strcmp(operation, "destroy") == 0) + reason = WIDGET_APP_DESTROY_TYPE_PERMANENT; } - wc->classid = strdup(class_id); - wc->user_data = user_data; - wc->ops = callback; - wc->next = prev; - wc->prev = NULL; + if (we->content) + content_info = bundle_decode((const bundle_raw *)we->content, strlen(we->content)); + else + content_info = bundle_create(); + + if (class_cxt->callback.destroy) + class_cxt->callback.destroy(context, reason, content_info, class_cxt->data); + _D("%s is destroyed %d", id, reason); - set_last_result(WIDGET_ERROR_NONE); + if (reason == WIDGET_APP_DESTROY_TYPE_PERMANENT) { + event = WIDGET_INSTANCE_EVENT_DESTROY; + aul_widget_instance_del(class_id, id); + } else { + __send_update_status(class_id, id, + WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, content_info); + } + + if (content_info) + bundle_free(content_info); + + __send_update_status(class_id, id, event, NULL); + appcore_multiwindow_base_class_on_terminate(context); +} + +static void __stub_pause(appcore_multiwindow_base_instance_h context, void *data) +{ + struct widget_class_context *class_cxt = data; + const char *id; + const char *class_id; + + appcore_multiwindow_base_class_on_pause(context); + id = appcore_multiwindow_base_instance_get_id(context); + class_id = appcore_multiwindow_base_instance_get_class_id(context); + + if (!class_cxt) { + _E("class context is NULL"); + return; + } + + if (class_cxt->callback.update) + class_cxt->callback.pause(context, class_cxt->data); + _D("%s is paused", id); + __send_update_status(class_id, id, + WIDGET_INSTANCE_EVENT_PAUSE, NULL); +} + +static void __stub_resume(appcore_multiwindow_base_instance_h context, void *data) +{ + struct widget_class_context *class_cxt = data; + const char *id; + const char *class_id; - if (prev) - prev->prev = wc; + appcore_multiwindow_base_class_on_resume(context); + id = appcore_multiwindow_base_instance_get_id(context); + class_id = appcore_multiwindow_base_instance_get_class_id(context); - return wc; + if (!class_cxt) { + _E("class context is NULL"); + return; + } + + if (class_cxt->callback.resume) + class_cxt->callback.resume(context, class_cxt->data); + _D("%s is resumed", id); + __send_update_status(class_id, id, + WIDGET_INSTANCE_EVENT_RESUME, NULL); } 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); + appcore_multiwindow_base_class cls; + struct widget_class_context *cxt; + + if (!__is_widget_feature_enabled()) { + _E("not supported"); + set_last_result(WIDGET_ERROR_NOT_SUPPORTED); + return NULL; + } + + if (!class_id) { + _E("class is is NULL"); + set_last_result(WIDGET_ERROR_INVALID_PARAMETER); + return NULL; + } + + cxt = calloc(1, sizeof(struct widget_class_context)); + + if (!cxt) { + _E("failed to calloc : %s", __FUNCTION__); + set_last_result(WIDGET_ERROR_OUT_OF_MEMORY); + return NULL; + } + + cxt->callback = callback; + cxt->data = user_data; + + cls.id = strdup(class_id); + cls.data = cxt; + cls.create = __stub_create; + cls.terminate = __stub_terminate; + cls.pause = __stub_pause; + cls.resume = __stub_resume; + + appcore_multiwindow_base_class_add(cls); + set_last_result(WIDGET_ERROR_NONE); + + return (widget_class_h)cxt; } 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); + return widget_app_class_add(NULL, __appid, callback, user_data); } EXPORT_API int widget_app_context_set_tag(widget_context_h context, void *tag) { - if (!_is_widget_feature_enabled()) { + struct widget_extra *we; + + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */ } - if (context == NULL) + if (!context) return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - context->tag = tag; + we = appcore_multiwindow_base_instance_get_extra((appcore_multiwindow_base_instance_h)context); + we->extra = tag; return WIDGET_ERROR_NONE; } EXPORT_API int widget_app_context_get_tag(widget_context_h context, void **tag) { - if (!_is_widget_feature_enabled()) { + struct widget_extra *we; + + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */ } - if (context == NULL || tag == NULL) + if (!context || !tag) return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - *tag = context->tag; + we = appcore_multiwindow_base_instance_get_extra((appcore_multiwindow_base_instance_h)context); + if (we == NULL) + return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, + __FUNCTION__, NULL); + *tag = we->extra; return WIDGET_ERROR_NONE; } @@ -1574,44 +1203,47 @@ EXPORT_API int widget_app_context_get_tag(widget_context_h context, void **tag) EXPORT_API int widget_app_context_set_content_info(widget_context_h context, bundle *content_info) { - const char *class_id = NULL; int ret = 0; bundle_raw *raw = NULL; int len; + const char *id; + const char *class_id; + struct widget_extra *we; + appcore_multiwindow_base_instance_h cxt; - if (!_is_widget_feature_enabled()) { + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */ } - if (context == NULL || content_info == NULL) + if (!context || !content_info) return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, __FUNCTION__, NULL); - if (context->provider == NULL) - return widget_app_error(WIDGET_ERROR_INVALID_PARAMETER, - __FUNCTION__, NULL); + cxt = (appcore_multiwindow_base_instance_h)context; + id = appcore_multiwindow_base_instance_get_id(cxt); + class_id = appcore_multiwindow_base_instance_get_class_id(cxt); + we = appcore_multiwindow_base_instance_get_extra(cxt); - class_id = context->provider->classid; - if (class_id == NULL) + if (!class_id || !id || !we) return widget_app_error(WIDGET_ERROR_FAULT, __FUNCTION__, NULL); - ret = __send_update_status(class_id, context->id, + ret = __send_update_status(class_id, id, WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, content_info); - if (context->content) - free(context->content); + if (we->content) + free(we->content); bundle_encode(content_info, &raw, &len); if (raw) - context->content = strdup((const char *)raw); + we->content = strdup((const char *)raw); else - context->content = NULL; + we->content = NULL; free(raw); if (ret < 0) { /* LCOV_EXCL_START */ - _E("failed to send content info: %s of %s (%d)", context->id, + _E("failed to send content info: %s of %s (%d)", id, class_id, ret); return widget_app_error(WIDGET_ERROR_IO_ERROR, __FUNCTION__, NULL); @@ -1624,16 +1256,24 @@ EXPORT_API int widget_app_context_set_content_info(widget_context_h context, EXPORT_API int widget_app_context_set_title(widget_context_h context, const char *title) { - if (!_is_widget_feature_enabled()) { + appcore_multiwindow_base_instance_h cxt; + struct widget_extra *we; + + if (!__is_widget_feature_enabled()) { _E("not supported"); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_NOT_SUPPORTED; /* LCOV_EXCL_LINE */ } - if (!context || !title) + if (!context || !title) { + _E("Invalid parameter %p %p", context, title); return WIDGET_ERROR_INVALID_PARAMETER; + } + + cxt = (appcore_multiwindow_base_instance_h)context; + we = appcore_multiwindow_base_instance_get_extra(cxt); - if (context->win) - elm_win_title_set(context->win, title); + if (we->win) + elm_win_title_set(we->win, title); return WIDGET_ERROR_NONE; } diff --git a/src/widget_app_internal.c b/src/widget_app_internal.c index 45b56d8..302248f 100644 --- a/src/widget_app_internal.c +++ b/src/widget_app_internal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2017 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,6 +27,7 @@ #include #include #include +#include #include "widget_app.h" #include "widget-log.h" @@ -39,31 +40,34 @@ #endif #define LOG_TAG "CAPI_WIDGET_APPLICATION" +extern char *_viewer_endpoint; +static char *__class_id; -static char *viewer_endpoint = NULL; -static GList *contexts = NULL; +static void __inst_cb(const char *class_id, const char *id, + appcore_multiwindow_base_instance_h cxt, void *data) +{ + if (!__class_id) + __class_id = strdup(class_id); +} -EXPORT_API int widget_app_restart() +EXPORT_API int widget_app_restart(void) { int ret; int status = AUL_WIDGET_INSTANCE_EVENT_APP_RESTART_REQUEST; bundle *kb; - widget_context_s *wc; - char *classid; - if (contexts == NULL) { - _E("no widget"); - return WIDGET_ERROR_IO_ERROR; - } - wc = (widget_context_s *)contexts->data; - classid = wc->provider->classid; - _D("restart widget classid : %s", classid); + appcore_multiwindow_base_instance_foreach_full(__inst_cb, NULL); kb = bundle_create(); - bundle_add_str(kb, AUL_K_WIDGET_ID, classid); + bundle_add_str(kb, AUL_K_WIDGET_ID, __class_id); bundle_add_byte(kb, AUL_K_WIDGET_STATUS, &status, sizeof(int)); - ret = aul_app_com_send(viewer_endpoint, kb); + ret = aul_app_com_send(_viewer_endpoint, kb); bundle_free(kb); + if (__class_id) { + free(__class_id); + __class_id = NULL; + } + if (ret != AUL_R_OK) { _E("failed to kill app"); return WIDGET_ERROR_IO_ERROR; @@ -71,44 +75,3 @@ EXPORT_API int widget_app_restart() return WIDGET_ERROR_NONE; } -GList *_widget_app_get_contexts() -{ - return contexts; -} - -int _widget_app_add_context(widget_context_s *wc) -{ - contexts = g_list_append(contexts, wc); - return WIDGET_ERROR_NONE; -} - -int _widget_app_remove_context(widget_context_s *wc) -{ - contexts = g_list_remove(contexts, wc); - return WIDGET_ERROR_NONE; -} - -int _widget_app_set_viewer_endpoint(char *endpoint) -{ - if (endpoint == NULL) - return WIDGET_ERROR_INVALID_PARAMETER; - - viewer_endpoint = strdup(endpoint); - if (viewer_endpoint == NULL) - return WIDGET_ERROR_OUT_OF_MEMORY; - - return WIDGET_ERROR_NONE; -} - -char *_widget_app_get_viewer_endpoint() -{ - return viewer_endpoint; -} - -int _widget_app_free_viewer_endpoint() -{ - if (viewer_endpoint) - free(viewer_endpoint); - - return WIDGET_ERROR_NONE; -} diff --git a/src/widget_error.c b/src/widget_error.c index bbe1549..8f90de4 100755 --- a/src/widget_error.c +++ b/src/widget_error.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015 - 2017 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. -- 2.7.4 From e07e23200583d5106aa08310ae5348a8cddb79ce Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Tue, 11 Apr 2017 13:11:14 +0900 Subject: [PATCH 15/16] Release version 1.1.0 Changes: Refactor appcore-widget using appcore_multiwindow_base Change-Id: Ieb5e602289b1194cc089971638430b3006011db4 Signed-off-by: Junghoon Park --- packaging/appcore-widget.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index 1c81f3c..6221a58 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -1,6 +1,6 @@ Name: appcore-widget Summary: Widget Application -Version: 1.0.4 +Version: 1.1.0 Release: 1 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From b2774407c9135edf6c5f403c9d775ea192a18344 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Wed, 12 Apr 2017 10:18:59 +0900 Subject: [PATCH 16/16] Fix typo Change-Id: I24c223935abdc39c47610f4bc52592ae273d360c Signed-off-by: Hyunho Kang --- src/widget_app.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widget_app.c b/src/widget_app.c index fcc7ae3..d0a8712 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -1004,7 +1004,7 @@ static void __stub_create(appcore_multiwindow_base_instance_h context, void *dat _D("%s is created %d", id); if (ret < 0) { - _W("Create callback resturns error(%d)", ret); + _W("Create callback returns error(%d)", ret); ret = __send_update_status(class_id, id, WIDGET_INSTANCE_EVENT_CREATE_ABORTED, NULL); __instance_drop(context); -- 2.7.4