From 73db548b766ea2a76b31f892c7b5d195592893c3 Mon Sep 17 00:00:00 2001 From: Soohye Shin Date: Tue, 23 Jun 2015 21:06:00 +0900 Subject: [PATCH] load user data - add data_user: integrate with lib-gum for loading user list - add data_switch: integrate with tlm for switching other user Change-Id: I5b402ec9a670c275ff128282a946c9043fb2b8af Signed-off-by: Soohye Shin --- include/datamgr.h | 1 + include/defs.h | 5 +- src/data/data_user.c | 329 ++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 329 insertions(+), 6 deletions(-) diff --git a/include/datamgr.h b/include/datamgr.h index 9ca5fd4..982694d 100644 --- a/include/datamgr.h +++ b/include/datamgr.h @@ -23,6 +23,7 @@ enum datamgr_item_select_action { ITEM_SELECT_ACTION_LAUNCH, ITEM_SELECT_ACTION_PUSH, + ITEM_SELECT_ACTION_POP, ITEM_SELECT_ACTION_SWITCH, ITEM_SELECT_ACTION_MAX }; diff --git a/include/defs.h b/include/defs.h index 081520d..d946e8b 100644 --- a/include/defs.h +++ b/include/defs.h @@ -97,5 +97,8 @@ #define COLOR_DEFAULT_A 255 #define IMAGE_BADGE IMAGEDIR"/badge_bg.png" - +#define IMAGE_USER_ADD IMAGEDIR"/btn_user_add_nor.png" +#define IMAGE_USER_ADD_FOCUS IMAGEDIR"/btn_user_add_foc.png" +#define IMAGE_USER_DEFAULT IMAGEDIR"/ic_user_01_nor.png" +#define IMAGE_USER_DEFAULT_FOCUS IMAGEDIR"/ic_user_01_foc.png" #endif /* __AIR_HOME_DEFS_H__ */ diff --git a/src/data/data_user.c b/src/data/data_user.c index 664e690..e2ab5c4 100644 --- a/src/data/data_user.c +++ b/src/data/data_user.c @@ -16,14 +16,323 @@ #include #include +#include #include +#include +#include +#include +#include +#include +#include +#include #include "data_user.h" #include "datamgr.h" +#include "defs.h" + +#define GUM_ATTR_NAME "username" +#define GUM_ATTR_USERTYPE "usertype" +#define GUM_ATTR_UID "uid" +#define GUM_ATTR_ICON "icon" +#define GUM_LIST_USERTYPE "normal" + +#define ADDRESS_BUF_MAX 128 +#define USER_SWITCH_TLM_SEAT_ID "seat0" +#define USER_SWITCH_DBUS_SOCKET_PATH "/var/run/tlm" +#define USER_SWITCH_TLM_BUS_NAME "org.O1.Tlm.Login" +#define USER_SWITCH_TLM_INTERFACE USER_SWITCH_TLM_BUS_NAME +#define USER_SWITCH_TLM_OBJECT_PATH "/org/O1/Tlm/Login" +#define USER_SWITCH_METHOD "switchUser" + +static GVariant *_build_env_param(const char *username, const char *password) +{ + GVariantBuilder *builder; + GVariant *param, *env; + + builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY); + if (!builder) { + _ERR("failed to new builder"); + return NULL; + } + + g_variant_builder_add(builder, "{ss}", "", ""); + env = g_variant_builder_end(builder); + g_variant_builder_unref(builder); + + param = g_variant_new("(sss@a{ss})", USER_SWITCH_TLM_SEAT_ID, + username, password, env); + + return param; +} + +static GDBusConnection *_get_bus_connection(GError **error) +{ + gchar address[ADDRESS_BUF_MAX]; + + g_snprintf(address, ADDRESS_BUF_MAX - 1, "unix:path=%s%s-%u", + USER_SWITCH_DBUS_SOCKET_PATH, USER_SWITCH_TLM_SEAT_ID, + getuid()); + + return g_dbus_connection_new_for_address_sync(address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, NULL, error); +} + +static void _switch(char *name, char *password) +{ + GDBusConnection *conn; + GError *error; + GVariant *param; + GDBusMessage *msg, *res; + guint32 serial; + + if (!name || !password) + return; + + error = NULL; + conn = _get_bus_connection(&error); + if (!conn) { + _ERR("failed to get connection, %s", + error ? error->message : ""); + g_error_free(error); + return; + } + + param = _build_env_param(name, password); + if (!param) { + _ERR("failed to build env param"); + goto err; + } + + msg = g_dbus_message_new_method_call(USER_SWITCH_TLM_BUS_NAME, + USER_SWITCH_TLM_OBJECT_PATH, USER_SWITCH_TLM_INTERFACE, + USER_SWITCH_METHOD); + g_dbus_message_set_body(msg, param); + + res = g_dbus_connection_send_message_with_reply_sync(conn, msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, 1000, &serial, NULL, + &error); + if (!res) { + _ERR("failed to send message, %s", error ? error->message : ""); + g_object_unref(msg); + goto err; + } + + g_object_unref(res); + g_object_unref(msg); + g_object_unref(conn); +err: + g_object_unref(conn); + g_error_free(error); + return; +} static void _select(struct datamgr_item *di) { - /* It should be implemented later */ + if (!di) + return; + + switch (di->action) { + case ITEM_SELECT_ACTION_SWITCH: + /* It should be implemented later */ + _switch(di->title, ""); + break; + case ITEM_SELECT_ACTION_PUSH: + viewmgr_push_view(di->parameter); + break; + case ITEM_SELECT_ACTION_POP: + viewmgr_pop_view(); + break; + default: + _ERR("Invalid state"); + return; + } +} + +static void _unload_user(struct datamgr *dm) +{ + struct datamgr_item *di; + + EINA_LIST_FREE(dm->list, di) { + free(di->title); + free(di->icon); + free(di->focus_icon); + free(di->parameter); + + free(di); + } + + dm->list = NULL; +} + +static struct datamgr_item *_pack_user(char *name, char *icon, char *focus_icon, + enum datamgr_item_select_action action, char *parameter) +{ + struct datamgr_item *di; + + di = calloc(1, sizeof(*di)); + if (!di) { + _ERR("failed calloc user item"); + return false; + } + + if (!icon || strlen(icon) == 0) + icon = IMAGE_USER_DEFAULT; + + if (!focus_icon || strlen(focus_icon) == 0) + focus_icon = IMAGE_USER_DEFAULT_FOCUS; + + if (name) + di->title = strdup(name); + if (parameter) + di->parameter = strdup(parameter); + di->icon = strdup(icon); + di->focus_icon = strdup(focus_icon); + di->action = action; + + return di; +} + +static bool _load_login_user(Eina_List **list) +{ + struct datamgr_item *di; + GumUser *user; + uid_t uid; + char *name, *icon; + struct passwd *passwd; + + uid = getuid(); + user = gum_user_get_sync(uid, FALSE); + if (!user) { + _ERR("failed to get user service"); + passwd = getpwuid(uid); + di = _pack_user(passwd->pw_name, IMAGE_USER_DEFAULT, + IMAGE_USER_DEFAULT_FOCUS, + ITEM_SELECT_ACTION_POP, NULL); + if (!di) + return false; + + *list = eina_list_append(*list, di); + return true; + } + + name = NULL; + icon = NULL; + g_object_get(G_OBJECT(user), GUM_ATTR_NAME, &name, GUM_ATTR_ICON, &icon, + NULL); + + di = _pack_user(name, icon, icon, ITEM_SELECT_ACTION_POP, NULL); + if (!di) { + g_object_unref(user); + return false; + } + + *list = eina_list_append(*list, di); + g_object_unref(user); + + return true; +} + +static gchar **_append_string(gchar **src_strv, const gchar *string) +{ + gchar **dest_strv; + gint ind; + gint len; + + if (src_strv) + len = g_strv_length(src_strv); + + len = 0; + ind = 0; + dest_strv = NULL; + + dest_strv = (gchar **)g_malloc0(sizeof(gchar *) * (len + 2)); + if (src_strv) { + while (src_strv[ind]) { + dest_strv[ind] = g_strdup(src_strv[ind]); + ind++; + } + } + + dest_strv[ind++] = g_strdup(string); + dest_strv[ind] = NULL; + + return dest_strv; +} + +static bool _load_users(Eina_List **list) +{ + GumUserList *ulist; + GumUser *user; + GumUserService *service; + struct datamgr_item *di; + char *name, *icon; + gchar **strv; + int i; + + service = gum_user_service_create_sync(FALSE); + if (!service) { + _ERR("failed to create service"); + return false; + } + + strv = _append_string(NULL, GUM_LIST_USERTYPE); + ulist = gum_user_service_get_user_list_sync(service, + (const gchar *const *)strv); + g_strfreev(strv); + if (!ulist) { + _ERR("failed to get user list"); + g_object_unref(service); + return false; + } + + for (i = 0; i < g_list_length(ulist); i++) { + user = g_list_nth_data(ulist, i); + if (!user) + continue; + + g_object_get(G_OBJECT(user), GUM_ATTR_NAME, &name, + GUM_ATTR_ICON, &icon, NULL); + di = _pack_user(name, icon, icon, ITEM_SELECT_ACTION_SWITCH, + NULL); + if (!di) + continue; + + *list = eina_list_append(*list, di); + } + + gum_user_service_list_free(ulist); + g_object_unref(service); + + return true; +} + +static bool _load_add_user(Eina_List **list) +{ + struct datamgr_item *di; + + di = _pack_user(NULL, IMAGE_USER_ADD, IMAGE_USER_ADD_FOCUS, + ITEM_SELECT_ACTION_PUSH, VIEW_USER_EDIT); + if (!di) + return false; + + *list = eina_list_append(*list, di); + + return true; +} + +static bool _load_user(struct datamgr *dm) +{ + if (!_load_login_user(&dm->list)) + _ERR("failed to load login user"); + + if (!_load_users(&dm->list)) + _ERR("failed to load users"); + + if (!_load_add_user(&dm->list)) + _ERR("failed to load add user"); + + return true; } static Eina_List *_get_items(struct datamgr *dm) @@ -33,19 +342,30 @@ static Eina_List *_get_items(struct datamgr *dm) return NULL; } + _unload_user(dm); + _load_user(dm); + return dm->list; } static void _fini(struct datamgr *dm) { - /* It should be implemented later */ + if (!dm) { + _ERR("Invalid argument"); + return; + } + + _unload_user(dm); } static bool _init(struct datamgr *dm) { - /* It should be implemented later */ + if (!dm) { + _ERR("Invalid argument"); + return false; + } - return true; + return _load_user(dm); } static struct data_class dclass = { @@ -59,4 +379,3 @@ struct data_class *datamgr_user_get_dclass(void) { return &dclass; } - -- 2.7.4