tizen_2.0_build
[apps/home/starter.git] / lock-mgr / src / lock-daemon.c
index 8842da8..7dba048 100755 (executable)
@@ -1,34 +1,28 @@
 /*
- * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved 
+ * Copyright 2012  Samsung Electronics Co., Ltd
  *
- * This file is part of <starter>
- * Written by <Seungtaek Chung> <seungtaek.chung@samsung.com>, <Mi-Ju Lee> <miju52.lee@samsung.com>, <Xi Zhichan> <zhichan.xi@samsung.com>
+ * Licensed under the Flora License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * PROPRIETARY/CONFIDENTIAL
- *
- * This software is the confidential and proprietary information of SAMSUNG ELECTRONICS ("Confidential Information").
- * You shall not disclose such Confidential Information and shall use it only in accordance
- * with the terms of the license agreement you entered into with SAMSUNG ELECTRONICS.
- * SAMSUNG make no representations or warranties about the suitability of the software,
- * either express or implied, including but not limited to the implied warranties of merchantability,
- * fitness for a particular purpose, or non-infringement.
- * SAMSUNG shall not be liable for any damages suffered by licensee as a result of using,
- * modifying or distributing this software or its derivatives.
+ *  http://www.tizenopensource.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.
  */
 
 #include <Elementary.h>
 
 #include <vconf.h>
 #include <vconf-keys.h>
-#include <glib.h>
-#include <poll.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <sys/socket.h>
+#include <sys/un.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/un.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
 #include "lockd-debug.h"
 #include "lock-daemon.h"
 #include "lockd-process-mgr.h"
-
-static int phone_lock_pid;
+#include "lockd-window-mgr.h"
 
 struct lockd_data {
-       int phone_lock_app_pid;
-       int phone_lock_state;
+       int lock_app_pid;
+       lockw_data *lockw;
 };
 
-struct ucred {
-       pid_t pid;
-       uid_t uid;
-       gid_t gid;
-};
-
-#define VCONFKEY_PHONE_LOCK_VERIFICATION "memory/lockscreen/phone_lock_verification"
-#define PHLOCK_SOCK_PREFIX "/tmp/phlock"
-#define PHLOCK_SOCK_MAXBUFF 65535
-#define PHLOCK_APP_CMDLINE "/opt/apps/org.tizen.phone-lock/bin/phone-lock"
+#define LAUNCH_INTERVAL 100*1000
 
+static void lockd_launch_lockscreen(struct lockd_data *lockd);
 static void lockd_launch_app_lockscreen(struct lockd_data *lockd);
 
+static void lockd_unlock_lockscreen(struct lockd_data *lockd);
+
 static void _lockd_notify_pm_state_cb(keynode_t * node, void *data)
 {
        LOCKD_DBG("PM state Notification!!");
@@ -101,45 +88,72 @@ _lockd_notify_lock_state_cb(keynode_t * node, void *data)
 
        if (val == VCONFKEY_IDLE_UNLOCK) {
                LOCKD_DBG("unlocked..!!");
+               if (lockd->lock_app_pid != 0) {
+                       LOCKD_DBG("terminate lock app..!!");
+                       lockd_process_mgr_terminate_lock_app(lockd->lock_app_pid, 1);
+               }
        }
 }
 
