From 150f55cbec59b7f623b8381992b8db8a1e66ce87 Mon Sep 17 00:00:00 2001 From: Hyunho Kang Date: Mon, 18 Jul 2016 20:20:33 +0900 Subject: [PATCH] Add widget app restart logic Change-Id: I54bce1b3e0eba8c919a238c808986fdb814fc277 Signed-off-by: Hyunho Kang --- CMakeLists.txt | 1 + include/widget_app_internal.h | 3 + src/widget-private.h | 30 +++++++++ src/widget_app.c | 60 +++++++----------- src/widget_app_internal.c | 114 ++++++++++++++++++++++++++++++++++ 5 files changed, 170 insertions(+), 38 deletions(-) create mode 100644 src/widget_app_internal.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 652d965..8e4023a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ SET(APPCORE_WIDGET "capi-appfw-widget-application") SET(SRCS_widget src/widget-i18n.c src/widget_app.c + src/widget_app_internal.c src/widget_error.c ) SET(HEADERS_widget widget_app.h widget_app_efl.h widget_app_internal.h) diff --git a/include/widget_app_internal.h b/include/widget_app_internal.h index 024cfa9..c278012 100644 --- a/include/widget_app_internal.h +++ b/include/widget_app_internal.h @@ -27,6 +27,7 @@ extern "C" { * For in-house applications * */ + typedef struct { struct __pointer { double x; @@ -60,6 +61,8 @@ struct _widget_class_factory_full { }; const widget_class_factory_full_s *widget_app_get_class_factory(void); +int widget_app_restart(); + #ifdef __cplusplus } diff --git a/src/widget-private.h b/src/widget-private.h index ef6d32c..847c099 100644 --- a/src/widget-private.h +++ b/src/widget-private.h @@ -18,12 +18,42 @@ #ifndef __APPCORE_WIDGET_PRIVATE_H__ #define __APPCORE_WIDGET_PRIVATE_H__ +#include + +#include #include #include #include #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); diff --git a/src/widget_app.c b/src/widget_app.c index 9d717ae..f90e7ec 100755 --- a/src/widget_app.c +++ b/src/widget_app.c @@ -62,14 +62,6 @@ enum { UPDATE_ALL = 1, }; -struct _widget_class { - void *user_data; - widget_instance_lifecycle_callback_s ops; - char *classid; - struct _widget_class *next; - struct _widget_class *prev; -}; - struct app_event_handler { app_event_type_e type; app_event_cb cb; @@ -81,19 +73,7 @@ struct app_event_info { void *value; }; -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_class widget_class_s; -typedef struct _widget_context widget_context_s; #define WIDGET_APP_EVENT_MAX 5 static GList *handler_list[WIDGET_APP_EVENT_MAX] = {NULL, }; @@ -103,8 +83,6 @@ static widget_app_lifecycle_callback_s *app_ops; static void *app_user_data; static char *appid; static widget_class_h class_provider; -static GList *contexts; -static char *viewer_endpoint; static int exit_called; static void _widget_core_set_appcore_event_cb(void); @@ -157,6 +135,7 @@ static gint __comp_by_id(gconstpointer a, gconstpointer b) static widget_context_s *__find_context_by_id(const char *id) { GList *ret; + GList *contexts = _widget_app_get_contexts(); if (id == NULL) return NULL; @@ -178,6 +157,7 @@ static gint __comp_by_win(gconstpointer a, gconstpointer b) 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 (ret == NULL) @@ -197,9 +177,9 @@ static int __send_lifecycle_event(const char *class_id, const char *instance_id, return -1; /* LCOV_EXCL_LINE */ } - bundle_add_str(b, WIDGET_K_ID, class_id); - bundle_add_str(b, WIDGET_K_INSTANCE, instance_id); - bundle_add_byte(b, WIDGET_K_STATUS, &status, sizeof(int)); + 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)); _D("send lifecycle %s(%d)", instance_id, status); ret = aul_app_com_send("widget.status", b); @@ -218,6 +198,7 @@ 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) { @@ -225,9 +206,9 @@ static int __send_update_status(const char *class_id, const char *instance_id, return -1; /* LCOV_EXCL_LINE */ } - bundle_add_str(b, WIDGET_K_ID, class_id); - bundle_add_str(b, WIDGET_K_INSTANCE, instance_id); - bundle_add_byte(b, WIDGET_K_STATUS, &status, sizeof(int)); + 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 (extra) { bundle_encode(extra, &raw, &len); @@ -359,7 +340,7 @@ static int __instance_update_all(widget_class_h handle, int force, const char *c widget_context_s *wc; int ret = 0; bundle *b = NULL; - GList *context = contexts; + GList *context = _widget_app_get_contexts(); if (content) b = bundle_decode((const bundle_raw *)content, strlen(content)); @@ -431,7 +412,7 @@ static int __instance_create(widget_class_h handle, const char *id, const char * content_info = bundle_decode((const bundle_raw *)content, strlen(content)); } - contexts = g_list_append(contexts, wc); + _widget_app_add_context(wc); ret = handle->ops.create(wc, content_info, w, h, handle->user_data); if (ret < 0) { @@ -460,6 +441,7 @@ static int __instance_destroy(widget_class_h handle, const char *id, int event = WIDGET_INSTANCE_EVENT_TERMINATE; bundle *content_info; + if (!wc) { _E("could not find widget obj: %s", id); /* LCOV_EXCL_LINE */ return WIDGET_ERROR_INVALID_PARAMETER; /* LCOV_EXCL_LINE */ @@ -488,7 +470,7 @@ static int __instance_destroy(widget_class_h handle, const char *id, ret = __send_update_status(handle->classid, id, event, NULL); - contexts = g_list_remove(contexts, wc); + _widget_app_remove_context(wc); if (wc->id) free(wc->id); @@ -498,7 +480,7 @@ static int __instance_destroy(widget_class_h handle, const char *id, free(wc); - if (contexts == NULL && !exit_called) /* all instance destroyed */ + if (_widget_app_get_contexts() == NULL && !exit_called) /* all instance destroyed */ widget_app_exit(); return ret; @@ -559,7 +541,7 @@ static void __control(bundle *b) if (class_id == NULL) class_id = appid; - bundle_get_str(b, WIDGET_K_INSTANCE, &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); @@ -617,6 +599,7 @@ error: static void __pause_all(int send_update) { + GList *contexts = _widget_app_get_contexts(); GList *iter = g_list_first(contexts); while (iter != NULL) { @@ -638,6 +621,7 @@ static void __pause_all(int send_update) /* 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) { @@ -658,6 +642,7 @@ static void __resume_all(int send_update) 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); @@ -849,6 +834,7 @@ static int __before_loop(int argc, char **argv) char *wayland_display = NULL; char *xdg_runtime_dir = NULL; char *name; + char *viewer_endpoint; #if !(GLIB_CHECK_VERSION(2, 36, 0)) g_type_init(); @@ -861,7 +847,7 @@ static int __before_loop(int argc, char **argv) bundle_get_str(kb, WIDGET_K_ENDPOINT, &viewer_endpoint); if (viewer_endpoint) { _E("viewer endpoint :%s", viewer_endpoint); - viewer_endpoint = strdup(viewer_endpoint); + _widget_app_set_viewer_endpoint(viewer_endpoint); } else { _E("endpoint is missing"); } @@ -952,9 +938,7 @@ static void __after_loop() if (app_ops->terminate) app_ops->terminate(app_user_data); - if (viewer_endpoint) - free(viewer_endpoint); - + _widget_app_free_viewer_endpoint(); _widget_core_unset_appcore_event_cb(); __free_handler_list(); elm_shutdown(); @@ -1202,6 +1186,7 @@ EXPORT_API int widget_app_terminate_context(widget_context_h context) EXPORT_API int widget_app_foreach_context(widget_context_cb cb, void *data) { + GList *contexts = _widget_app_get_contexts(); GList *list; widget_context_s *wc; @@ -1517,4 +1502,3 @@ EXPORT_API int widget_app_context_set_title(widget_context_h context, return WIDGET_ERROR_NONE; } - diff --git a/src/widget_app_internal.c b/src/widget_app_internal.c new file mode 100644 index 0000000..45b56d8 --- /dev/null +++ b/src/widget_app_internal.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 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 "widget_app.h" +#include "widget-log.h" +#include "widget-private.h" +#include "widget_app_internal.h" +#include "widget-private.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "CAPI_WIDGET_APPLICATION" + +static char *viewer_endpoint = NULL; +static GList *contexts = NULL; + +EXPORT_API int widget_app_restart() +{ + 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); + + kb = bundle_create(); + bundle_add_str(kb, AUL_K_WIDGET_ID, classid); + bundle_add_byte(kb, AUL_K_WIDGET_STATUS, &status, sizeof(int)); + ret = aul_app_com_send(viewer_endpoint, kb); + bundle_free(kb); + if (ret != AUL_R_OK) { + _E("failed to kill app"); + return WIDGET_ERROR_IO_ERROR; + } + 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; +} -- 2.34.1