Implement periodic update 71/150671/5
authorJunghoon Park <jh9216.park@samsung.com>
Wed, 19 Jul 2017 06:09:56 +0000 (15:09 +0900)
committerHyunho Kang <hhstark.kang@samsung.com>
Thu, 21 Sep 2017 08:33:57 +0000 (17:33 +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>
Signed-off-by: Hyunho Kang <hhstark.kang@samsung.com>
src/base/widget_base.c

index 8e74db9..d479c52 100644 (file)
@@ -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);
 }