diff options
author | Hwankyu Jhun <h.jhun@samsung.com> | 2017-09-25 11:24:40 +0900 |
---|---|---|
committer | Hwankyu Jhun <h.jhun@samsung.com> | 2017-09-25 11:24:40 +0900 |
commit | b498c4f849e1ba8c0a1886cb320d59840e44f63a (patch) | |
tree | 655d4c5240b2e1e60d05ddc27dcd6debc8b93cd2 | |
parent | c226780592898b9967ff95bb0a77a7fce1e00913 (diff) | |
parent | 118916174281f6ad5521f89c92b5334e38156643 (diff) | |
download | appcore-widget-b498c4f849e1ba8c0a1886cb320d59840e44f63a.tar.gz appcore-widget-b498c4f849e1ba8c0a1886cb320d59840e44f63a.tar.bz2 appcore-widget-b498c4f849e1ba8c0a1886cb320d59840e44f63a.zip |
Merge branch 'devel/tizen' into tizen
-rwxr-xr-x | include/widget_app.h | 4 | ||||
-rw-r--r-- | src/base/widget_base.c | 228 |
2 files changed, 198 insertions, 34 deletions
diff --git a/include/widget_app.h b/include/widget_app.h index cf1b275..9e309d2 100755 --- a/include/widget_app.h +++ b/include/widget_app.h @@ -353,7 +353,7 @@ const char *widget_app_get_id(widget_context_h context); * @return The new widget class object, * NULL on error * @exception #WIDGET_ERROR_NONE Successfully added - * @exception #WIDGET_ERROR_INVALID_PARAMETER Not supported + * @exception #WIDGET_ERROR_INVALID_PARAMETER Invalid parameter * @exception #WIDGET_ERROR_NOT_SUPPORTED Not supported * @exception #WIDGET_ERROR_OUT_OF_MEMORY Out of memory * @see get_last_result() @@ -432,7 +432,7 @@ int widget_app_context_set_title(widget_context_h context, const char *title); * @return The new widget class object, * NULL on error * @exception #WIDGET_ERROR_NONE Successfully added - * @exception #WIDGET_ERROR_INVALID_PARAMETER Not supported + * @exception #WIDGET_ERROR_INVALID_PARAMETER Invalid parameter * @exception #WIDGET_ERROR_NOT_SUPPORTED Not supported * @exception #WIDGET_ERROR_OUT_OF_MEMORY Out of memory * @see get_last_result() diff --git a/src/base/widget_base.c b/src/base/widget_base.c index 6f19ce9..e43635d 100644 --- a/src/base/widget_base.c +++ b/src/base/widget_base.c @@ -84,8 +84,13 @@ 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; + char *pending_content; void *user_data; } widget_base_instance_data; @@ -94,6 +99,33 @@ static char *__appid; static char *__package_id; static bool __fg_signal; static char *__viewer_endpoint; +static bool __is_permanent; +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) { @@ -150,7 +182,9 @@ 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->pending_content); free(data->content); + free(data->id); free(data); __check_empty_instance(); } @@ -205,12 +239,13 @@ static int __send_lifecycle_event(const char *class_id, const char *instance_id, } static int __send_update_status(const char *class_id, const char *instance_id, - int status, bundle *extra) + int status, int err, bundle *extra) { bundle *b; int lifecycle = -1; bundle_raw *raw = NULL; int len; + char err_str[256]; b = bundle_create(); if (!b) { @@ -218,6 +253,11 @@ static int __send_update_status(const char *class_id, const char *instance_id, return -1; /* LCOV_EXCL_LINE */ } + if (err < 0) { + snprintf(err_str, sizeof(err_str), "%d", err); + bundle_add_str(b, AUL_K_WIDGET_ERROR_CODE, err_str); + } + 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)); @@ -268,6 +308,7 @@ static void __control_create(const char *class_id, const char *id, bundle *b) return; } + data->id = strdup(id); data->args = b; /* call stub create */ @@ -350,23 +391,21 @@ static void __control_resize(const char *class_id, const char *id, bundle *b) LOGD("%s is resized to %dx%d", id, w, h); __send_update_status(class_id, id, - WIDGET_INSTANCE_EVENT_SIZE_CHANGED, NULL); + WIDGET_INSTANCE_EVENT_SIZE_CHANGED, 0, 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)); @@ -406,20 +436,70 @@ static void __update_cb(const char *class_id, const char *id, cls->ops.update(instance_h, content, force, class_data); __send_update_status(class_id, id, - WIDGET_INSTANCE_EVENT_UPDATE, NULL); + WIDGET_INSTANCE_EVENT_UPDATE, 0, NULL); LOGD("updated:%s", id); if (content) bundle_free(content); } +static void __update_pending_content( + appcore_multiwindow_base_instance_h instance_h, + const char *content_raw) +{ + widget_base_instance_data *data; + + data = (widget_base_instance_data *) + appcore_multiwindow_base_instance_get_extra(instance_h); + + if (data->pending_content) { + free(data->pending_content); + data->pending_content = NULL; + } + + if (content_raw) { + data->pending_content = strdup(content_raw); + if (data->pending_content == NULL) + LOGW("Out of memory"); + } + + data->pending_update = true; +} + +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); + if (!appcore_multiwindow_base_instance_is_resumed(instance_h) && !force) + __update_pending_content(instance_h, content_raw); + else + __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 +509,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) @@ -450,11 +530,55 @@ 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->pending_content); free(data->content); + free(data->id); free(data); __check_empty_instance(); } +static void __control_change_period(const char *class_id, const char *id, + bundle *b) +{ + appcore_multiwindow_base_instance_h instance_h; + widget_base_instance_data *data; + double *period = NULL; + size_t size; + int ret; + + instance_h = appcore_multiwindow_base_instance_find(id); + if (!instance_h) { + LOGE("context not found: %s", id); + return; + } + + data = (widget_base_instance_data *) + appcore_multiwindow_base_instance_get_extra(instance_h); + + if (!data) { + LOGE("could not find instance data: %s", id); + return; + } + + if (data->periodic_timer) { + LOGD("Remove timer!"); + g_source_remove(data->periodic_timer); + data->periodic_timer = 0; + } + + ret = bundle_get_byte(b, WIDGET_K_PERIOD, (void **)&period, &size); + if (ret == BUNDLE_ERROR_NONE) + data->period = *period; + + if (data->period > 0) { + LOGD("Restart timer!"); + data->periodic_timer = g_timeout_add_seconds(data->period, + __timeout_cb, data); + } + + return; +} + static int __multiwindow_create(void *data) { char pkgid[256] = {0, }; @@ -546,6 +670,8 @@ static int __multiwindow_control(bundle *b, void *data) __control_pause(class_id, id, b); else if (strcmp(operation, "terminate") == 0) __control_destroy(class_id, id, b); + else if (strcmp(operation, "period") == 0) + __control_change_period(class_id, id, b); return 0; } @@ -644,7 +770,8 @@ static void __multiwindow_exit(void *data) EXPORT_API int widget_base_exit(void) { appcore_multiwindow_base_exit(); - aul_widget_notify_exit(); + if (appcore_multiwindow_base_instance_get_cnt() != 0 && __is_permanent) + aul_notify_exit(); return 0; } @@ -843,7 +970,7 @@ EXPORT_API int widget_base_context_set_content_info( return WIDGET_BASE_ERROR_FAULT; ret = __send_update_status(class_id, id, - WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, content_info); + WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, 0, content_info); if (data->content) free(data->content); @@ -1122,9 +1249,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( @@ -1199,6 +1327,8 @@ static void __multiwindow_instance_create( int h = 0; int ret = -1; widget_base_class *cls; + double *period = NULL; + size_t size; appcore_multiwindow_base_class_on_create(instance_h); instance_data = appcore_multiwindow_base_instance_get_extra(instance_h); @@ -1243,14 +1373,27 @@ static void __multiwindow_instance_create( if (ret < 0) { LOGW("Create callback returns error(%d)", ret); ret = __send_update_status(class_id, id, - WIDGET_INSTANCE_EVENT_CREATE_ABORTED, NULL); + WIDGET_INSTANCE_EVENT_CREATE_ABORTED, ret, NULL); + if (ret < 0) + LOGE("Fail to send abort status (%d) ", ret); __instance_drop(instance_h); } else { LOGD("%s is created", id); ret = __send_update_status(class_id, id, - WIDGET_INSTANCE_EVENT_CREATE, NULL); + WIDGET_INSTANCE_EVENT_CREATE, 0, NULL); + if (ret < 0) + LOGE("Fail to send create status (%d) ", ret); aul_widget_instance_add(class_id, id); + + ret = bundle_get_byte(b, WIDGET_K_PERIOD, (void **)&period, + &size); + if (ret == BUNDLE_ERROR_NONE) { + instance_data->period = *period; + instance_data->periodic_timer = g_timeout_add_seconds( + instance_data->period, + __timeout_cb, instance_data); + } } if (content_info) @@ -1264,6 +1407,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,12 +1418,27 @@ 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; + __call_update_cb(class_id, data->id, 0, data->pending_content); + 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); LOGD("%s is resumed", id); __send_update_status(class_id, id, - WIDGET_INSTANCE_EVENT_RESUME, NULL); + WIDGET_INSTANCE_EVENT_RESUME, 0, NULL); if (!__fg_signal) { LOGD("Send fg signal to resourceD"); @@ -1314,7 +1473,7 @@ static void __multiwindow_instance_pause( LOGD("%s is paused", id); __send_update_status(class_id, id, - WIDGET_INSTANCE_EVENT_PAUSE, NULL); + WIDGET_INSTANCE_EVENT_PAUSE, 0, NULL); if (__fg_signal) { LOGD("Send bg signal to resourceD"); @@ -1369,18 +1528,23 @@ static void __multiwindow_instance_terminate( LOGD("%s is destroyed %d", id, reason); if (reason == WIDGET_BASE_DESTROY_TYPE_PERMANENT) { + __is_permanent = true; event = WIDGET_INSTANCE_EVENT_DESTROY; aul_widget_instance_del(class_id, id); } else { + __is_permanent = false; __send_update_status(class_id, id, - WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, + WIDGET_INSTANCE_EVENT_EXTRA_UPDATED, 0, content_info); } if (content_info) bundle_free(content_info); - __send_update_status(class_id, id, event, NULL); + if (data->periodic_timer) + g_source_remove(data->periodic_timer); + + __send_update_status(class_id, id, event, 0, NULL); appcore_multiwindow_base_class_on_terminate(instance_h); } |