Implement periodic update 92/139492/7
authorJunghoon Park <jh9216.park@samsung.com>
Wed, 19 Jul 2017 06:09:56 +0000 (15:09 +0900)
committerJunghoon Park <jh9216.park@samsung.com>
Thu, 20 Jul 2017 01:17:56 +0000 (10:17 +0900)
- 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 <jh9216.park@samsung.com>
src/widget-private.h
src/widget_app.c

index 847c099..1c7f519 100644 (file)
@@ -43,6 +43,9 @@ struct _widget_context {
        Evas_Object *win;
        int win_id;
        char *content;
+       double period;
+       guint periodic_timer;
+       bool pending_update;
        widget_instance_lifecycle_callback_s ops;
 };
 
index db42d0b..5cc0e22 100755 (executable)
@@ -94,6 +94,7 @@ static bool fg_signal;
 
 static void _widget_core_set_appcore_event_cb(void);
 static void _widget_core_unset_appcore_event_cb(void);
+static int __instance_update(widget_class_h handle, const char *id, int force, const char *content);
 
 static void __free_handler_cb(gpointer data)
 {
@@ -282,6 +283,26 @@ static int __send_update_status(const char *class_id, const char *instance_id,
        return 0;
 }
 
+static gboolean __timeout_cb(gpointer user_data)
+{
+       widget_context_s *wc = user_data;
+
+       if (wc->state == WC_RUNNING) {
+               _D("Periodic update!");
+               __instance_update(wc->provider, wc->id, 0, NULL);
+       } else if (wc->state == WC_PAUSED ||
+                       wc->state == WC_READY) {
+               wc->pending_update = true;
+               if (wc->periodic_timer) {
+                       _D("Remove timer!");
+                       g_source_remove(wc->periodic_timer);
+                       wc->periodic_timer = 0;
+               }
+       }
+
+       return G_SOURCE_CONTINUE;
+}
+
 static int __instance_resume(widget_class_h handle, const char *id, int send_update)
 {
        widget_context_s *wc = __find_context_by_id(id);
@@ -302,6 +323,18 @@ static int __instance_resume(widget_class_h handle, const char *id, int send_upd
                return 0; /* LCOV_EXCL_LINE */
        }
 
+       if (wc->pending_update) {
+               _D("pending update!");
+               wc->pending_update = false;
+               __instance_update(wc->provider, wc->id, 0, NULL);
+
+               if (wc->period > 0) {
+                       _D("Restart timer!");
+                       wc->periodic_timer = g_timeout_add_seconds(wc->period,
+                                       __timeout_cb, wc);
+               }
+       }
+
        if (handle->ops.resume)
                handle->ops.resume(wc, handle->user_data);
 
@@ -448,7 +481,8 @@ static int __instance_update(widget_class_h handle, const char *id, int force, c
 }
 /* LCOV_EXCL_STOP */
 
-static int __instance_create(widget_class_h handle, const char *id, const char *content, int w, int h)
+static int __instance_create(widget_class_h handle, const char *id,
+               const char *content, int w, int h, double period)
 {
        widget_context_s *wc = NULL;
        int ret = 0;
@@ -500,6 +534,12 @@ static int __instance_create(widget_class_h handle, const char *id, const char *
        if (content_info)
                bundle_free(content_info);
 
+       if (period > 0) {
+               wc->period = period;
+               wc->periodic_timer = g_timeout_add_seconds(period,
+                               __timeout_cb, wc);
+       }
+
        return ret;
 }
 
@@ -547,6 +587,9 @@ static int __instance_destroy(widget_class_h handle, const char *id,
        if (wc->content)
                free(wc->content);
 
+       if (wc->periodic_timer)
+               g_source_remove(wc->periodic_timer);
+
        free(wc);
 
        if (_widget_app_get_contexts() == NULL && !exit_called) /* all instance destroyed */
@@ -603,7 +646,11 @@ static void __control(bundle *b)
        char *remain = NULL;
        int force;
        char *force_str = NULL;
+       double *period = NULL;
+       double update_period = 0;
        widget_class_h handle = NULL;
+       size_t size;
+       int ret;
 
        bundle_get_str(b, WIDGET_K_CLASS, &class_id);
        /* for previous version compatibility, use appid for default class id */
@@ -640,8 +687,12 @@ static void __control(bundle *b)
        if (h_str)
                h = (int)g_ascii_strtoll(h_str, &remain, 10);
 
+       ret = bundle_get_byte(b, WIDGET_K_PERIOD, (void **)&period, &size);
+       if (ret == BUNDLE_ERROR_NONE)
+               update_period = *period;
+
        if (strcmp(operation, "create") == 0) {
-               __instance_create(handle, id, content, w, h);
+               __instance_create(handle, id, content, w, h, update_period);
        } else if (strcmp(operation, "resize") == 0) {
                __resize_window(id, w, h);
                __instance_resize(handle, id, w, h);