-static void
-_lockd_notify_phone_lock_verification_cb(keynode_t * node, void *data)
+static int lockd_app_dead_cb(int pid, void *data)
 {
-       LOCKD_DBG("%s, %d", __func__, __LINE__);
+       LOCKD_DBG("app dead cb call! (pid : %d)", pid);
 
        struct lockd_data *lockd = (struct lockd_data *)data;
-       int val = -1;
 
-       if (lockd == NULL) {
-               LOCKD_ERR("lockd is NULL");
-               return;
+       if (pid == lockd->lock_app_pid ) {
+               LOCKD_DBG("lock app(pid:%d) is destroyed.", pid);
+               lockd_unlock_lockscreen(lockd);
        }
+       return 0;
+}
 
-       if (vconf_get_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, &val) < 0) {
-               LOCKD_ERR("Cannot get VCONFKEY_PHONE_LOCK_VERIFICATION");
-               return;
+static Eina_Bool lockd_app_create_cb(void *data, int type, void *event)
+{
+       struct lockd_data *lockd = (struct lockd_data *)data;
+
+       if (lockd == NULL) {
+               return EINA_TRUE;
        }
+       LOCKD_DBG("%s, %d", __func__, __LINE__);
+       lockd_window_set_window_effect(lockd->lockw, lockd->lock_app_pid,
+                                      event);
+       lockd_window_set_window_property(lockd->lockw, lockd->lock_app_pid,
+                                        event);
+       return EINA_FALSE;
+}
 
-       if (val == TRUE) {
-               vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_UNLOCK);
+static Eina_Bool lockd_app_show_cb(void *data, int type, void *event)
+{
+       struct lockd_data *lockd = (struct lockd_data *)data;
+
+       if (lockd == NULL) {
+               return EINA_TRUE;
        }
+       LOCKD_DBG("%s, %d", __func__, __LINE__);
+       lockd_window_set_window_property(lockd->lockw, lockd->lock_app_pid,
+                                        event);
+
+       return EINA_FALSE;
 }
 
 static void lockd_launch_app_lockscreen(struct lockd_data *lockd)
 {
        LOCKD_DBG("launch app lock screen");
 
-       int call_state = -1, bootlock_state = -1;
-
-       vconf_get_bool(VCONFKEY_SETAPPL_STATE_POWER_ON_LOCK_BOOL,
-                      &bootlock_state);
+       int call_state = -1, phlock_state = -1;
+       int r = 0;
 
-       if (bootlock_state) {
-               lockd->phone_lock_state = 1;
-       } else {
-               lockd->phone_lock_state = 0;
+       if (lockd_process_mgr_check_lock(lockd->lock_app_pid) == TRUE) {
+               LOCKD_DBG("Lock Screen App is already running.");
+               r = lockd_process_mgr_restart_lock();
+               if (r < 0) {
+                       LOCKD_DBG("Restarting Lock Screen App is fail [%d].", r);
+                       usleep(LAUNCH_INTERVAL);
+               } else {
+                       LOCKD_DBG("Restarting Lock Screen App, pid[%d].", r);
+                       return;
+               }
        }
 
        vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
@@ -150,276 +164,59 @@ static void lockd_launch_app_lockscreen(struct lockd_data *lockd)
                return;
        }
 
-       if (lockd->phone_lock_state == 1) {
-               vconf_set_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, FALSE);
-               /* Check phone lock application is already exit */
-               if (lockd_process_mgr_check_lock(lockd->phone_lock_app_pid) == TRUE) {
-                       LOCKD_DBG("phone lock App is already running.");
-                       return;
-               }
-               vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_LOCK);
-               lockd->phone_lock_app_pid =
-                   lockd_process_mgr_start_phone_lock();
-               phone_lock_pid = lockd->phone_lock_app_pid;
-               LOCKD_DBG("%s, %d, phone_lock_pid = %d", __func__, __LINE__,
-                         phone_lock_pid);
-       }
-}
-
-inline static void lockd_set_sock_option(int fd, int cli)
-{
-       int size;
-       struct timeval tv = { 1, 200 * 1000 };
-
-       size = PHLOCK_SOCK_MAXBUFF;
-       setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
-       setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
-       if (cli)
-               setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-}
-
-static int lockd_create_sock(void)
-{
-       struct sockaddr_un saddr;
-       int fd;
-
-       fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if (fd < 0) {
-               if (errno == EINVAL) {
-                       fd = socket(AF_UNIX, SOCK_STREAM, 0);
-                       if (fd < 0) {
-                               LOCKD_DBG
-                                   ("second chance - socket create error");
-                               return -1;
-                       }
-               } else {
-                       LOCKD_DBG("socket error");
-                       return -1;
-               }
-       }
-
-       bzero(&saddr, sizeof(saddr));
-       saddr.sun_family = AF_UNIX;
-
-       strncpy(saddr.sun_path, PHLOCK_SOCK_PREFIX, strlen(PHLOCK_SOCK_PREFIX));
-       saddr.sun_path[strlen(PHLOCK_SOCK_PREFIX)] = 0;
-
-       unlink(saddr.sun_path);
-
-       if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
-               LOCKD_DBG("bind error");
-               return -1;
-       }
-
-       if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
-               LOCKD_DBG("failed to change the socket permission");
-               return -1;
-       }
-
-       lockd_set_sock_option(fd, 0);
-
-       if (listen(fd, 10) == -1) {
-               LOCKD_DBG("listen error");
-               return -1;
-       }
-
-       return fd;
-}
+       lockd->lock_app_pid =
+           lockd_process_mgr_start_lock(lockd, lockd_app_dead_cb);
+       if (lockd->lock_app_pid < 0)
+               return;
 
-static gboolean lockd_glib_check(GSource * src)
-{
-       GSList *fd_list;
-       GPollFD *tmp;
-
-       fd_list = src->poll_fds;
-       do {
-               tmp = (GPollFD *) fd_list->data;
-               if ((tmp->revents & (POLLIN | POLLPRI)))
-                       return TRUE;
-               fd_list = fd_list->next;
-       } while (fd_list);
-
-       return FALSE;
+       vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_LOCK);
+       lockd_window_mgr_ready_lock(lockd, lockd->lockw, lockd_app_create_cb,
+                                   lockd_app_show_cb);
 }
 
