Add dump feature on widget-mgr tool 47/141447/1 accepted/tizen/3.0/common/20170801.163006 accepted/tizen/3.0/ivi/20170801.062108 accepted/tizen/3.0/mobile/20170801.062054 accepted/tizen/3.0/tv/20170801.062059 submit/tizen_3.0/20170731.114949
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 31 Jul 2017 11:35:11 +0000 (20:35 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 31 Jul 2017 11:36:06 +0000 (20:36 +0900)
Change-Id: I31a0d878a012ef6a751479069aa661e8a28226bf
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
tool/CMakeLists.txt
tool/widget-mgr.c

index d3023bb..890cf4b 100644 (file)
@@ -7,7 +7,15 @@ PROJECT(${WIDGET_MGR} C)
 
 INCLUDE(FindPkgConfig)
 
-SET(WIDGET_MGR_PKG_CHECK_MODULES glib-2.0 aul)
+SET(WIDGET_MGR_PKG_CHECK_MODULES
+       glib-2.0
+       aul
+       elementary
+       screen_connector_watcher_evas
+       wayland-tbm-client
+       ecore-wayland
+       tizen-remote-surface-client)
+
 PKG_CHECK_MODULES(WIDGET_MGR_PKGS REQUIRED ${WIDGET_MGR_PKG_CHECK_MODULES})
 
 FOREACH(flag ${WIDGET_MGR_PKGS_CFLAGS})
index e92230c..896d93c 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <glib.h>
 #include <aul.h>
 #include <aul_widget.h>
+#include <wayland-extension/tizen-remote-surface-client-protocol.h>
+#include <tbm_surface.h>
+#include <screen_connector_toolkit_evas.h>
+#include <Elementary.h>
 
 #define MAX_BUFSZ 100
 #define REGULAR_UID_MIN 5000
 
 enum command_e {
        CMD_LIST,
+       CMD_DUMP,
        CMD_MAX,
 };
 
 enum option_e {
        OPT_USER,
+       OPT_PATH,
        OPT_MAX,
 };
 
 struct command_arg {
+       int argc;
+       char **argv;
        uid_t uid;
+       char *path;
 };
 
 struct command {
@@ -48,19 +58,32 @@ struct command {
        void (*finish)(struct command_arg *);
 };
 
+struct widget_info {
+       char *widget_id;
+       char *instance_id;
+       pid_t pid;
+       unsigned int surf;
+};
+
 static gchar *help;
 static gpointer cmd_opt[CMD_MAX];
 static GOptionEntry cmd_entries[] = {
        { "list", 'l', 0, G_OPTION_ARG_NONE, &cmd_opt[CMD_LIST],
                "Show running widget list", NULL },
+       { "dump", 'd', 0, G_OPTION_ARG_NONE, &cmd_opt[CMD_DUMP],
+               "Dump running widget windows", NULL },
        { NULL }
 };
 static gpointer opt[OPT_MAX];
 static GOptionEntry opt_entries[] = {
        { "user", 'u', 0, G_OPTION_ARG_INT, &opt[OPT_USER],
                "Specify the user ID", "USER ID" },
+       { "path", 'p', 0, G_OPTION_ARG_STRING, &opt[OPT_PATH],
+               "Specify the path", "PATH" },
        { NULL }
 };
+static GList *widget_info_list;
+static Evas_Object *win;
 
 static GOptionGroup *__get_opt_group(void)
 {
@@ -80,9 +103,14 @@ static struct command_arg __get_command_arg(int argc, char **argv)
 {
        struct command_arg cmd_arg = { 0, };
 
+       cmd_arg.argc = argc;
+       cmd_arg.argv = argv;
+
        if (opt[OPT_USER])
                cmd_arg.uid = GPOINTER_TO_INT(opt[OPT_USER]);
 
+       cmd_arg.path = opt[OPT_PATH];
+
        return cmd_arg;
 }
 
@@ -152,6 +180,267 @@ static int __cmd_list_run(struct command_arg *arg)
        return r;
 }
 
+static int __save_image(Evas_Object *image, 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];
+
+       if (image == NULL || filename == NULL)
+               return -1;
+
+       snprintf(buf, sizeof(buf), "quality=%d compress=%d", quality, compress);
+       ns = evas_object_image_native_surface_get(image);
+       if (ns == NULL) {
+               evas_object_image_save(image, filename, NULL, buf);
+               return 0;
+       }
+
+       surface = (tbm_surface_h)ns->data.tbm.buffer;
+       if (surface == NULL)
+               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) {
+               tbm_surface_unmap(surface);
+               return -1;
+       }
+
+       obj = evas_object_image_add(ecore_evas_get(ee));
+       if (obj == NULL) {
+               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);
+
+       evas_object_image_save(obj, filename, NULL, buf);
+       tbm_surface_unmap(surface);
+       evas_object_del(obj);
+       ecore_evas_free(ee);
+
+       return 0;
+}
+
+static void __destroy_widget_info(struct widget_info *info)
+{
+       if (info == NULL)
+               return;
+
+       if (info->instance_id)
+               free(info->instance_id);
+       if (info->widget_id)
+               free(info->widget_id);
+       free(info);
+}
+
+static gint __compare_surf(gconstpointer a, gconstpointer b)
+{
+       struct widget_info *info = (struct widget_info *)a;
+       unsigned int surf = GPOINTER_TO_UINT(b);
+
+       if (info->surf == surf)
+               return 0;
+
+       return -1;
+}
+
+static void __screen_connector_toolkit_evas_added_cb(const char *appid,
+               const char *instance_id, int pid,
+               Evas_Object *image, void *data)
+{
+       const char *path = (const char *)data;
+       char cwd[PATH_MAX];
+       char buf[PATH_MAX];
+       unsigned int surf;
+       struct widget_info *info = NULL;
+       GList *found;
+
+       if (image == NULL)
+               return;
+
+       if (path == NULL)
+               path = getcwd(cwd, sizeof(cwd));
+       if (access(path, F_OK) != 0)
+               mkdir(path, 0755);
+
+       screen_connector_toolkit_evas_get_rid(image, (int *)&surf);
+       found = g_list_find_custom(widget_info_list, GUINT_TO_POINTER(surf),
+                       __compare_surf);
+       if (found)
+               info = (struct widget_info *)found->data;
+
+       if (info == NULL) {
+               printf("Unknown surface(%u)", surf);
+               return;
+       }
+
+       snprintf(buf, sizeof(buf), "%s/%d_%s.jpg",
+                       path, info->pid, info->instance_id);
+       __save_image(image, buf, 100, 100);
+
+       widget_info_list = g_list_remove(widget_info_list, info);
+       __destroy_widget_info(info);
+
+       if (widget_info_list == NULL)
+               elm_exit();
+}
+
+static void __screen_connector_toolkit_evas_removed_cb(const char *appid,
+               const char *instance_id, int pid,
+               Evas_Object *image, void *data)
+{
+       /* Nothing */
+}
+
+static void __screen_connector_toolkit_evas_updated_cb(const char *appid,
+               const char *instance_id, int pid,
+               Evas_Object *image, void *data)
+{
+       /* Nothing */
+}
+
+static void __get_widget_list(aul_widget_info_h info,
+               void *user_data)
+{
+       struct widget_info *w_info;
+       char *widget_id = NULL;
+       char *instance_id = NULL;
+       pid_t pid = -1;
+       unsigned int surf = 0;
+       int r;
+
+       if (info == NULL)
+               return;
+
+       r = aul_widget_info_get_widget_id(info, &widget_id);
+       if (r != AUL_R_OK)
+               return;
+
+       r = aul_widget_info_get_instance_id(info, &instance_id);
+       if (r != AUL_R_OK)
+               goto err;
+
+       r = aul_widget_info_get_pid(info, &pid);
+       if (r != AUL_R_OK)
+               goto err;
+
+       r = aul_widget_info_get_surface_id(info, &surf);
+       if (r != AUL_R_OK)
+               goto err;
+
+       w_info = calloc(1, sizeof(struct widget_info));
+       if (!w_info) {
+               printf("Failed to create widget info\n");
+               goto err;
+       }
+
+       w_info->widget_id = widget_id;
+       w_info->instance_id = instance_id;
+       w_info->pid = pid;
+       w_info->surf = surf;
+
+       widget_info_list = g_list_append(widget_info_list, w_info);
+
+       return;
+err:
+       if (instance_id);
+               free(instance_id);
+       if (widget_id)
+               free(widget_id);
+}
+
+static int __cmd_dump_init(struct command_arg *arg)
+{
+       int r;
+
+       r = aul_widget_info_foreach_for_uid(__get_widget_list,
+                       NULL, arg->uid);
+       if (r < 0)
+               return -1;
+
+       if (widget_info_list == NULL) {
+               printf("Widget info is empty\n");
+               return -1;
+       }
+
+       elm_init(arg->argc, arg->argv);
+
+       win = elm_win_util_standard_add("widget-mgr", "widget-mgr");
+       if (!win) {
+               printf("Failed to add window\n");
+               elm_shutdown();
+               return -1;
+       }
+
+       elm_win_alpha_set(win, EINA_FALSE);
+       evas_object_show(win);
+
+       screen_connector_toolkit_evas_init(win,
+                       SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET);
+
+       return 0;
+}
+
+static void __foreach_widget_info_list(gpointer data, gpointer user_data)
+{
+       struct widget_info *info = (struct widget_info *)data;
+       screen_connector_toolkit_evas_ops ops;
+       screen_connector_toolkit_evas_h handle;
+
+       if (info == NULL)
+               return;
+
+       ops.added_cb = __screen_connector_toolkit_evas_added_cb;
+       ops.removed_cb = __screen_connector_toolkit_evas_removed_cb;
+       ops.updated_cb = __screen_connector_toolkit_evas_updated_cb;
+
+       handle = screen_connector_toolkit_evas_add_by_rid(&ops, info->surf,
+                       SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET, user_data);
+       if (handle == NULL) {
+               printf("Failed to add toolkit by rid(%u)", info->surf);
+               return;
+       }
+}
+
+static gboolean __dump_widgets(gpointer data)
+{
+       g_list_foreach(widget_info_list, __foreach_widget_info_list, data);
+
+       return G_SOURCE_REMOVE;
+}
+
+static int __cmd_dump_run(struct command_arg *arg)
+{
+       g_idle_add(__dump_widgets, arg->path);
+       elm_run();
+
+       return 0;
+}
+
+static void __cmd_dump_finish(struct command_arg *arg)
+{
+       screen_connector_toolkit_evas_fini(SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET);
+       evas_object_del(win);
+       elm_shutdown();
+}
+
 static struct command cmd_table[] = {
        [CMD_LIST] = {
                .name = "list",
@@ -159,6 +448,12 @@ static struct command cmd_table[] = {
                .run = __cmd_list_run,
                .finish = NULL
        },
+       [CMD_DUMP] = {
+               .name = "dump",
+               .init = __cmd_dump_init,
+               .run = __cmd_dump_run,
+               .finish = __cmd_dump_finish
+       },
 };
 
 static struct command *__find_command(void)