From 8a06ef9a2f901a9592982c71e901413f2b6bff2d Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 8 May 2020 10:17:19 +0900 Subject: [PATCH] Save widget images of the widget viewer Requires: - https://review.tizen.org/gerrit/#/c/platform/core/appfw/aul-1/+/232855/ - https://review.tizen.org/gerrit/#/c/platform/core/appfw/amd/+/232857/ Change-Id: Ibbef122d663bbc70e7e180294a9c583e2de17f37 Signed-off-by: Hwankyu Jhun --- tool/widget-mgr.c | 22 ++- unittest/mock/app_common.h | 4 + unittest/mock/mock.cc | 4 +- widget_viewer_evas/CMakeLists.txt | 4 +- widget_viewer_evas/src/log_private.h | 48 +++++++ widget_viewer_evas/src/widget_viewer_evas.c | 61 +++++++- widget_viewer_evas/src/widget_viewer_image.c | 143 +++++++++++++++++++ widget_viewer_evas/src/widget_viewer_image.h | 28 ++++ 8 files changed, 303 insertions(+), 11 deletions(-) create mode 100644 widget_viewer_evas/src/log_private.h create mode 100644 widget_viewer_evas/src/widget_viewer_image.c create mode 100644 widget_viewer_evas/src/widget_viewer_image.h diff --git a/tool/widget-mgr.c b/tool/widget-mgr.c index 76b3b561..c78e772c 100644 --- a/tool/widget-mgr.c +++ b/tool/widget-mgr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 - 2020 Samsung Electronics Co., Ltd. * * Licensed under the Flora License, Version 1.1 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -425,6 +426,25 @@ static void __foreach_widget_info_list(gpointer data, gpointer user_data) static gboolean __dump_widgets(gpointer data) { + const char *path = data; + bundle *event_data; + int ret; + + event_data = bundle_create(); + if (!event_data) { + fprintf(stderr, "Failed to create bundle\n"); + return G_SOURCE_REMOVE; + } + + if (path) + bundle_add(event_data, "path", path); + + ret = aul_widget_send_event(AUL_WIDGET_EVENT_SAVE_IMAGE, event_data); + if (ret != AUL_R_OK) + fprintf(stderr, "Failed to send widget event. error(%d)", ret); + + bundle_free(event_data); + g_list_foreach(widget_info_list, __foreach_widget_info_list, data); return G_SOURCE_REMOVE; diff --git a/unittest/mock/app_common.h b/unittest/mock/app_common.h index 69f440c7..478dc7a4 100644 --- a/unittest/mock/app_common.h +++ b/unittest/mock/app_common.h @@ -36,6 +36,10 @@ typedef enum { DECLARE_FAKE_VALUE_FUNC(int, app_get_name, char**); +DECLARE_FAKE_VALUE_FUNC(int, app_get_id, char**); + +DECLARE_FAKE_VALUE_FUNC(char*, app_get_data_path); + #ifdef __cplusplus } #endif diff --git a/unittest/mock/mock.cc b/unittest/mock/mock.cc index 10b321ba..978c950b 100644 --- a/unittest/mock/mock.cc +++ b/unittest/mock/mock.cc @@ -17,6 +17,8 @@ DEFINE_FFF_GLOBALS; DEFINE_FAKE_VALUE_FUNC(int, app_get_name, char**); +DEFINE_FAKE_VALUE_FUNC(int, app_get_id, char**); +DEFINE_FAKE_VALUE_FUNC(char*, app_get_data_path); /* system */ DEFINE_FAKE_VALUE_FUNC(int, system_info_get_platform_bool, @@ -100,4 +102,4 @@ DEFINE_FAKE_VALUE_FUNC(char *, vconf_get_str, const char *); DEFINE_FAKE_VALUE_FUNC(int, vconf_notify_key_changed, const char *, vconf_callback_fn, void *); DEFINE_FAKE_VALUE_FUNC(int, vconf_ignore_key_changed, - const char *, vconf_callback_fn); \ No newline at end of file + const char *, vconf_callback_fn); diff --git a/widget_viewer_evas/CMakeLists.txt b/widget_viewer_evas/CMakeLists.txt index 38eafc66..e7cd95fe 100644 --- a/widget_viewer_evas/CMakeLists.txt +++ b/widget_viewer_evas/CMakeLists.txt @@ -25,9 +25,7 @@ pkg_check_modules(viewer_evas REQUIRED screen_connector_watcher_evas ) -SET(BUILD_SOURCE - src/widget_viewer_evas.c -) +AUX_SOURCE_DIRECTORY(src BUILD_SOURCE) FOREACH(flag ${viewer_evas_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/widget_viewer_evas/src/log_private.h b/widget_viewer_evas/src/log_private.h new file mode 100644 index 00000000..95765ec3 --- /dev/null +++ b/widget_viewer_evas/src/log_private.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LOG_PRIVATE_H__ +#define __LOG_PRIVATE_H__ + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "WIDGET_EVAS" + + +#ifdef _E +#undef _E +#endif +#define _E LOGE + +#ifdef _W +#undef _W +#endif +#define _W LOGW + +#ifdef _I +#undef _I +#endif +#define _I LOGI + +#ifdef _D +#undef _D +#endif +#define _D LOGD + +#endif /* __LOG_PRIVATE_H__ */ diff --git a/widget_viewer_evas/src/widget_viewer_evas.c b/widget_viewer_evas/src/widget_viewer_evas.c index 3511695e..870892fc 100644 --- a/widget_viewer_evas/src/widget_viewer_evas.c +++ b/widget_viewer_evas/src/widget_viewer_evas.c @@ -44,19 +44,17 @@ #include #include #include +#include +#include #ifdef API #undef API #endif #define API __attribute__((visibility("default"))) -#if defined(LOG_TAG) -#undef LOG_TAG -#endif -#define LOG_TAG "WIDGET_EVAS" -#include - +#include "log_private.h" #include "widget_viewer_evas.h" +#include "widget_viewer_image.h" #if !defined(WIDGET_COUNT_OF_SIZE_TYPE) #define WIDGET_COUNT_OF_SIZE_TYPE 13 @@ -1038,6 +1036,53 @@ static void __flush_event_queue(struct widget_info *info) info->event_queue = NULL; } +static void __aul_widget_event_cb(const char *event_name, + bundle *event_data, + void *user_data) +{ + struct widget_info *info; + Evas_Object *tbm_obj; + const char *path; + GHashTableIter iter; + gpointer key; + gpointer value; + char buf[512]; + char *id = NULL; + + _W("event_name: %s", event_name); + if (strcmp(event_name, AUL_WIDGET_EVENT_SAVE_IMAGE) != 0) + return; + + path = bundle_get_val(event_data, "path"); + app_get_id(&id); + + g_hash_table_iter_init(&iter, s_info.widget_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + info = (struct widget_info *)value; + if (!info) { + _E("info is nullptr"); + continue; + } + + if (!info->layout) { + _E("widget(%s) layotu is invalid", info->instance_id); + continue; + } + + tbm_obj = elm_object_part_content_get(info->layout, + "tbm,widget"); + if (!tbm_obj) { + _E("widge(%s:%d) object is invalid", + info->instance_id, info->pid); + continue; + } + + snprintf(buf, sizeof(buf), "%s_%s.jpg", id, info->instance_id); + _widget_viewer_image_save(tbm_obj, path, buf, 100, 100); + } + free(id); +} + API int widget_viewer_evas_init(Evas_Object *win) { char app_id[255]; @@ -1081,6 +1126,8 @@ API int widget_viewer_evas_init(Evas_Object *win) s_info.widget_table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, __destroy_widget_info); s_info.instance_cnt_table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); + aul_widget_set_event_cb(__aul_widget_event_cb, NULL); + return WIDGET_ERROR_NONE; } @@ -1097,6 +1144,8 @@ API int widget_viewer_evas_fini(void) return WIDGET_ERROR_FAULT; } + aul_widget_unset_event_cb(); + if (s_info.widget_table) g_hash_table_destroy(s_info.widget_table); diff --git a/widget_viewer_evas/src/widget_viewer_image.c b/widget_viewer_evas/src/widget_viewer_image.c new file mode 100644 index 00000000..334b442b --- /dev/null +++ b/widget_viewer_evas/src/widget_viewer_image.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log_private.h" +#include "widget_viewer_image.h" + +#define PATH_RUN_AUL_DUMP "/run/aul/dump" + +static const char *__get_path(void) +{ + static char path[1024] = { 0, }; + char *data_path; + char *app_id = NULL; + int ret; + + if (path[0] != '\0') + return path; + + ret = access(PATH_RUN_AUL_DUMP, F_OK); + if (ret != 0) { + _W("Failed to access %s. errno(%d)", path, errno); + data_path = app_get_data_path(); + if (!data_path) { + _E("Failed to get data path"); + return NULL; + } + + snprintf(path, sizeof(path), "%s.widget", data_path); + free(data_path); + } else { + ret = app_get_id(&app_id); + if (ret != APP_ERROR_NONE) { + _E("Failed to get app id. error(%d)", ret); + return NULL; + } + + snprintf(path, sizeof(path), "%s/%s", + PATH_RUN_AUL_DUMP, app_id); + free(app_id); + } + + ret = mkdir(path, 0755); + _W("mkdir(%s): %d", path, ret); + return path; +} + +int _widget_viewer_image_save(Evas_Object *image, + const char *path, + const char *filename, + int quality, + int compress) +{ + Ecore_Evas *ee; + Evas_Object *obj; + tbm_surface_h surface; + tbm_surface_info_s info; + Evas_Native_Surface *ns; + void *data; + int w; + int h; + char buf[128]; + char file[PATH_MAX]; + + _W("WIDGET_VIEWER_IMAGE_SAVE"); + if (image == NULL || filename == NULL) { + _E("Invalid parameter"); + return -1; + } + + snprintf(buf, sizeof(buf), "quality=%d compress=%d", quality, compress); + ns = evas_object_image_native_surface_get(image); + if (ns == NULL) { + _W("native_surface is nullptr"); + evas_object_image_save(image, filename, NULL, buf); + return 0; + } + + surface = (tbm_surface_h)ns->data.tbm.buffer; + if (surface == NULL) { + _E("surface is nullptr"); + return -1; + } + + memset(&info, 0, sizeof(tbm_surface_info_s)); + tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info); + data = info.planes[0].ptr; + w = info.planes[0].stride / 4; + h = info.height; + + ee = ecore_evas_buffer_new(1, 1); + if (ee == NULL) { + _E("Out of memory"); + tbm_surface_unmap(surface); + return -1; + } + + obj = evas_object_image_add(ecore_evas_get(ee)); + if (obj == NULL) { + _E("Out of memory"); + ecore_evas_free(ee); + tbm_surface_unmap(surface); + return -1; + } + + evas_object_image_alpha_set(obj, EINA_TRUE); + evas_object_image_size_set(obj, w, h); + evas_object_image_data_set(obj, data); + + if (path == NULL) + path = __get_path(); + + snprintf(file, sizeof(file), "%s/%s", path, filename); + evas_object_image_save(obj, file, NULL, buf); + tbm_surface_unmap(surface); + evas_object_del(obj); + ecore_evas_free(ee); + _W("file(%s)", file); + + return 0; +} diff --git a/widget_viewer_evas/src/widget_viewer_image.h b/widget_viewer_evas/src/widget_viewer_image.h new file mode 100644 index 00000000..561af211 --- /dev/null +++ b/widget_viewer_evas/src/widget_viewer_image.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIDGET_VIEWER_IMAGE_H__ +#define __WIDGET_VIEWER_IMAGE_H__ + +#include + +int _widget_viewer_image_save(Evas_Object *image, + const char *path, + const char *filename, + int quality, + int compress); + +#endif /* __WIDGET_VIEWER_IMAGE_H__ */ -- 2.34.1