summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHwankyu Jhun <h.jhun@samsung.com>2017-09-25 11:24:40 +0900
committerHwankyu Jhun <h.jhun@samsung.com>2017-09-25 11:24:40 +0900
commitb498c4f849e1ba8c0a1886cb320d59840e44f63a (patch)
tree655d4c5240b2e1e60d05ddc27dcd6debc8b93cd2
parentc226780592898b9967ff95bb0a77a7fce1e00913 (diff)
parent118916174281f6ad5521f89c92b5334e38156643 (diff)
downloadappcore-widget-b498c4f849e1ba8c0a1886cb320d59840e44f63a.tar.gz
appcore-widget-b498c4f849e1ba8c0a1886cb320d59840e44f63a.tar.bz2
appcore-widget-b498c4f849e1ba8c0a1886cb320d59840e44f63a.zip
Merge branch 'devel/tizen' into tizen
-rwxr-xr-xinclude/widget_app.h4
-rw-r--r--src/base/widget_base.c228
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);
}