load user data 22/42122/4
authorSoohye Shin <soohye.shin@samsung.com>
Tue, 23 Jun 2015 12:06:00 +0000 (21:06 +0900)
committerSoohye Shin <soohye.shin@samsung.com>
Wed, 24 Jun 2015 07:19:24 +0000 (16:19 +0900)
- 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 <soohye.shin@samsung.com>
include/datamgr.h
include/defs.h
src/data/data_user.c

index 9ca5fd4..982694d 100644 (file)
@@ -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
 };
index 081520d..d946e8b 100644 (file)
@@ -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__ */
index 664e690..e2ab5c4 100644 (file)
 
 #include <app_debug.h>
 #include <Eina.h>
+#include <Evas.h>
 #include <stdbool.h>
+#include <viewmgr.h>
+#include <stdlib.h>
+#include <gum/gum-user.h>
+#include <gum/gum-user-service.h>
+#include <gum/common/gum-user-types.h>
+#include <pwd.h>
+#include <gio/gio.h>
 
 #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;
 }
-