-static char *lockd_read_cmdline_from_proc(int pid)
+static void lockd_launch_lockscreen(struct lockd_data *lockd)
 {
-       int memsize = 32;
-       char path[32];
-       char *cmdline = NULL, *tempptr = NULL;
-       FILE *fp = NULL;
+       LOCKD_DBG("launch lock screen");
 
-       snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
-
-       fp = fopen(path, "r");
-       if (fp == NULL) {
-               LOCKD_DBG("Cannot open cmdline on pid[%d]", pid);
-               return NULL;
-       }
-
-       cmdline = malloc(32);
-       if (cmdline == NULL) {
-               LOCKD_DBG("%s", "Out of memory");
-               fclose(fp);
-               return NULL;
-       }
-
-       bzero(cmdline, memsize);
-       if (fgets(cmdline, 32, fp) == NULL) {
-               LOCKD_DBG("%s", "Cannot read cmdline");
-               free(cmdline);
-               fclose(fp);
-               return NULL;
-       }
+       int call_state = -1;
+       int r = 0;
 
-       while (cmdline[memsize - 2] != 0) {
-               cmdline[memsize - 1] = (char)fgetc(fp);
-               tempptr = realloc(cmdline, memsize + 32);
-               if (tempptr == NULL) {
-                       fclose(fp);
-                       LOCKD_DBG("%s", "Out of memory");
-                       return NULL;
+       if (lockd_process_mgr_check_lock(lockd->lock_app_pid) == TRUE) {
+               LOCKD_DBG("Lock Screen App is already running.");
+               r = lockd_process_mgr_restart_lock();
+               if (r < 0) {
+                       LOCKD_DBG("Restarting Lock Screen App is fail [%d].", r);
+               } else {
+                       LOCKD_DBG("Restarting Lock Screen App, pid[%d].", r);
+                       return;
                }
-               cmdline = tempptr;
-               bzero(cmdline + memsize, 32);
-               fgets(cmdline + memsize, 32, fp);
-               memsize += 32;
-       }
-
-       if (fp != NULL)
-               fclose(fp);
-       return cmdline;
-}
-
-static int lockd_sock_handler(int fd)
-{
-       int cl;
-       int len;
-       int sun_size;
-       int clifd = -1;
-       char cmd[PHLOCK_SOCK_MAXBUFF];
-       char *cmdline = NULL;
-
-       struct ucred cr;
-       struct sockaddr_un lockd_addr;
-
-       cl = sizeof(cr);
-       sun_size = sizeof(struct sockaddr_un);
-
-       if ((clifd =
-            accept(fd, (struct sockaddr *)&lockd_addr,
-                   (socklen_t *) & sun_size)) == -1) {
-               if (errno != EINTR)
-                       LOCKD_DBG("accept error");
-               return -1;
-       }
-
-       if (getsockopt(clifd, SOL_SOCKET, SO_PEERCRED, &cr, (socklen_t *) & cl)
-           < 0) {
-               LOCKD_DBG("peer information error");
-               close(clifd);
-               return -1;
-       }
-       LOCKD_DBG("Peer's pid=%d, uid=%d, gid=%d\n", cr.pid, cr.uid, cr.gid);
-
-       memset(cmd, 0, PHLOCK_SOCK_MAXBUFF);
-
-       lockd_set_sock_option(clifd, 1);
-
-       len = recv(clifd, cmd, PHLOCK_SOCK_MAXBUFF, 0);
-
-       if (cmd == NULL) {
-               LOCKD_DBG("recv error, cmd is NULL");
-               close(clifd);
-               return -1;
-       }
-
-       if (len != strlen(cmd)) {
-               LOCKD_DBG("recv error %d %d", len, strlen(cmd));
-               close(clifd);
-               return -1;
        }
 
-       LOCKD_DBG("cmd %s", cmd);
-
-       cmdline = lockd_read_cmdline_from_proc(cr.pid);
-       if (cmdline == NULL) {
-               LOCKD_DBG("Error on opening /proc/%d/cmdline", cr.pid);
-               return -1;
-       }
-
-       LOCKD_DBG("/proc/%d/cmdline : %s", cr.pid, cmdline);
-
-       if ((!strncmp(cmdline, PHLOCK_APP_CMDLINE, strlen(cmdline)))
-           && (phone_lock_pid == cr.pid)) {
-               LOCKD_DBG("pid [%d] %s is verified, unlock..!!\n", cr.pid,
-                         cmdline);
-               lockd_process_mgr_terminate_phone_lock(phone_lock_pid);
-               phone_lock_pid = 0;
-               vconf_set_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, TRUE);
+       vconf_get_int(VCONFKEY_CALL_STATE, &call_state);
+       if (call_state != VCONFKEY_CALL_OFF) {
+               LOCKD_DBG
+                   ("Current call state(%d) does not allow to launch lock screen.",
+                    call_state);
+               return;
        }
 
-       return 0;
-}
+       lockd_window_mgr_ready_lock(lockd, lockd->lockw, lockd_app_create_cb,
+                                   lockd_app_show_cb);
 
-static gboolean lockd_glib_handler(gpointer data)
-{
-       GPollFD *gpollfd = (GPollFD *) data;
-       if (lockd_sock_handler(gpollfd->fd) < 0) {
-               LOCKD_DBG("lockd_sock_handler is failed..!!");
-       }
-       return TRUE;
-}
+       lockd->lock_app_pid =
+           lockd_process_mgr_start_lock(lockd, lockd_app_dead_cb);
 
-static gboolean lockd_glib_dispatch(GSource * src, GSourceFunc callback,
-                                   gpointer data)
-{
-       callback(data);
-       return TRUE;
+       vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_LOCK);
 }
 
-static gboolean lockd_glib_prepare(GSource * src, gint * timeout)
+static void lockd_unlock_lockscreen(struct lockd_data *lockd)
 {
-       return FALSE;
-}
-
-static GSourceFuncs funcs = {
-       .prepare = lockd_glib_prepare,
-       .check = lockd_glib_check,
-       .dispatch = lockd_glib_dispatch,
-       .finalize = NULL
-};
-
-static int lockd_init_sock(void)
-{
-       int fd;
-       GPollFD *gpollfd;
-       GSource *src;
-       int ret;
-
-       fd = lockd_create_sock();
-       if (fd < 0) {
-               LOCKD_DBG("lock daemon create sock failed..!!");
-       }
+       LOCKD_DBG("unlock lock screen");
+       lockd->lock_app_pid = 0;
 
-       src = g_source_new(&funcs, sizeof(GSource));
+       lockd_window_mgr_finish_lock(lockd->lockw);
 
-       gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD));
-       gpollfd->events = POLLIN;
-       gpollfd->fd = fd;
-
-       g_source_add_poll(src, gpollfd);
-       g_source_set_callback(src, (GSourceFunc) lockd_glib_handler,
-                             (gpointer) gpollfd, NULL);
-       g_source_set_priority(src, G_PRIORITY_LOW);
-
-       ret = g_source_attach(src, NULL);
-       if (ret == 0)
-               return -1;
-
-       g_source_unref(src);
-
-       return 0;
+       vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_UNLOCK);
 }
 
 static void lockd_init_vconf(struct lockd_data *lockd)
