From: Junghoon Park Date: Wed, 19 Jul 2017 06:09:56 +0000 (+0900) Subject: Implement periodic update X-Git-Tag: accepted/tizen/4.0/unified/20170925.151051~1^2~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F71%2F150671%2F5;p=platform%2Fcore%2Fappfw%2Fappcore-widget.git Implement periodic update - update-callabck should be invoked periodically when the value of 'update-period' is bigger then 0 - Paused widget's update-callback should be deferred until it is resumed - Require https://review.tizen.org/gerrit/#/c/139466/ Change-Id: Id30e4de0576f3cb8b35743fff0ac37989356df6d Signed-off-by: Junghoon Park Signed-off-by: Hyunho Kang --- diff --git a/src/base/widget_base.c b/src/base/widget_base.c index 8e74db9..d479c52 100644 --- a/src/base/widget_base.c +++ b/src/base/widget_base.c @@ -84,8 +84,12 @@ typedef struct _widget_base_context { typedef struct _widget_base_instance_data { bundle *args; + char *id; char *content; void *tag; + double period; + guint periodic_timer; + bool pending_update; void *user_data; } widget_base_instance_data; @@ -94,6 +98,32 @@ static char *__appid; static char *__package_id; static bool __fg_signal; static char *__viewer_endpoint; +static void __call_update_cb(const char *class_id, const char *id, int force, + const char *content_raw); + +static gboolean __timeout_cb(gpointer user_data) +{ + widget_base_instance_data *data = + (widget_base_instance_data *)user_data; + appcore_multiwindow_base_instance_h cxt; + const char *class_id; + + cxt = appcore_multiwindow_base_instance_find(data->id); + if (appcore_multiwindow_base_instance_is_resumed(cxt)) { + LOGD("Periodic update!"); + class_id = appcore_multiwindow_base_instance_get_class_id(cxt); + __call_update_cb(class_id, data->id, 0, NULL); + } else { + data->pending_update = true; + if (data->periodic_timer) { + LOGD("Remove timer!"); + g_source_remove(data->periodic_timer); + data->periodic_timer = 0; + } + } + + return G_SOURCE_CONTINUE; +} static bool __is_widget_feature_enabled(void) { @@ -151,6 +181,7 @@ static void __instance_drop(appcore_multiwindow_base_instance_h instance_h) data = appcore_multiwindow_base_instance_get_extra(instance_h); appcore_multiwindow_base_instance_drop(instance_h); free(data->content); + free(data->id); free(data); __check_empty_instance(); } @@ -260,6 +291,9 @@ static void __control_create(const char *class_id, const char *id, bundle *b) { widget_base_instance_data *data; char *content = NULL; + double *period = NULL; + size_t size; + int ret; data = (widget_base_instance_data *) calloc(1, sizeof(widget_base_instance_data)); @@ -268,7 +302,14 @@ static void __control_create(const char *class_id, const char *id, bundle *b) return; } + data->id = strdup(id); data->args = b; + ret = bundle_get_byte(b, WIDGET_K_PERIOD, (void **)&period, &size); + if (ret == BUNDLE_ERROR_NONE) { + data->period = *period; + data->periodic_timer = g_timeout_add_seconds(data->period, + __timeout_cb, data); + } /* call stub create */ appcore_multiwindow_base_instance_run(class_id, id, data); @@ -353,20 +394,18 @@ static void __control_resize(const char *class_id, const char *id, bundle *b) WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL); } -static void __update_cb(const char *class_id, const char *id, - appcore_multiwindow_base_instance_h instance_h, void *data) +static void __call_update_cb(const char *class_id, const char *id, int force, + const char *content_raw) { void *class_data; + widget_base_class *cls; const appcore_multiwindow_base_class *raw_cls; + appcore_multiwindow_base_instance_h instance_h; bundle *content = NULL; - char *content_raw = NULL; - char *force_str = NULL; - int force; - bundle *b = data; - widget_base_class *cls; - if (!b) { - LOGE("bundle is NULL"); + instance_h = appcore_multiwindow_base_instance_find(id); + if (!instance_h) { + LOGE("context not found: %s", id); return; } @@ -388,15 +427,6 @@ static void __update_cb(const char *class_id, const char *id, return; } - bundle_get_str(b, WIDGET_K_FORCE, &force_str); - - if (force_str && strcmp(force_str, "true") == 0) - force = 1; - else - force = 0; - - bundle_get_str(b, WIDGET_K_CONTENT_INFO, &content_raw); - if (content_raw) { content = bundle_decode((const bundle_raw *)content_raw, strlen(content_raw)); @@ -413,13 +443,37 @@ static void __update_cb(const char *class_id, const char *id, bundle_free(content); } +static void __update_process(const char *class_id, const char *id, + appcore_multiwindow_base_instance_h instance_h, void *data) +{ + char *content_raw = NULL; + char *force_str = NULL; + int force; + bundle *b = data; + + if (!b) { + LOGE("bundle is NULL"); + return; + } + + bundle_get_str(b, WIDGET_K_FORCE, &force_str); + + if (force_str && strcmp(force_str, "true") == 0) + force = 1; + else + force = 0; + + bundle_get_str(b, WIDGET_K_CONTENT_INFO, &content_raw); + __call_update_cb(class_id, id, force, content_raw); +} + static void __control_update(const char *class_id, const char *id, bundle *b) { appcore_multiwindow_base_instance_h instance_h; if (!id) { appcore_multiwindow_base_instance_foreach(class_id, - __update_cb, b); + __update_process, b); return; } @@ -429,7 +483,7 @@ static void __control_update(const char *class_id, const char *id, bundle *b) return; } - __update_cb(class_id, id, instance_h, b); + __update_process(class_id, id, instance_h, b); } static void __control_destroy(const char *class_id, const char *id, bundle *b) @@ -451,6 +505,7 @@ static void __control_destroy(const char *class_id, const char *id, bundle *b) /* call stub terminate */ appcore_multiwindow_base_instance_exit(instance_h); free(data->content); + free(data->id); free(data); __check_empty_instance(); } @@ -1122,9 +1177,10 @@ static void __free_class(gpointer data) EXPORT_API void widget_base_fini(void) { - appcore_multiwindow_base_fini(); g_list_free_full(__context.classes, __free_class); __context.classes = NULL; + + appcore_multiwindow_base_fini(); } EXPORT_API int widget_base_context_window_bind( @@ -1264,6 +1320,7 @@ static void __multiwindow_instance_resume( const char *id; const char *class_id; widget_base_class *cls; + widget_base_instance_data *data; appcore_multiwindow_base_class_on_resume(instance_h); id = appcore_multiwindow_base_instance_get_id(instance_h); @@ -1274,6 +1331,21 @@ static void __multiwindow_instance_resume( return; } + data = (widget_base_instance_data *) + appcore_multiwindow_base_instance_get_extra(instance_h); + + if (data->pending_update) { + LOGD("pending update!"); + data->pending_update = false; + __control_update(class_id, data->id, data->args); + if (data->period > 0) { + LOGD("Restart timer!"); + data->periodic_timer = g_timeout_add_seconds( + data->period, + __timeout_cb, data); + } + } + if (cls->ops.resume) cls->ops.resume(instance_h, class_data); @@ -1380,6 +1452,9 @@ static void __multiwindow_instance_terminate( if (content_info) bundle_free(content_info); + if (data->periodic_timer) + g_source_remove(data->periodic_timer); + __send_update_status(class_id, id, event, NULL); appcore_multiwindow_base_class_on_terminate(instance_h); }