From ae1eeb5eb6e7bec59ed96c4d80f8fa43ee818adb Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 16 Mar 2017 12:59:35 +0900 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 08/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 09/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 From 2aeb40b993d6156b0443475fc1a009f2eb8e1660 Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Thu, 13 Apr 2017 20:02:56 +0900 Subject: [PATCH 10/16] Fix bug about checking pause callback Change-Id: Ia43d1d2c31e6deb9f23ab6156db688604876eccc Signed-off-by: Junghoon Park --- 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 d0a8712..b059fc2 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -1081,7 +1081,7 @@ static void __stub_pause(appcore_multiwindow_base_instance_h context, void *data return; } - if (class_cxt->callback.update) + if (class_cxt->callback.pause) class_cxt->callback.pause(context, class_cxt->data); _D("%s is paused", id); __send_update_status(class_id, id, -- 2.7.4 From cae79319c4a2b82701761d0b3cd05334d6084fca Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Thu, 6 Apr 2017 18:08:08 +0900 Subject: [PATCH 11/16] Add more doxygen description about instance id Change-Id: I8b0531afd9dfc0ead7c62d2fa430a350bfd63a53 Signed-off-by: Hyunho Kang --- include/widget_app.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/include/widget_app.h b/include/widget_app.h index 5e29aea..cf1b275 100755 --- a/include/widget_app.h +++ b/include/widget_app.h @@ -326,13 +326,20 @@ int widget_app_remove_event_handler(app_event_handler_h event_handler); * @brief Gets a widget instance id. * @since_tizen 2.3.1 * @remarks The specific error code can be obtained using the get_last_result() method. Error codes are described in Exception section. - * @remark You must not free returned Widget ID + * @remark You must not free returned widget instance id + * @remark The returned widget instance id is volatile. If the device reboots or the widget's process restarts, it will be changed.\n + * So, you should not assume this value is a persistent one. + * @remark widget_service_trigger_update(), widget_service_change_period(), widget_service_get_content_of_widget_instance()\n + * can be called with returned instance id. * @param[in] context The context for widget instance - * @return Widget ID on success, - * otherwise NULL + * @return widget instance id on success, + * otherwise NULL * @exception #WIDGET_ERROR_NOT_SUPPORTED Not supported * @exception #WIDGET_ERROR_FAULT Unrecoverable error * @see get_last_result() + * @see widget_service_trigger_update() + * @see widget_service_change_period() + * @see widget_service_get_content_of_widget_instance() */ const char *widget_app_get_id(widget_context_h context); -- 2.7.4 From 31124c6416f300cb2c3814642daf6d485fc2832c Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Fri, 14 Apr 2017 11:02:13 +0900 Subject: [PATCH 12/16] Release version 1.1.1 Changes: - Add more doxygen description about instance id - Fix bug about checking pause callback - Fix typo Change-Id: Iae48ca2e885e7950e79825c376a87f6191fa2654 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 6221a58..3220322 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -1,6 +1,6 @@ Name: appcore-widget Summary: Widget Application -Version: 1.1.0 +Version: 1.1.1 Release: 1 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 6c3d8c4e54a19a8722392cd4186514292b372165 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Fri, 26 May 2017 10:43:43 +0900 Subject: [PATCH 13/16] Move unversioned so file to devel package Unversioned so file is not needed at runtime. It is only used at build time. Change-Id: I8e1833983498132e544993f90db5604c3db8a5b6 Signed-off-by: Hyunho Kang --- packaging/appcore-widget.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packaging/appcore-widget.spec b/packaging/appcore-widget.spec index 3220322..18c7fd2 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -54,7 +54,7 @@ cp capi-appfw-widget-application.pc %{buildroot}%{_libdir}/pkgconfig %files %manifest appcore-widget.manifest %defattr(-,root,root,-) -%{_libdir}/libcapi-appfw-widget-application.so* +%{_libdir}/libcapi-appfw-widget-application.so.* %license LICENSE %files -n capi-appfw-widget-application-devel @@ -62,4 +62,5 @@ cp capi-appfw-widget-application.pc %{buildroot}%{_libdir}/pkgconfig /usr/include/appfw/widget_app_efl.h /usr/include/appfw/widget_app_internal.h %{_libdir}/pkgconfig/capi-appfw-widget-application.pc +%{_libdir}/libcapi-appfw-widget-application.so -- 2.7.4 From 5fc3c815929af673eeb28d4f0f9fad2ffe2379f4 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 30 May 2017 19:12:24 +0900 Subject: [PATCH 14/16] Handle abnormal exit Whlie calling widget_app_exit(), the widget app sends the normal termination signal to the amd. If the amd doesn't get the signal when the widget app is dead, the amd will send the widget fault signal to the widget viewer. Requires: - https://review.tizen.org/gerrit/#/c/131674/ [aul-1] - https://review.tizen.org/gerrit/#/c/131685/ [amd] - https://review.tizen.org/gerrit/#/c/131692/ [widget-service] - https://review.tizen.org/gerrit/#/c/131695/ [widget-viewer] Change-Id: I2815cc30c51ad538e2069a87b7f405e602c585c4 Signed-off-by: Hwankyu Jhun --- src/widget_app.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widget_app.c b/src/widget_app.c index b059fc2..3840ac2 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -681,6 +681,8 @@ EXPORT_API int widget_app_exit(void) } appcore_multiwindow_base_exit(); + aul_widget_notify_exit(); + return WIDGET_ERROR_NONE; } -- 2.7.4 From 7f8984e3e6a2c5e57b4276fd35108af79940e605 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 1 Jun 2017 09:25:36 +0900 Subject: [PATCH 15/16] Release version 1.1.2 Changes: - Handle abnormal exit - Move unversioned so file to devel package Change-Id: I6c27b04200455d05c1324373a189a3b224552522 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 18c7fd2..42899da 100644 --- a/packaging/appcore-widget.spec +++ b/packaging/appcore-widget.spec @@ -1,6 +1,6 @@ Name: appcore-widget Summary: Widget Application -Version: 1.1.1 +Version: 1.1.2 Release: 1 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From f42c993425ba9047016c56762e84ddf1ac28692c Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 20 Jun 2017 14:50:05 +0900 Subject: [PATCH 16/16] Override multiwindow base methods The methods are init(), finish(), run() and exit(). The elementary dependency is removed from multiwindow base. Requires: - https://review.tizen.org/gerrit/#/c/134810/ Change-Id: Icc01285d3ca1313f20e5ad0767da7d78b8b6676e Signed-off-by: Hwankyu Jhun --- src/widget_app.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/widget_app.c b/src/widget_app.c index 3840ac2..4c20c2c 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -614,6 +614,33 @@ static int __widget_app_receive(aul_type type, bundle *b, void *data) return 0; } +static int __widget_app_init(int argc, char **argv, void *data) +{ + elm_init(argc, argv); + return 0; +} + +static void __widget_app_finish(void) +{ + elm_shutdown(); + + /* Check Loader case */ + if (getenv("AUL_LOADER_INIT")) { + unsetenv("AUL_LOADER_INIT"); + elm_shutdown(); + } +} + +static void __widget_app_run(void *data) +{ + elm_run(); +} + +static void __widget_app_exit(void *data) +{ + elm_exit(); +} + EXPORT_API int widget_app_main(int argc, char **argv, widget_app_lifecycle_callback_s *callback, void *user_data) { @@ -647,6 +674,11 @@ EXPORT_API int widget_app_main(int argc, char **argv, ops.base.control = __widget_app_control; ops.base.terminate = __widget_app_terminate; ops.base.receive = __widget_app_receive; + ops.base.init = __widget_app_init; + ops.base.finish = __widget_app_finish; + ops.base.run = __widget_app_run; + ops.base.exit = __widget_app_exit; + __context.callback = *callback; __context.data = user_data; kb = bundle_import_from_argv(argc, argv); @@ -929,7 +961,7 @@ EXPORT_API int widget_app_get_elm_win(widget_context_h context, 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); - appcore_multiwindow_base_window_bind(cxt, ret_win); + appcore_multiwindow_base_window_bind(cxt, wl_win); _D("window created: %d", win_id); -- 2.7.4