@@ -432,33 +229,12 @@ static void lockd_init_vconf(struct lockd_data *lockd)
        }
 
        if (vconf_notify_key_changed
-           (VCONFKEY_PHONE_LOCK_VERIFICATION,
-            _lockd_notify_phone_lock_verification_cb, lockd) != 0) {
-               if (vconf_get_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, &val) < 0) {
-                       LOCKD_ERR
-                           ("Cannot get VCONFKEY_PHONE_LOCK_VERIFICATION");
-                       vconf_set_bool(VCONFKEY_PHONE_LOCK_VERIFICATION, 0);
-                       if (vconf_notify_key_changed
-                           (VCONFKEY_PHONE_LOCK_VERIFICATION,
-                            _lockd_notify_phone_lock_verification_cb,
-                            lockd) != 0) {
-                               LOCKD_ERR
-                                   ("Fail vconf_notify_key_changed : VCONFKEY_PHONE_LOCK_VERIFICATION");
-                       }
-               } else {
-                       LOCKD_ERR
-                           ("Fail vconf_notify_key_changed : VCONFKEY_PHONE_LOCK_VERIFICATION");
-               }
-       }
-
-       if (vconf_notify_key_changed
            (VCONFKEY_IDLE_LOCK_STATE,
             _lockd_notify_lock_state_cb,
             lockd) != 0) {
                LOCKD_ERR
                    ("[Error] vconf notify : lock state");
        }
-       
 }
 
 static void lockd_start_lock_daemon(void *data)
@@ -476,10 +252,7 @@ static void lockd_start_lock_daemon(void *data)
 
        lockd_init_vconf(lockd);
 
-       r = lockd_init_sock();
-       if (r < 0) {
-               LOCKD_DBG("lockd init socket failed: %d", r);
-       }
+       lockd->lockw = lockd_window_init();
 
        LOCKD_DBG("%s, %d", __func__, __LINE__);
 }
@@ -495,12 +268,5 @@ int start_lock_daemon()
        memset(lockd, 0x0, sizeof(struct lockd_data));
        lockd_start_lock_daemon(lockd);
 
-       vconf_get_bool(VCONFKEY_SETAPPL_STATE_POWER_ON_LOCK_BOOL, &val);
-       LOCKD_DBG("%s, %d, val = %d", __func__, __LINE__, val);
-
-       if (val) {
-               lockd_launch_app_lockscreen(lockd);
-       }
-
        return 0;
 }