Send error code to viewer
[platform/core/appfw/appcore-widget.git] / src / base / widget_base.c
index c10cd8d..e43635d 100644 (file)
@@ -90,6 +90,7 @@ typedef struct _widget_base_instance_data {
        double period;
        guint periodic_timer;
        bool pending_update;
+       char *pending_content;
        void *user_data;
 } widget_base_instance_data;
 
@@ -98,6 +99,7 @@ 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);
 
@@ -180,6 +182,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->pending_content);
        free(data->content);
        free(data->id);
        free(data);
@@ -236,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) {
@@ -249,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));
@@ -291,9 +300,6 @@ 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));
@@ -304,12 +310,6 @@ static void __control_create(const char *class_id, const char *id, bundle *b)
 
        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);
@@ -391,7 +391,7 @@ 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 __call_update_cb(const char *class_id, const char *id, int force,
@@ -436,13 +436,36 @@ static void __call_update_cb(const char *class_id, const char *id, int force,
                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)
 {
@@ -464,7 +487,10 @@ static void __update_process(const char *class_id, const char *id,
                force = 0;
 
        bundle_get_str(b, WIDGET_K_CONTENT_INFO, &content_raw);
-       __call_update_cb(class_id, id, force, 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)
@@ -504,6 +530,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->pending_content);
        free(data->content);
        free(data->id);
        free(data);
@@ -743,7 +770,8 @@ static void __multiwindow_exit(void *data)
 EXPORT_API int widget_base_exit(void)
 {
        appcore_multiwindow_base_exit();
-       aul_notify_exit();
+       if (appcore_multiwindow_base_instance_get_cnt() != 0 && __is_permanent)
+               aul_notify_exit();
 
        return 0;
 }
@@ -942,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);
@@ -1299,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);
@@ -1343,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)
@@ -1381,7 +1424,7 @@ static void __multiwindow_instance_resume(
        if (data->pending_update) {
                LOGD("pending update!");
                data->pending_update = false;
-               __control_update(class_id, data->id, data->args);
+               __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(
@@ -1395,7 +1438,7 @@ static void __multiwindow_instance_resume(
 
        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");
@@ -1430,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");
@@ -1485,11 +1528,13 @@ 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);
        }
 
@@ -1499,7 +1544,7 @@ static void __multiwindow_instance_terminate(
        if (data->periodic_timer)
                g_source_remove(data->periodic_timer);
 
-       __send_update_status(class_id, id, event, NULL);
+       __send_update_status(class_id, id, event, 0, NULL);
        appcore_multiwindow_base_class_on_terminate(instance_h);
 }