From c24440649a91cf89a549791a31a67e03f4c4c694 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 20 Jul 2017 14:58:32 +0900 Subject: [PATCH] Add widget-mgr tool for debugging widget apps Change-Id: Ie7b3391e5b2b7f877745c1c16b09ba520a8809bf Signed-off-by: Hwankyu Jhun --- CMakeLists.txt | 1 + packaging/libwidget_viewer.spec | 2 +- packaging/libwidget_viewer_evas.manifest | 3 + tool/CMakeLists.txt | 30 ++++ tool/widget-mgr.c | 263 +++++++++++++++++++++++++++++++ 5 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 tool/CMakeLists.txt create mode 100644 tool/widget-mgr.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 65c8072..7b2ad02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,5 +5,6 @@ ADD_SUBDIRECTORY(widget_viewer_dali) ADD_SUBDIRECTORY(widget_viewer_evas) ADD_SUBDIRECTORY(widget_viewer_sdk) ADD_SUBDIRECTORY(watch-control) +ADD_SUBDIRECTORY(tool) ADD_DEPENDENCIES(widget_viewer_sdk widget_viewer_evas) diff --git a/packaging/libwidget_viewer.spec b/packaging/libwidget_viewer.spec index 2c3c053..0f2f230 100644 --- a/packaging/libwidget_viewer.spec +++ b/packaging/libwidget_viewer.spec @@ -161,7 +161,7 @@ Header & package configuration of watch-control /usr/share/widget_viewer_evas/res/edje/widget_viewer_evas.edj /usr/share/widget_viewer_evas/res/image/*.png /usr/share/widget_viewer_evas/res/locale/*/LC_MESSAGES/* - +%{_bindir}/widget-mgr %files -n %{name}_evas-devel %{_includedir}/widget_viewer_evas/widget_viewer_evas.h diff --git a/packaging/libwidget_viewer_evas.manifest b/packaging/libwidget_viewer_evas.manifest index a76fdba..c9146e4 100644 --- a/packaging/libwidget_viewer_evas.manifest +++ b/packaging/libwidget_viewer_evas.manifest @@ -2,4 +2,7 @@ + + + diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt new file mode 100644 index 0000000..d3023bb --- /dev/null +++ b/tool/CMakeLists.txt @@ -0,0 +1,30 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + +SET(WIDGET_MGR "widget-mgr") +SET(WIDGET_MGR_DIR ${CMAKE_SOURCE_DIR}/tool) +PROJECT(${WIDGET_MGR} C) + +INCLUDE(FindPkgConfig) + +SET(WIDGET_MGR_PKG_CHECK_MODULES glib-2.0 aul) +PKG_CHECK_MODULES(WIDGET_MGR_PKGS REQUIRED ${WIDGET_MGR_PKG_CHECK_MODULES}) + +FOREACH(flag ${WIDGET_MGR_PKGS_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" ) +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") +SET(CMAKE_SKIP_BUILD_RPATH true) + +SET(CMAKE_EXE_LINKER_FLAGS "-pie -Wl,--as-needed") + +ADD_EXECUTABLE(${WIDGET_MGR} widget-mgr.c) +TARGET_LINK_LIBRARIES(${WIDGET_MGR} ${WIDGET_MGR_PKGS_LDFLAGS}) +INSTALL(TARGETS ${WIDGET_MGR} DESTINATION bin) diff --git a/tool/widget-mgr.c b/tool/widget-mgr.c new file mode 100644 index 0000000..9a17e95 --- /dev/null +++ b/tool/widget-mgr.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2017 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 + +#define MAX_BUFSZ 100 +#define REGULAR_UID_MIN 5000 + +enum command_e { + CMD_LIST, + CMD_MAX, +}; + +enum option_e { + OPT_USER, + OPT_MAX, +}; + +struct command_arg { + uid_t uid; +}; + +struct command { + const char *name; + int (*init)(struct command_arg *); + int (*run)(struct command_arg *); + void (*finish)(struct command_arg *); +}; + +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 }, + { 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" }, + { NULL } +}; + +static GOptionGroup *__get_opt_group(void) +{ + GOptionGroup *group; + + group = g_option_group_new("option", "Additional Options:", + "Additional options", NULL, NULL); + if (!group) + return NULL; + + g_option_group_add_entries(group, opt_entries); + + return group; +} + +static struct command_arg __get_command_arg(int argc, char **argv) +{ + struct command_arg cmd_arg = { 0, }; + + if (opt[OPT_USER]) + cmd_arg.uid = GPOINTER_TO_INT(opt[OPT_USER]); + + return cmd_arg; +} + +static void __print_delim(char c) +{ + char buf[MAX_BUFSZ]; + + memset(buf, c, sizeof(buf)); + printf("%s\n", buf); +} + +static void __foreach_widget_info(aul_widget_info_h info, + void *user_data) +{ + char *widget_id = NULL; + char *instance_id = NULL; + char *app_id = NULL; + char *package_id = NULL; + char *app_path = NULL; + pid_t pid = -1; + unsigned int surf = 0; + int *count = (int *)user_data; + + if (info == NULL) + return; + + aul_widget_info_get_widget_id(info, &widget_id); + aul_widget_info_get_instance_id(info, &instance_id); + aul_widget_info_get_app_id(info, &app_id); + aul_widget_info_get_package_id(info, &package_id); + aul_widget_info_get_app_path(info, &app_path); + aul_widget_info_get_pid(info, &pid); + aul_widget_info_get_surface_id(info, &surf); + + if (*count != 0) + __print_delim('-'); + + printf(" - [Widget ID] \t\t%s\n", widget_id); + printf(" - [Instance ID] \t%s\n", instance_id); + printf(" - [App ID] \t\t%s\n", app_id); + printf(" - [Package ID] \t%s\n", package_id); + printf(" - [App Path] \t\t%s\n", app_path); + printf(" - [PID] \t\t%d\n", pid); + printf(" - [Surface ID] \t%#x\n", surf); + + free(app_path); + free(package_id); + free(app_id); + free(instance_id); + free(widget_id); + (*count)++; +} + +static int __cmd_list_run(struct command_arg *arg) +{ + int r; + int count = 0; + + __print_delim('='); + printf(" Running Widget List\n"); + __print_delim('='); + + r = aul_widget_info_foreach_for_uid(__foreach_widget_info, + &count, arg->uid); + __print_delim('='); + + return r; +} + +static struct command cmd_table[] = { + [CMD_LIST] = { + .name = "list", + .init = NULL, + .run = __cmd_list_run, + .finish = NULL + }, +}; + +static struct command *__find_command(void) +{ + int i; + + for (i = 0; i < G_N_ELEMENTS(cmd_table); ++i) { + if (cmd_opt[i]) + return &cmd_table[i]; + } + + return NULL; +} + +static int __run_command(struct command_arg *cmd_arg) +{ + struct command *cmd; + + cmd = __find_command(); + if (cmd == NULL) { + printf("%s", help); + return -1; + } + + if (cmd->init) { + if (cmd->init(cmd_arg) < 0) + return -1; + } + + if (cmd->run) { + if (cmd->run(cmd_arg) < 0) + return -1; + } + + if (cmd->finish) + cmd->finish(cmd_arg); + + return 0; +} + +static int __parse_args(int argc, char **argv) +{ + GOptionContext *context; + GOptionGroup *opt_group; + GError *error = NULL; + + context = g_option_context_new(NULL); + if (!context) { + printf("Failed to create GOptionContext\n"); + return -1; + } + + g_option_context_add_main_entries(context, cmd_entries, NULL); + + opt_group = __get_opt_group(); + if (!opt_group) { + printf("Failed to get opt group\n"); + g_option_context_free(context); + return -1; + } + g_option_context_add_group(context, opt_group); + + if (!g_option_context_parse(context, &argc, &argv, &error)) { + printf("%s: %s\n", argv[0], error->message); + g_option_group_unref(opt_group); + g_option_context_free(context); + g_clear_error(&error); + return -1; + } + + help = g_option_context_get_help(context, TRUE, NULL); + g_option_group_unref(opt_group); + g_option_context_free(context); + + return 0; +} + +int main(int argc, char **argv) +{ + struct command_arg cmd_arg; + int r; + + if (getuid() >= REGULAR_UID_MIN) { + printf("Regular users cannot run this tool.\n"); + return -1; + } + + r = __parse_args(argc, argv); + if (r < 0) + return -1; + + cmd_arg = __get_command_arg(argc, argv); + r = __run_command(&cmd_arg); + if (r < 0) { + free(help); + return -1; + } + + free(help); + + return 0; +} -- 2.7.4